답변:
bash 의 작업 제어 를 사용하여 프로세스를 백그라운드로 보내기 :
bg
백그라운드에서 실행합니다.disown -h [job-spec]
여기서 [job-spec]은 작업 번호 ( %1
첫 번째 실행 작업의 경우와 같이 jobs
명령으로 번호를 찾습니다 )이므로 터미널을 닫을 때 작업이 종료되지 않습니다.disown -h
이었을 것입니다. 아마도 가장 정확한 대답은 다음과 같습니다. "disown이 nohup과 비슷하게 동작하도록하십시오 (즉, 작업은 쉘을 종료 할 때까지 현재 쉘의 프로세스 트리에 남아 있습니다). 이 쉘이 시작한 모든 작업 " ([ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )
disown
disown이 프로세스를 데몬으로 만든 후 작업의 출력을 볼 수 없습니다. 즉 표준 입력 / 출력이 / dev / null로 리디렉션됩니다. 따라서 작업을 my_job_command | tee my_job.log
어떤 이유로 Ctrl+ Z도 작동하지 않는다고 가정 하고 다른 터미널로 이동하여 프로세스 ID를 찾고 (을 사용하여 ps
) 다음을 실행하십시오.
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
프로세스를 일시 중단하고 SIGCONT
백그라운드에서 프로세스를 다시 시작합니다. 이제 두 터미널을 모두 닫아도 프로세스가 중단되지 않습니다.
disown %1
터미널을 닫기 전에 첫 번째 터미널에서 수행해야 합니다.
kwin
에는 결과를 생각하지 않고 충돌 후 곤솔에서 시작했습니다 ). 그래서 kwin을 멈 추면 모든 것이 멈췄을 것이고 도망 칠 가능성도 없었습니다 bg
!
쉘에서 실행중인 작업을 분리하는 명령 (=는 nohup)은 disown
기본 쉘 명령입니다.
bash-manpage (man bash)에서 :
폐기 [-ar] [-h] [jobspec ...]
옵션이 없으면 각 작업 스펙이 활성 작업 테이블에서 제거됩니다. -h 옵션이 제공되면 각 jobspec은 테이블에서 제거되지 않지만 쉘이 SIGHUP을 수신 할 때 SIGHUP이 작업으로 전송되지 않도록 표시됩니다. jobspec이없고 -a 또는 -r 옵션이 제공되지 않으면 현재 작업이 사용됩니다. jobspec이 제공되지 않으면 -a 옵션은 모든 작업을 제거하거나 표시하는 것을 의미합니다. jobspec 인수가없는 -r 옵션은 작업을 실행중인 작업으로 제한합니다. jobspec이 유효한 작업을 지정하지 않으면 리턴 값은 0입니다.
즉, 간단한
disown -a
작업 테이블에서 모든 작업을 제거하고 nohup하게합니다.
disown -a
모든 작업을 제거합니다. 단순 disown
은 현재 작업 만 제거합니다. 답변의 맨 페이지가 말합니다.
위의 좋은 답변입니다. 설명을 추가하고 싶었습니다.
당신은 disown
pid 나 프로세스, disown
직업 이 될 수 없으며 그것은 중요한 차이점입니다.
작업은 쉘에 첨부 된 프로세스의 개념 인 작업이므로 작업을 백그라운드로 던지고 (일시 중단하지 말고) 제거해야합니다.
발행물:
% jobs
[1] running java
[2] suspended vi
% disown %1
Unix Job Control에 대한 자세한 내용은 http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ 을 참조 하십시오 .
불행히도 disown
배쉬에만 적용되며 모든 쉘에서 사용 가능한 것은 아닙니다.
Unix의 특정 특징 (예 : AIX 및 Solaris)은 nohup
실행중인 프로세스에 적용 할 수있는 명령 자체 에 대한 옵션 이 있습니다.
nohup -p pid
AIX
및 에만 해당됩니다 Solaris
. "nohup의 AIX 및 Solaris 버전에는 향후 SIGHUP 신호를 무시하도록 실행중인 프로세스를 수정하는 -p 옵션이 있습니다. 위에서 설명한 bash 내장 거부와 달리 nohup -p는 프로세스 ID를 승인합니다." 출처
노드의 대답은 정말 훌륭하지만 stdout 및 stderr를 리디렉션하는 방법에 대한 의문을 남겼습니다. 유닉스 및 리눅스 에서 해결책을 찾았 지만 완벽하지 않습니다. 이 두 가지 솔루션을 병합하고 싶습니다. 여기있어:
내 테스트를 위해 loop.sh라는 작은 bash 스크립트를 만들었습니다.
$./loop.sh
이제이 프로세스의 PID를 어떻게 든 얻으십시오. 일반적으로 ps -C loop.sh
충분하지만 제 경우에는 인쇄됩니다.
이제 다른 터미널로 전환 할 수 있습니다 (또는 동일한 터미널에서 ^ Z를 누름). 이제이 gdb
프로세스에 첨부해야합니다.
$ gdb -p <PID>
스크립트가 중지됩니다 (실행중인 경우). 그 상태를 확인할 수있다 ps -f <PID>
여기서 STAT
필드는 '+ T'(또는 ^ Z 'T'의 경우), 어떤 수단 (남자 PS (1))
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
Close (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 * 파일 처리기 ( FD
열)에 대해 'u'라고 표시됩니다 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
원하는 경우 다른 파일 이름 을 사용 call close(2)
하고 call open(...)
다시 사용 하려면 stderr을 다른 파일로 리디렉션 할 수 있습니다 .
이제 첨부 파일 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)
논평
명령을 포함하는 파일 (예 : loop.gdb)을 만들어 gdb를 자동화하고 실행할 수 gdb -q -x loop.gdb -p <PID>
있습니다. 내 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>
이것이 솔루션에 대한 완전한 설명이기를 바랍니다.
lsof
(파일 핸들의 이름이 pipe
아닌 /dev/pts/1
)을 사용하거나 ls -l /proc/<PID>/fd/<fd>
(이것이 핸들의 심볼릭 링크를 표시 함 )을 사용하여 리디렉션되는지 확인할 수 있습니다 . 또한 서브 프로세스는 여전히 출력을 경로 재 지정할 수 없으므로 파일로 경로 재지 정해야합니다.
nohup으로 실행중인 프로세스를 보내려면 ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
, 그것은 나를 위해 일하지 않았다
그런 다음 다음 명령을 시도하고 매우 잘 작동했습니다.
SOMECOMMAND를 실행하십시오 (예 :) /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.
Ctrl+ Z프로그램을 중지 (일시 중지)하고 쉘로 돌아갑니다.
bg
백그라운드에서 실행합니다.
disown -h
터미널이 닫힐 때 프로세스가 종료되지 않습니다.
exit
셸에서 빠져 나오려면 입력하십시오. 이제는 자체 프로세스에서 백그라운드에서 작업이 실행되므로 셸에 묶이지 않기 때문에 작업을 진행하는 것이 좋습니다.
이 프로세스는 running과 동일합니다 nohup SOMECOMMAND
.
bg
-이것은 작업을 백그라운드로 놓고 실행중인 프로세스로 돌아갑니다.disown -a
-이것은 작업과 함께 모든 첨부 파일을 잘라냅니다 (따라서 터미널을 닫을 수 있으며 여전히 실행됩니다)이 간단한 단계를 통해 프로세스를 계속 실행하면서 터미널을 닫을 수 있습니다.
그것은에 넣어 실 거예요 nohup
(귀하의 질문에 대한 이해를 기반으로, 당신은 여기 필요하지 않습니다).
이것은 tcshell에있는 동안 Ubuntu Linux에서 나를 위해 일했습니다.
CtrlZ 일시 정지
bg
백그라운드에서 실행
jobs
직업 번호를 얻기 위해
nohup %n
여기서 n은 작업 번호입니다.
nohup: failed to run command '%1': No such file or directory
yourExecutable &
하고 출력이 화면에 계속Ctrl+C
나타나고 아무것도 멈추지 않는 것처럼 보이지만 화면이 출력으로 스크롤 되어도 맹목적으로 입력disown;
하고 누르십시오.Enter
입력 중입니다. 프로세스가 폐기되고 프로세스가 종료되지 않고 터미널을 닫을 수 있습니다.