*모든* 표준 입력이 있는 경우 프로그램이 실패하는 문제를 어떻게 해결합니까?

*모든* 표준 입력이 있는 경우 프로그램이 실패하는 문제를 어떻게 해결합니까?

예를 들어 다음은 정상적으로 작동합니다.

/usr/bin/program

일부 출력을 생성하고 결과를 얻습니다.

하지만 내가 이렇게 부르면:

echo -n | /usr/bin/program

아니면 이거

echo -n | bash -c "/usr/bin/program"

아니면 이것도:

echo -n | bash -c "wc -c; /usr/bin/program"

일부 출력 라인을 생성한 다음 실패합니다. 프로그램의 소스 코드에 접근할 수 없기 때문에 이러한 동작을 일으키는 원인이 무엇인지조차 알 수 없습니다.

Python 스크립트에서 호출하려고 하면 동일한 결과가 나타납니다.

echo | python -c 'from subprocess import call; call("/usr/bin/program", shell=True)'

("echo" 접두사가 없는 버전은 잘 작동합니다)

왜 이런 일이 일어나는지조차 모르겠습니다. 프로그램이 어디에서 읽어야 하는지 명시적으로 지정하지 않더라도 표준 입력이 열려 있으므로 이것이 원인이 되어서는 안 됩니다.

이 문제를 해결할 방법이 있나요?

편집하다:

출력의 마지막 네 줄 strace- 유일한 다른 줄은 다음과 같습니다.

# without echo
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
...

# with echo
select(1, [0], NULL, NULL, {0, 0})      = 1 (in [0], left {0, 0})
write(4, "\0\0\0j\0\0\0\3\0\0\0\4\0\0\0\0\377\377\377\377", 20) = 20
write(3, "\0\0\0j\0\0\0\3\0\0\0\4\0\0\0\0\377\377\377\377", 20) = 20
exit_group(1)                           = ?

부분적인 해결책:

sleep 20 | /usr/bin/program

programstdin에서 어떤 일이 일어날 때까지 기다리고 개행이나 EOF가 발생하면 종료하는 것 같습니다 ( selectstrace 출력의 호출에서 볼 수 있습니다. 입력이 "실제" 사용자로부터 오는 경우 시간 초과됩니다). 따라서 우리는 표준 입력을 열어두면서 표준 입력에 아무것도 쓰지 않고 sleep작업을 수행하는 프로그램이 필요합니다.

답변1

당신이 요구하는 것을 수행하는 Perl 한 줄짜리 코드는 다음과 같습니다:

perl -e '$SIG{CHLD} = sub{exit 0}; open $fh, "|-", @ARGV or die; sleep 20 while 1;' /usr/bin/program

sleep forever | /usr/bin/program이는 프로그램 완료를 모니터링하고 완료되자마자 종료된다는 점을 제외하면 본질적으로 Myth* 와 동일합니다 . /usr/bin/program에 매개변수가 필요한 경우 해당 매개변수를 행 끝에 추가할 수 있습니다.

*는 sleep forever작동하지 않지만, GNU sleep은 영원히 잠들 것입니다 sleep inf!

관련 정보