백그라운드에서 두 개의 쉘 스크립트를 차례로 실행하고 싶습니다. 가급적이면 nohup
.
나는 출신
% nohup a.sh &
이는 a
백그라운드에서 실행됩니다.
% nohup a.sh && nohup b.sh
a
그런 다음 실행 b
( a
성공한 경우)
하지만 백그라운드에서 마지막 조합을 시작하는 방법은 무엇입니까?
만약 내가한다면
% nohup a.sh && nohup b.sh &
a
전경에서 실행되어 프롬프트를 차단한 다음 b
백그라운드에서 시작하여 프롬프트에 제어권을 반환합니다.
% nohup a.sh & && nohup b.sh &
오류가 발생합니다.zsh: parse error near '&&'
백그라운드에서 두 프로세스를 시작하는 방법은 무엇입니까?
답변1
이는 sh(또는 csh)와 비교하여 zsh의 알려진 편차 중 하나입니다.
sh에서:
A && B &
약어는 다음과 같습니다.
(A && B) &
즉, 백그라운드에서/비동기적으로 및/또는 목록을 실행하는 하위 쉘을 실행합니다.
zsh에서는
A && B &
동기식으로 실행되고 A
대기하며 성공하면 B
백그라운드/비동기식으로 실행됩니다.
그건설명서에 명시된(바라보다 info zsh list
):
ㅏ목록
;
0개 이상의 하위 목록으로 구성된 시퀀스입니다. 여기서 각 하위 목록은 , , 또는 개행 문자로&
끝&|
납니다&!
. 목록이(...)
또는 에서 복잡한 명령으로 나타나는 경우 선택적으로 목록의 마지막 하위 목록에서 이 종결자를 생략할 수 있습니다{...}
. 하위 목록이 또는 개행 문자로 종료되면;
쉘은 다음 하위 목록을 실행하기 전에 하위 목록이 완료될 때까지 기다립니다.&
하위 목록이&|
, 또는 로 끝나는 경우&!
셸은 백그라운드에서 마지막 파이프를 실행하고 완료될 때까지 기다리지 않습니다(백그라운드에서 전체 하위 목록을 실행하는 다른 셸과의 차이점에 유의하세요).. 백그라운드 파이프라인은 0 상태를 반환합니다.
(강조).
그리고FAQ에서:
zsh에서는 전체 표현식
cmd1 && cmd2 &
만cmd2
백그라운드에서 실행됩니다. 매뉴얼에는 이것이 버그라고 나와 있습니다.{ cmd1 && cmd2 } &
해결 방법 으로 사용됩니다 .
A && B
다른 쉘처럼 백그라운드에서 서브쉘을 실행하려면 다음을 사용하십시오.
(A && B) &
또는 FAQ 항목에서 제안한 대로:
{A && B} &
비동기식으로 실행해야 한다면 어쨌든 프로세스를 포크해야 하기 때문에 이는 동일합니다(그리고 그 동안 기본 셸 프로세스는 나머지 스크립트를 계속 실행합니다).
그래서 여기 있습니다:
(nohup a.sh && nohup b.sh) &
그러나 하위 쉘을 실행하는 프로세스와 해당 프로세스가 생성되는 다른 프로세스가 SIGHUP 신호에 영향을 받지 않도록 하려는 경우:
(trap '' HUP; A && B) &
< /dev/null >> nohup.out 2>&1
( nohup을 더 가깝게 모방하기 위해 일부를 추가할 수도 있습니다 )
대신 다른 sh 유사 쉘에서 zsh와 동일한 동작을 원하는 경우:
A && { B & }
(기억해주세요zsh 이외의 쉘에서 작업 제어가 활성화되지 않으면 비동기 실행 목록의 stdin이 /dev/null로 리디렉션됩니다.)
1 이전 문서의 문구로 인해 의도하지 않은 편차가 있을 수 있습니다.2000년에 변경된 내용으로 실제 동작과 일치하도록 수정되었습니다.(이 내용은 1990년 zsh 1.0으로 거슬러 올라갑니다) sh 동작을 설명합니다. 이것은 FAQ의 결론이기도 합니다."설명서에는 이것이 버그라고 나와 있습니다." 1997년부터. 하지만 지금 바꾸기에는 너무 늦었습니다(그러나 일부 사람들은 sh, csh 또는 ksh 에뮬레이션에서 변경해야 한다고 생각합니다).
답변2
다음 두 명령을 결합해야 합니다.
nohup sh -c 'a.sh; b.sh' &
성공적인 종료에서만 실행하려면 다음 ;
으로 바꾸십시오.&&
b.sh
a.sh