GNU/Linux >> Linux の 問題 >  >> Linux

シェルスクリプトとパイプの動作に関する明確化

引数と標準入力を混同しています。プログラムにデータをパイプすることは、コマンド ライン引数を与えることと同じではありません。

最初のケースでは、スクリプトに引数を渡さず、標準入力ストリームを介してデータを供給するだけです。だから $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 に書き込みます

  • Linux
    1. スペースを含むファイル名をシェルスクリプトに渡しますか?

    2. スクリプトが終了したメッセージで突然終了しますか?

    3. シェルスクリプトの予期しない動作?

    1. 関数とパラメータを変数として持つシェルスクリプト?

    2. パイプからシェル変数に値を読み込む

    3. シェルスクリプトを使用して HTML メールを送信する

    1. Pythonスクリプトを使用してシェルの作業ディレクトリを変更する

    2. シェル スクリプトを使用してデータベース接続を確認する

    3. 変数でディレクトリを変更するシェルスクリプト