(bash) 스크립트 A는 스크립트 B를 기다리지만 하위 프로세스는 기다리지 않습니다.

(bash) 스크립트 A는 스크립트 B를 기다리지만 하위 프로세스는 기다리지 않습니다.

그래서 scriptA가 있고 그 역할은 다음과 같습니다.

ssh server1 -- scriptB &
ssh server2 -- scriptB &
ssh server3 -- scriptB &
wait
otherstuffhappens

ScriptB의 기능은 다음과 같습니다.

rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
exit

내가 원하는 결과는 scriptA가 계속하기 전에 scriptB의 모든 인스턴스가 완료될 때까지 기다리는 것입니다. 현재는 그렇게 하고 있지만 덜 중요한 항목의 백그라운드 rsync도 기다리고 있습니다. 이 파일은 더 크므로 기다리고 싶지 않습니다.

나는 다 읽었다nohup, disown, &의 차이점다양한 조합을 시도했지만 원하는 결과를 얻지 못했습니다.

이 시점에서 나는 혼란스러워진다. 어떤 도움이라도 대단히 감사하겠습니다!

답변1

여기서 문제는 sshd명령의 stdout을 읽는 파이프의 파일 끝을 기다리는 것입니다(적어도 테스트 중인 버전에서는 어떤 이유로 stderr 대신). 그리고 백그라운드 작업은 파이프라인의 fd를 상속합니다.

따라서 이 문제를 해결하려면 백그라운드 명령의 출력을 rsync일부 파일로 리디렉션하거나 /dev/null신경쓰지 않는 경우에 하십시오. 또한 stderr를 리디렉션해야 합니다. sshd가 해당 파이프를 기다리지 않더라도 sshd종료 후 파이프가 파괴되므로 rsyncstderr에 쓰려고 하면 파이프가 종료되기 때문입니다.

그래서:

rsync ... > /dev/null 2>&1 &

비교하다:

$ time ssh localhost 'sleep 2 &'
ssh localhost 'sleep 2 &'  0.05s user 0.00s system 2% cpu 2.365 total
$ time ssh localhost 'sleep 2 > /dev/null &'
ssh localhost 'sleep 2 > /dev/null &'  0.04s user 0.00s system 12% cpu 0.349 total

그리고:

$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null &'; sleep 2; cat out
141  # ls by killed with SIGPIPE upon writing the error message
$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null 2>&1 &'; sleep 2; cat out
2    # ls exited normally after writing the error on /dev/null instead
     # of a broken pipe

답변2

두 가지 모두의 부모인 스크립트를 작성하면 쉽게 할 수 있습니다.둘 다 제어. 또는두 채널 간의 통신 채널 구축.

특정 백그라운드 작업을 구체적으로 무시하려면 PID( $!마지막 백그라운드 작업 PID)를 캡처하고 wait $pid해당 작업이 완료될 때까지 기다리면 됩니다.

답변3

-fssh문제를 해결 하려면 플래그를 지정하세요. 테스트 대상:

#!/bin/sh -e
echo $$_script__begin
( echo sleeping; sleep 2; echo slept )&
echo $$_script__end

를 사용하여 실행하면 나타날 ssh localhost ./script때까지 기다립니다 . slept-f플래그를 사용하면 명령이 반환된 후 종료되고 echo $$_script__end나중에 slept백그라운드에 나타납니다.ssh

답변4

이것을 시도해 볼 수 있습니다. $!가장 최근에 실행된 백그라운드 파이프/프로세스의 프로세스 ID를 포함하는 기본 셸 변수입니다.

command1 &
lpid1=$!

command2 &
lpid2=$!

command3 &
lpid=$!

wait $lpid1  # waits for only the process with PID lpid1  to complete. 

스크립트를 기반으로 export변수 등을 사용하여 이를 활용 해야 합니다.

관련 정보