Linux
如果有 any 標準輸入,我該如何解決程序失敗的問題?
例如,以下工作正常:
/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 則退出(我們可以從select
strace 輸出中的呼叫中看到它 - 如果輸入來自“真實”使用者,它會超時)。因此,我們需要一個不向標準輸入寫入任何內容,同時仍保持打開狀態的程序——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
!