bash 함수에서 프로세스를 트리거하고 잊어버리려고 합니다. 나는 이 함수가 프로세스가 실제로 트리거되었다는 사실에 해당하는 상태를 반환하고 함수의 출력을 검색하여 하위 프로세스의 PID를 가져오기를 원합니다. 그래서 나는 이렇게 썼다:
my_ping() {
# ... param check which potentially return 1
ping "$1" &
local pid
pid="$!"
echo "$pid"
return 0
}
명령 대체와 함께 호출되면 함수는 차단되고 절대 반환되지 않습니다(명령 대체 외부는 차단되지 않습니다).
main() {
# my_ping www.google.com # does not block and print PID
# Blocks waiting for ping to terminate
local mp_pid
mp_pid=$(my_ping www.google.com)
}
main "$@"
이 경우 함수가 왜 차단되는지 이해가 되지 않습니다. 다양한 방법(setsid, disown 등...)을 시도했지만 성공하지 못했지만 무슨 일이 일어나고 있는지 잘 모르겠습니다. 이 상황을 이해하는 데 도움이 되는 조언이 있나요?
답변1
ping
기본값(명령 대체를 통해 생성된 파이프라인)이 아닌 다른 위치 로 출력을 리디렉션해야 합니다 . 프로세스가 여전히 파이프의 쓰기 끝 부분에 대한 참조를 보유하고 있는 한 기본 쉘은 EOF를 얻지 못하고 명령 대체에서 모든 출력을 얻을 때까지 계속 기다립니다.
예를 들어 스크립트의 원시 표준 출력으로 리디렉션하려면 다음을 수행하세요.
my_ping() {
...
ping "$1" >&"$out" &
...
}
main() {
exec {out}>&1
...
mp_pid=$(my_ping www.google.com)
}