標準入力がターミナルからのものか、シェルスクリプトのパイプからのものかを確認するにはどうすればよいですか?
質問
次のように stdin から入力を受け取る場合と受け取らない場合がある POSIX シェル スクリプトを作成しています。 foo.sh < test.txt
, 、非対話型。
停止を避けるために、標準入力に何かがあるかどうかを確認するにはどうすればよいですか while read -r line...
?
解決
私は質問権を取得する場合、あなたは次のことを試してください:
#!/bin/sh
if [ -t 0 ]; then
echo running interactivelly
else
while read -r line ; do
echo $line
done
fi
他のヒント
質問に文字通りに答えるには (ただし、実際に望むものではありません): read -t 0
タイムアウト、0 秒。
- これは競合状態であり、左側がいつデータを提供する準備ができているかによって異なります。指定できます
-t 5
しかし、スラッシング システムではそれさえ問題になります。 read -t
SUSv3では標準化されていません。BSD sh、bash、zsh にあります。ksh やダッシュにはありません。
したがって、 #!/bin/sh を使用するだけでこれを期待することはできません。
基本的な問題は、現在標準入力に何もないとしても、すぐになくなるわけではないということです。プログラムを呼び出すと、通常、stdin は端末などに接続されたままになるため、何が必要なのかを知る方法はありません。
したがって、質問に文字通りに答えることはできますが、実際には次のような選択肢があります。
- stdin が tty かどうかをテストします。
[ -t 0 ]
- argv を使用して動作を制御する
「cat」コマンドと同様の動作を簡単に実装できます。つまり、提供されたファイルのリストから読み取るか、ファイルが提供されていない場合は標準入力から読み取ることができます。
あなたはこのアイデアを使用しないかもしれませんが、この Linux Journal の記事はあなたにとって興味深いものになると思います http://www.linuxjournal.com/content/determine-if-shell-input-coming-terminal-or-pipe
:-)
あなたが対話的にスクリプトを実行したくない場合は、それはむしろstdin
を使用するよりも、パラメータとして入力ファイルを取ります。一部のプログラムは、彼らが標準入力からではなく、ファイルからの入力を取る必要があることを示すフラグや特別なファイル名を使用します。その場合は、必要な場合は、コマンドラインの画策を処理できます。
、なぜあなたはそれが対話的(あるいは、少なくとも他のPOSIXツールのように振る舞う)させたくない?