heredocスクリプトのstdinスクリプトを読み取り、「sh」にパイプします。

heredocスクリプトのstdinスクリプトを読み取り、「sh」にパイプします。

期待どおりに動作します。

$> cat ./readfromstdin.sh
echo reading
cat /dev/stdin

$> echo hello | ./readfromstdin.sh
reading
hello

一時ファイルなしで同様のことを達成しようとしています。私の最初の試みは

echo hello | (echo cat /dev/stdin|sh)

これはうまくいきません。 heredocを使うとうまくいきません(正しい構文が何であるかはわかりませんが:

echo hello | (cat << EOF | sh
cat /dev/stdin
EOF)
pipe cmdsubst pipe heredoc>

シェルにパイプされたスクリプトを使用してstdinからデータを読み取ることはできますか?

答え1

サブシェルにパイプを接続すると、比較的簡単に説明する操作を実行できます。

$ echo hello | ( echo reading; cat /dev/stdin )
reading
hello

私はこれについてのどのユースケースも想像できないことを認めています。ただしないでください。

$ echo hello | ( echo reading; read var; echo "$var")
reading
hello

これにより、標準入力の内容を変数として保存し、余暇に操作できます。

答え2

$ echo 'world' |  { echo 'hello'; cat }
hello
world

他のオペランドが指定されていない場合は、基本的に操作が実行されるため、これを明示的/dev/stdinに指定する必要はありません。catcat

自分のコードから次を渡したいようです。注文する出力する文字列ではなくsh、とにかく、これがコードの存在を解釈する方法です。しかし、これがあなたに必要かどうかは完全にはわかりません。

これを行うときに発生する問題は、スクリプトにsh標準入力を提供することによって発生します。したがって、標準入力はコマンド用に予約されているため、ここに文字列をパイプすることは機能しません。

答え3

親プロセスで渡されたstdinを参照するstdinを介して、コマンドが渡されたサブシェルからstdinにアクセスすることを意味しますか?

これは本当に一口の物語です。これはどういう意味ですか?

$ cat ~/.tmp/test.sh 
#!/bin/bash
set -eu

echo i am stdin from pipe | {
    echo '0</dev/fd/100 cat -' | sh -x

} 100<&0
$ ~/.tmp/test.sh 
+ cat -
i am stdin from pipe
  • echo i am stdin from pipe100<&0参照損失を防ぐには、fdにリダイレクトしてください。
  • '0</dev/fd/100 cat -'標準入力に文字列として渡され、評価されsh -x実行されます。
  • 標準入力参照は、標準出力に文字列を書き込むプロセスに/dev/fd/100リダイレクトされます。/dev/stdincat -i am stdin from pipe

どうやら申し上げたら絶対にしないでください^^。

関連情報