쉘 스크립트의 표준 입력을 백그라운드 명령에 전달하는 방법

쉘 스크립트의 표준 입력을 백그라운드 명령에 전달하는 방법

쉘 스크립트에서는 쉘 스크립트와 동일한 표준 입력을 사용하여 백그라운드 명령을 시작하려고 합니다.

#!/bin/sh
# ...

the-program &

그러나 the-program위의 방법은 쉘 스크립트와 동일한 표준 입력에 액세스할 수 없습니다. 내 쉘 매뉴얼에 따르면 (대시(1)):

쉘이 대화형이 아닌 경우 비동기 명령의 표준 입력은 로 설정됩니다 /dev/null.

시도해 보았 the-program & <&0으나 원하는 효과를 얻지 못한 것 같습니다. 표준 입력은 the-program여전히 ​​입니다 /dev/null.

나는 쉘 스크립트의 표준 입력을 복사하고 어떻게든 그 새 파일 설명자를 백그라운드 프로세스에 전달하여 새 파일 설명자를 생성하는 것을 고려했습니다. 그러나 백그라운드 프로세스는 어떻게든 이 새 파일 설명자를 표준 입력(replacement /dev/null)으로 리디렉션해야 합니다. 이 아이디어가 가능한지 모르겠고 POSIX sh에서 구현하는 방법도 모르겠습니다.

답변1

응 짜증나POSIX sh사양 요구 사항비대화식 쉘을 통해 비동기적으로 시작된 명령을 호출하면( monitorIOW 작업 제어 옵션이 활성화되지 않은 경우) 해당 표준 입력이 /dev/null로 리디렉션됩니다.

작업 제어가 비활성화된 경우(참조 set) -m비동기 목록의 표준 입력은 명시적 리디렉션이 수행되기 전에 동일한 속성을 가진 파일에 할당된 것처럼 처리되어야 합니다 /dev/null. 작업 제어가 활성화된 경우에는 이런 일이 발생하지 않습니다. 모든 경우에 표준 입력의 명시적인 리디렉션이 이 활동을 재정의해야 합니다.

일반적인 해결책은 다음과 같습니다.

{ cmd <&3 3<&- & } 3<&0

이것은 당신이 생각하는 것과 같습니다.

예:

$ sh -c 'readlink /proc/self/fd/0 & wait' < /
/dev/null
$ sh -c '{ readlink /proc/self/fd/0 <&3 3<&- & } 3<&0; wait' < /
/

zsh또 다른 옵션은 시뮬레이션에서도 이 요구 사항을 무시하는 방법을 사용하는 것입니다 .sh

$ zsh -c 'readlink /proc/self/fd/0 & wait' < /
/
$ zsh --emulate sh -c 'readlink /proc/self/fd/0 & wait' < /
/

관련 정보