引数と標準入力を混同しています。プログラムにデータをパイプすることは、コマンド ライン引数を与えることと同じではありません。
最初のケースでは、スクリプトに引数を渡さず、標準入力ストリームを介してデータを供給するだけです。だから $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 に書き込みます