Bash: 명령을 백그라운드 작업으로 대체

Bash: 명령을 백그라운드 작업으로 대체

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)
}

관련 정보