Linux

如果有 any 標準輸入,我該如何解決程序失敗的問題?

  • July 11, 2013

例如,以下工作正常:

/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”前綴的版本可以正常工作)

我什至不知道為什麼會發生這種情況。即使我沒有明確指定程序應該從哪裡讀取,Stdin 也會打開,所以這不應該是原因。

有沒有辦法解決這個問題?

編輯:

輸出的最後四行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

似乎program等待標準輸入發生某些事情,如果遇到換行符或 EOF 則退出(我們可以從selectstrace 輸出中的呼叫中看到它 - 如果輸入來自“真實”使用者,它會超時)。因此,我們需要一個不向標準輸入寫入任何內容,同時仍保持打開狀態的程序——sleep完成這項工作。

這是一個 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,只是它還監視程序完成,並在完成時立即退出。如果 /usr/bin/program 需要任何參數,您可以將它們添加到行尾。

*sleep forever不起作用,但如果你 GNU sleep 將永遠休眠sleep inf

引用自:https://unix.stackexchange.com/questions/82665