web-dev-qa-db-ja.com

stdinがシェルスクリプトのターミナルまたはパイプからのものであるかどうかを確認するにはどうすればよいですか?

foo.sh < test.txtのように、非対話的にstdinから入力を受け取る場合と受け取らない場合があるPOSIXシェルスクリプトを作成しています。

while read -r line...で停止しないように、stdinに何かがあるかどうかを確認するにはどうすればよいですか?

33
l0b0

質問が正しければ、次のことを試してみてください。

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

質問に文字通り答えるには(ただし、実際に必要なものではありません):read -t 0

タイムアウト、ゼロ秒。

  1. これは、左側がデータを提供する準備ができているかどうかに応じて、競合状態です。 -t 5を指定できますが、スラッシングシステムではそれでも問題があります。
  2. read -tはSUSv3では標準化されていません。 BSD sh、bash、zshにあります。 kshやダッシュではありません。

したがって、#!/ bin/shを使用して、これを期待することはできません。

基本的な問題は、現在stdinに何もないとしても、すぐになくなるという意味ではないということです。プログラムを呼び出すと、通常、stdinは端末などに接続されたままになるため、何が必要かを判断する方法はありません。

だから、あなたの質問に文字通り答えるために、あなたはそれをすることができます、しかし実際にはあなたの選択肢は次のとおりです:

  1. stdinがttyであるかどうかをテストします:[ -t 0 ]
  2. argvを使用して動作を制御する
8
Phil P

「cat」コマンドと同様の動作を簡単に実装できます。これは、提供されたファイルのリストから読み取られるか、提供されていない場合はstdinから読み取られます。

このアイデアを使用しないかもしれませんが、このLinux Journalの記事はあなたにとって興味深いものになると思います http://www.linuxjournal.com/content/determine-if-Shell-input-coming-terminal-or-pipe

:-)

6
darkturo

スクリプトをインタラクティブに実行したくない場合は、stdinを使用するのではなく、入力ファイルをパラメーターとして受け取るようにします。一部のプログラムは、フラグまたは特別なファイル名を使用して、ファイルからではなく標準入力から入力を受け取る必要があることを示します。その場合、必要に応じてコマンドラインジョッキーを処理できます。

スクリプトに標準入力を使用させたい場合は、スクリプトをインタラクティブに(または少なくとも他のPOSIXツールのように動作させて)みませんか?

1
Carl Norum