web-dev-qa-db-ja.com

エコーコマンドで配管が機能しない

次のBashスクリプトを実行すると、Helloが出力されるはずです。代わりに、空白行を出力して終了します。

echo 'Hello' | echo

pipingからechoへのecho出力が機能しないのはなぜですか?

45
Elliot A.

echoは、すべての引数を出力します。 stdinからは読み取りません。したがって、2番目のechoは、Hellostdinを無視して、すべての引数(なし)を出力して終了します。

stdinを読み取り、それをstdoutに出力するプログラムの場合、catを使用します。

$ echo Hello | cat
Hello
53
iobender

パイプを理解していないようです。この場合、名前がないため(named pipes)もあるため、anonymousパイプとしてより正確に知られています。匿名パイプは、たとえば同じ親を持つプロセスなど、関連するプロセス間でのみ機能します。

パイプは、Cランタイムライブラリに起因するIOシステムの一部です。これらのストリームはデフォルトでバッファリングされます(例外があります)。基本的に、パイプは、あるプロセスの出力バッファーを別のプロセスの入力バッファーに接続するだけです。

使用される最初の3つのストリーム(ファイル記述子と呼ばれる)には、0、1、および2の番号が付けられます。最初の0は、標準入力、またはstdin(Cで使用される名前)。デフォルトではこれはキーボードに接続されていますが、<シンボルまたはパイプの右側にあるプログラム名を使用してリダイレクトできます。

2番目の1は、標準出力またはstdoutとして知られています。デフォルトでは、これは端末画面に接続されていますが、>シンボルまたはパイプの左側にあるプログラム名を使用してリダイレクトできます。

そう:

echo 'Hello' | echo

echoから標準出力を取得し、echoの標準入力に渡します。しかし、echoは標準入力を読みません!だから何も起こりません。

フィルタープログラムは、コマンドラインで指定されたファイル名を処理します。ファイル名が指定されていない場合、標準入力を読み取ります。例には、catgrep、およびsedが含まれますが、notechoです。例えば:

echo 'Hello' | cat

「Hello」と表示され、catは役に立たない(多くの場合)。

echo 'Hello' | cat file1

echoからの出力をignoreし、file1の内容のみを表示します。 stdinは、ファイル名が指定されていない場合にのみ読み取られることに注意してください。

これは何を表示すると思いますか?

echo 'Hello' | cat < file1 file2

なぜ?

最後に、3番目のストリーム2はstandard errorまたはstderrと呼ばれ、これはunbufferedです。パイプはstdinとstdoutの間でのみ動作するため、無視されます。ただし、stdoutを使用するようにstderrをリダイレクトできます(man dup2を参照):

myprog 2>&1 | anotherprog

2>&1は、「ファイル記述子2をファイル記述子1と同じ場所にリダイレクトする」ことを意味します。

上記は通常の動作ですが、プログラムは必要に応じてすべてをオーバーライドできます。たとえば、ファイル記述子2から読み取ることができます。 process substitutionhere documentsなどの他の形式のリダイレクトなど、他の多くの詳細は省略しました。

15
cdarke

パイプは、stdinから入力を受け取るコマンドに対してのみ実行できます。ただし、エコーはstdinから取得しません。引数から入力を取得して出力します。したがって、これは機能しません。エコーするには、echo $(echo 'hello')のようなことができます

5
Rakesh Nair

echo(ビルトインと/bin/echoの両方)がstdinから何も読み取らないためです。

代わりにcatを使用します。

echo 'Hello' | cat
Hello

またはパイプなし:

cat <<< 'Hello'
2
anubhava