Nohup 아래에서 이미 실행되는 프로세스를 어떻게 배치합니까?
문제
이미 오랫동안 실행 중이며 끝내고 싶지 않은 프로세스가 있습니다.
nohup 아래에 넣는 방법 (즉, 터미널을 닫더라도 계속 실행할 수 있습니까?)
해결책
사용 직업 관리 프로세스를 백그라운드로 보내기위한 배쉬의 :
- Ctrl 키+지 프로그램을 멈추고 (일시 중지) 프로그램을 다시 시작하십시오.
bg
백그라운드에서 실행합니다.disown -h [job-spec]
여기서 [job-spec]는 작업 번호입니다 (%1
첫 번째 달리기 작업을 위해; 당신의 번호에 대해 찾으십시오jobs
명령) 터미널이 닫히면 작업이 죽지 않도록하십시오.
다른 팁
어떤 이유로 든 가정합니다 Ctrl 키+지 또한 작동하지 않고 다른 터미널로 이동하여 프로세스 ID를 찾으십시오 (사용 ps
) 및 실행 :
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
프로세스를 중단합니다 SIGCONT
백그라운드에서 프로세스를 재개합니다. 이제 두 터미널을 모두 닫으면 프로세스가 중지되지 않습니다.
실행 작업을 쉘에서 분리하라는 명령 (= Nohup을 만듭니다)은 다음과 같습니다. disown
그리고 기본 쉘-명령.
Bash-Manpage (Man Bash) :
-ar] [-h] [jobspec ...
옵션이 없으면 각 Jobspec은 활성 작업 테이블에서 제거됩니다. -H 옵션이 제공되면 각 JobSpec은 테이블에서 제거되지 않지만 쉘이 한 잔을 수신하면 SIGHUP이 작업에 전송되지 않도록 표시됩니다. JobSpec이없고 -a 또는 -r 옵션이 제공되지 않으면 현재 작업이 사용됩니다. JobSpec이 제공되지 않으면 -a 옵션은 모든 작업을 제거하거나 표시하는 것을 의미합니다. JobSpec 인수가없는 -R 옵션은 작업을 실행하는 작업으로 제한합니다. JobSpec이 유효한 작업을 지정하지 않는 한 리턴 값은 0입니다.
그것은 단순한 것입니다
disown -a
작업 테이블에서 모든 작업을 제거하고 Nohup로 만듭니다.
이것들은 위의 좋은 답변입니다. 나는 단지 설명을 추가하고 싶었습니다.
당신은 할 수 없습니다 disown
PID 또는 프로세스, 당신 disown
직업, 그리고 그것은 중요한 차이입니다.
작업은 쉘에 부착 된 프로세스의 개념이므로 작업을 배경에 던져야 한 다음 해체해야합니다.
문제:
% jobs
[1] running java
[2] suspended vi
% disown %1
보다 http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/유닉스 직업 관리에 대한보다 자세한 토론.
안타깝게도 disown
Bash에만 적합하며 모든 쉘에서 사용할 수있는 것은 아닙니다.
유닉스의 특정 맛 (예 : AIX 및 Solaris)은 nohup
실행중인 프로세스에 적용 할 수있는 명령 자체 :
nohup -p pid
Node의 대답은 정말 훌륭하지만 STDOUT와 STDERR을 어떻게 리디렉션 할 수 있는지에 대한 질문을 열었습니다. 나는 해결책을 찾았다 유닉스 & 리눅스, 그러나 그것은 또한 완전하지 않습니다. 이 두 솔루션을 병합하고 싶습니다. 여기있어:
내 테스트를 위해 나는 loop.sh라는 작은 bash 스크립트를 만들었습니다.이 스크립트는 무한 루프에서 1 분의 잠을 자고 자체의 PID를 인쇄했습니다.
$./loop.sh
이제이 과정의 PID를 어떻게 든 받으십시오. 대개 ps -C loop.sh
충분하지만 제 경우에는 인쇄됩니다.
이제 다른 터미널로 전환 할 수 있습니다 (또는 ^z를 누르고 동일한 터미널). 지금 gdb
이 과정에 첨부해야합니다.
$ gdb -p <PID>
스크립트가 중지됩니다 (실행 중). 상태는 확인할 수 있습니다 ps -f <PID>
, 어디에 STAT
필드는 't+'(또는 ^z 't'의 경우)입니다.
T Stopped, either by a job control signal or because it is being traced
+ is in the foreground process group
(gdb) call close(1)
$1 = 0
닫기 (1)는 성공시 0을 반환합니다.
(gdb) call open("loop.out", 01102, 0600)
$6 = 1
Open (1) 성공하면 새 파일 디스크립터를 반환합니다.
이 개방은 동일합니다 open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
. 대신에 O_RDWR
O_WRONLY
적용될 수는 있지만 /usr/sbin/lsof
모든 std* 파일 처리기에 대해 'u'라고 말합니다 (FD
칼럼) O_RDWR
.
/usr/include/bits/fcntl.h 헤더 파일에서 값을 확인했습니다.
출력 파일을 열 수 있습니다 O_APPEND
, 처럼 nohup
그렇게 할 것입니다. 그러나 이것은 제안되지 않습니다 man open(2)
, 가능한 NFS 문제로 인해.
우리가 -1을 반환 값으로 얻으면 call perror("")
오류 메시지를 인쇄합니다. errno가 필요한 경우 사용하십시오 p errno
gdb comand.
이제 새로 리디렉션 된 파일을 확인할 수 있습니다. /usr/sbin/lsof -p <PID>
인쇄물:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
원한다면 사용하려면 stderr를 다른 파일로 리디렉션 할 수 있습니다. call close(2)
그리고 call open(...)
다시 다른 파일 이름을 사용합니다.
이제 첨부 된 bash
석방되어야하고 우리는 종료 할 수 있습니다 gdb
:
(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q
스크립트가 중지 된 경우 gdb
다른 터미널에서 계속 실행됩니다. 우리는 loop.sh의 터미널로 다시 전환 할 수 있습니다. 이제 화면에 아무것도 쓰지 않고 파일을 실행하고 씁니다. 우리는 그것을 배경에 넣어야합니다. 그러니 누르십시오 ^Z
.
^Z
[1]+ Stopped ./loop.sh
(이제 우리는 같은 상태에 있습니다. ^Z
처음에 압박을 받았습니다.)
이제 작업 상태를 확인할 수 있습니다.
$ ps -f 24522
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
$ jobs
[1]+ Stopped ./loop.sh
따라서 프로세스는 백그라운드에서 실행되고 터미널에서 분리되어야합니다. 숫자의 숫자 jobs
사각형 괄호 안의 명령의 출력 내부의 작업을 식별합니다. bash
. 우리는 다음 내장에서 사용할 수 있습니다 bash
작업 번호 앞에 '%'부호를 적용하는 명령 :
$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh
그리고 이제 우리는 호출 bash에서 그만 둘 수 있습니다. 프로세스는 계속해서 백그라운드에서 실행됩니다. 우리가 PPID를 1 (init (1) 프로세스)가되고 제어 터미널을 알 수 없게됩니다.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID> <PID> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted)
loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,36 38 /dev/pts/36 (deleted)
논평
GDB 물건을 자동화 할 수 있습니다. gdb -q -x loop.gdb -p <PID>
. my loop.gdb는 다음과 같습니다.
call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit
또는 다음 하나의 라이너를 대신 사용할 수 있습니다.
gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>
이것이 솔루션에 대한 상당히 완전한 설명이기를 바랍니다.
달리기 프로세스를 Nohup에 보내기 위해 (http://en.wikipedia.org/wiki/nohup)
nohup -p pid
, 그것은 나를 위해 일하지 않았다
그런 다음 다음 명령을 시도했는데 매우 잘 작동했습니다.
Somecommand를 실행하십시오
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl 키+지 프로그램을 멈추고 (일시 중지) 프로그램을 다시 시작하십시오.
bg
백그라운드에서 실행합니다.disown -h
터미널이 닫히면 프로세스가 죽지 않도록합니다.유형
exit
껍질에서 벗어나려면 이제 작업이 자체 프로세스에서 백그라운드에서 작동하므로 쉘에 연결되지 않습니다.
이 프로세스는 실행과 동일합니다 nohup SOMECOMMAND
.
내 AIX 시스템에서 나는 시도했다
nohup -p processid>
이것은 잘 작동했습니다. 터미널 윈도우를 닫은 후에도 내 프로세스를 계속 실행했습니다. 우리는 기본 쉘로 ksh를 가지고 있습니다 bg
그리고 disown
명령은 작동하지 않았습니다.
- Ctrl 키 + 지 - 이것은 작업을 일시 중지합니다 (취소되지 않을 것입니다!)
bg
- 이것은 작업을 백그라운드에 넣고 실행중인 과정에서 돌아갑니다.disown -a
- 이렇게하면 모든 첨부 파일이 작업을 중단합니다 (따라서 터미널을 닫을 수 있고 여전히 실행됩니다).
이 간단한 단계를 통해 프로세스를 계속 진행하면서 터미널을 닫을 수 있습니다.
그것은 입지 않을 것입니다 nohup
(귀하의 질문에 대한 이해를 바탕으로 여기에는 필요하지 않습니다).
이것은 tcshell에서 Ubuntu Linux에서 나를 위해 일했습니다.
Ctrl 키지 그것을 일시 중지합니다
bg
백그라운드에서 실행합니다jobs
작업 번호를 얻으려면nohup %n
여기서 n은 작업 번호입니다