프로세스를 생성하고 이를 최상위 수준에서 실행하여 셸이 종료될 때 프로세스가 계속 실행되도록 하고 싶습니다.
나는 nohup이 이 작업을 수행할 것이라고 잘못 생각했지만 쉘을 종료하고(쉘은 내가 ssh로 연결하는 lxc 컨테이너임) 다시 들어가자 프로세스가 사라졌습니다.
(pstree를 보면) nohup이나 disown을 사용해도 프로세스는 여전히 호출 셸 아래에 있는 것 같습니다.
몇 가지 옵션을 시도했는데 setid가 작동하는 것 같습니다. 하지만 여기서 nohup에 문제가 있는 걸까요?
$ cat myproc
sleep 1234
$ myproc &
$ pstree -a | grep -B 3 "1234" | grep -v grep
|-screen
| |-bash -ls
| | |-bash -ls
| | | `-sleep 1234
$ nohup myproc &
$ pstree
|-screen
| |-bash -ls
| | |-pstree -a
| | `-sh ./myproc
| | `-sleep 1234
$ myproc &
$ disown $!
$ pstree -a | grep -B 3 "1234" | grep -v grep
|-screen
| |-bash -ls
| | |-bash -ls
| | | `-sleep 1234
$ setsid myproc &
|-sh ./myproc
| `-sleep 1234
성공. 그런데 왜 nohup은 같은 효과를 얻지 못하는 걸까요? nohup을 사용하는 더 올바른 방법이 있습니까?
답변1
출처를 밝히지 않으셔서 진단이 다소 어렵지만 myproc
, 귀하의 문제가 "제어 TTY". 저는 을 호출하는 작은 쉘 스크립트를 작성했습니다 sleep 100
. 아래에서 실행합니다 nohup
.
$ nohup ./sleeper > sleeper.out &
[1] 25305
-bash-3.2$ jobs
[1]+ Running nohup ./sleeper > sleeper.out &
-bash-3.2$ ps -l -p 25305
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 429624 25305 18252 0 77 0 - 15961 wait pts/0 00:00:00 sleeper
ps
출력을 보면 "텔레타이프라이터". 적어도 일부 버전이 있습니다 nohup
(위에서 사용한 버전은 GNU coreutils 버전 5.97이므로 비교적 오래된 버전입니다). 시작한 bash 셸을 종료하면 sleeper
TTY 열이 "? ”, 즉 sleeper
“하나 없이는 없다”는 뜻입니다.
제어 TTY에서 의도적으로 자신을 분리하지 않으면 myproc
stdout에 쓰려고 할 때 SIGPIPE 신호와 같은 신호를 얻을 수 있습니다. 다른 일도 가능한 것 같지만 기억이 나거나 Google에 검색할 수 없습니다.
"를 찾거나 컴파일할 수 있는 경우악마", 시도해 볼 수도 있습니다. myproc
컴파일이 통과되면 소스 코드를 수정하여 daemon(3)
라이브러리 함수를 호출할 수 있습니다.
답변2
당신은 그것을 사용할 수 있습니다at
이를 위해.
이
at
유틸리티는 표준 입력에서 명령을 읽고 이를 하나로 결합해야 합니다.직장에서, 나중에 실행됩니다.이것직장에서환경 변수, 현재 작업 디렉토리, 파일 생성 마스크 및 기타 구현 정의 실행 시간 속성이 적용되는 경우를 제외하고 제어 터미널 없이 별도의 프로세스 그룹에서 실행되는 별도의 쉘 호출로 실행되어야 합니다. 유틸리티가 실행될 때 유지되고 사용되어야 합니다.직장에서처형되다.
echo myproc | at now
...작동하지만 일부 시스템에서는 at
먼저 데몬 모니터를 구성해야 합니다.
답변3
프로세스를 완전히 분리하려면:
nohup ./command &
stdout 및 stderr은 nohup이 실행되는 동일한 디렉터리에 있는 nohup.out이라는 파일에 기록됩니다.
독립 실행형 명령을 실행하는 동안 터미널에서 출력을 보려면 tail을 사용하세요.
TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./command &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &