2010-03-16 84 views
25

我正在編寫一個POSIX外殼腳本​​,它可能會或可能不會從標準輸入接收輸入(如foo.sh < test.txt,非交互式)。如何檢查stdin上是否有任何內容,以避免在while read -r line...上停止?檢測外殼腳本中標準輸入內容的存在

+0

標準輸出:http://stackoverflow.com/questions/911168/how-to-detect-if-my-shell-script-is-running-through-a-pipe – 2017-05-11 09:01:10

回答

39

如果我有問題的權利,你可以嘗試以下方法:

#!/bin/sh 
if [ -t 0 ]; then 
    echo running interactivelly 
else 
    while read -r line ; do 
     echo $line 
    done 
fi 
+0

只是向上看,這是由於stdin和捕獲stdout時觸發的。 (二者interactivelly運行) ./yourscript <./the_input_your_giving_your_script.txt && ./yourscript> ./what_your_script_outputs。txt – DebugXYZ 2014-06-29 05:23:03

+1

@DeShawnWilliams不,@ dmedvinsky的回答是正確的:如果在終端上打開文件描述符'n','test -tn'爲true,因此'test -t 0'只檢查stdin,'test -t 1 '只檢查標準輸出。 – bootleg 2015-05-22 07:55:09

1

如果您從不想以交互方式運行腳本,請將輸入文件作爲參數,而不是使用stdin。某些程序使用標誌或特殊文件名來表示它們應該從標準輸入而不是從文件輸入;該案例可以讓你在必要時處理命令行操作。

如果您希望您的腳本採用標準輸入,爲什麼不想讓它成爲交互式(或至少像其他POSIX工具一樣)?

+4

一種常見的方式來告訴程序從標準輸入讀取的文件是提供'-'而不是文件名。 – Cascabel 2010-03-16 18:07:46

6

您可以輕鬆實現類似的行爲作爲「貓」的命令,即從提供的文件,或者如果列表請他們'沒有提供,然後從標準輸入讀取。

雖然你可能不使用這種想法,我覺得這篇Linux Journal中會是很有意思的,你http://www.linuxjournal.com/content/determine-if-shell-input-coming-terminal-or-pipe

:-)

+0

嗯,從中午回覆。很酷^ _^ – darkturo 2010-03-16 18:08:26

+0

該鏈接非常有幫助,謝謝! – hamstar 2013-08-14 21:47:35

8

爲了從字面上回答這個問題(但不是你真正想要的東西):read -t 0

超時,零秒。

  1. 這是一種競爭條件,取決於左側何時準備提供數據。您可以指定-t 5,但是在抖動系統上即使有問題也是如此。
  2. ​​在SUSv3中沒有標準化。它在BSD sh,bash,zsh中。它不在ksh或破折號中。

所以你不能只使用#!/ bin/sh,並期待有這個。

基本的問題是,即使現在沒有任何標準輸入,這並不意味着不會很快。調用一個程序通常會讓stdin連接到終端/無論如何,所以無法告訴需要什麼。

所以,從字面上回答你的問題,你可以做到這一點,但實際上你的選擇是:

  1. 測試,如果標準輸入是一個tty:[ -t 0 ]
  2. 使用argv的控制行爲
+1

我剛剛使用zsh進行了試驗。我注意到'read -t'或等價地'read -t0'具有**非確定性**行爲。所以,如你所說,避免使用它。 – Tarrasch 2013-01-01 18:25:51

+1

但是,這要與答案中使用的_test_「-t」區分開來。 – 2014-11-20 00:21:01