引数と標準入力を混同しています。プログラムにデータをパイプすることは、コマンド ライン引数を与えることと同じではありません。
最初のケースでは、スクリプトに引数を渡さず、標準入力ストリームを介してデータを供給するだけです。だから $1
スクリプトの全期間中、設定されていません。
more
の最初の呼び出し したがって、パラメータはなく、標準入力をページングします。これは、そこにパイプしたものを表示します (dir1
、テキストとして)。後続の echo
印刷するものがないため、新しい行のみを印刷し、最後の more
印刷するものも何も残っていません - 標準入力は最初のものによって「排出」されています.
2 番目のケースでは、引数を渡します。つまり $1
値は dir2
です スクリプトで。最初の more
以外は同じことが起こります。 両方:
- 両方の標準入力のページ
- ファイル
dir2
のページングを試みます これはディレクトリであるため、エラーが発生します
$1
を指定すると、エコーは期待どおりの動作をします dir2
を含む 、および最後の more
dir2
のエラーのみ - 標準入力から読み取るものは何もありません。
違いは「引数」にあります " VS "標準入力 ".
echo dir1 | bash script.sh
を実行すると 、$1
議論 あなたの script.sh
で 引数が与えられていないため、常に空です ( set -x
を追加してみてください 開始すると、デバッグ出力に表示されます。dir1
標準入力からエコーされます more
として 引数が指定されていない場合、コマンドは stdin を読み取ります ($1
を思い出してください) 空です)
どのように cmd1 | cmd2
作品
パイプを使用する場合:
<オール>cmd2
cmd1
のサブプロセスです .cmd2
の標準入力 「接続されている」 cmd1
の標準出力 .Linux stdio lib はファイル記述子を介してバッファリングされたストリームを提供したため、stdin の内容は stdin が開かれたときのみ消費されます (つまり、1 回だけ読み取られます)。 .
一歩ずつ cmd1 | cmd2
ワークフロー
コマンド例:
<ブロック引用>
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
echo dir1 |
:「dir1\n
」と書く エコーされませんが、stdio を介してバッファリングされ、stdin を介してサブプロセスに使用できる最初のコマンドの stdout で。echo "a"
:「a\n
」と書く " on stdout; stdin を読みません! したがって、「dir1\n
" 文字列はまだ利用可能ですread stdinvalue
:EOL (または EOF) まで stdin を読み取り、文字列を bash 変数に格納しますecho "$stdinvalue"
:stdinvalue 変数の値を stdout に書き込みます