コマンドが完了するのを待ってから、stdinをstdoutにパイプする方法を見つけようとしています。私はMacを使用していますが、私の質問は、Macに関連するものよりもプロセスが完了するのを待って出力をパイプする方法です。
Macでは、複数のコマンドを一緒に実行できます。演算子を使用してコマンドをリンクすると、次のsay
コマンドを開始する前に各構文が完全に話されるまで待ちます。&&
$ say "stage 1" && say "stage 2"
これが実際のユースケースです。 bashスクリプトがあり、stdinをstdoutに渡したいと思います。後ろに終わりました。
$ cat /etc/passwd | say_and_pass "stage 1" | grep -v test | say_and_pass "stage 2"
したがって、概念的には、これは「フェーズ1」と大声で話し、すぐに「フェーズ2」と言い、次にgrepの内容を/etc/password
標準出力にダンプします。
スクリプトの初期クラックはsay_and_pass
次のとおりです。
話し合う
#!/usr/bin/env bash
OUT="$*"
say "$OUT" && cat
しかし、うまくいかないようです;-)
編集:上記の例をsay_and_pass "stage2"
最終コマンドとして使用するように変更しました。これは必要なものです。私のソリューション働く...
ベストアンサー1
これが実際のユースケースです。何かを完了した後にstdinをstdoutに渡したいbashスクリプトがあります。
$ cat /etc/password | say_and_pass "stage 1" | grep -v test | say "stage 2"
ここでやろうとしていることの問題は、2つのデータストリームがあるように見えることです。 1つはテキストsay
処理用で、もう1つはテキスト処理用です(例:cat
sum grep
)。
データを混在させるため、単一のパイプラインは使用できません。 cat /etc/passwd | say
コンピュータはファイルの内容全体を読み取ろうとします。しかも書かsay
ないでください。何もない標準出力に変換するので、パイプには何も残りません。
データ処理ストリームを「中断」する他のユーティリティ(say
一時ファイルなど)。
あなたのデモケースは例としてあまり役に立ちません。なぜならsay
sにもかかわらずgrep
ファイルをpingするだけなのでgrep -v test /etc/passwd
(cat file | grep pattern
は次のようにすることができます。役に立たない使用cat
)。
要約すると、次は一時ファイルを使用する例です。
scratch=$(mktemp)
trap "rm -f $scratch" EXIT
cat /etc/passwd > $scratch
say "Stage one"
grep -v test $scratch
say "Stage two"
そのうちの1つは、名前付きパイプを使用して次のことを行いますsay
。
mkfifo youtalktoomuch
say youtalktoomuch &
exec 3> youtalktoomuch
do_thing_one
echo "Stage one" > youtalktoomuch
do_thing_two
echo "Stage two" > youtalktoomuch
exec 3>&-
rm youtalktoomuch
Once again, though, if you need to connect the output of `do_thing_one` to the input of `do_thing_two` without piping one into the other, you will need to use either another named pipe or a scratch file on disk to hold the data.