次のbashスクリプトコードを考えてみましょう。
#!/bin/bash
function bug_part() {
cat $1 > sample.first
cat $1 > sample.second #second time you open file $1, it contains no data
}
bug_part <(echo "TEST")
[ "$(cat sample.first)" != "$(cat sample.second)" ] && echo "THIS IS A BUG" 1>&2 && exit 1
rm sample.first sample.second
この問題がbashバグであることに同意しますか?それともLinuxのバグですか?
後ろから何が起こっているのか知っている人はいますか?
答え1
私はこれが間違いだとは思わない。次のコマンドで接続された名前付きパイプを読み書きできます。プロセスの交換一度だけ。
答え2
これはスクリプトのバグです。tee
一度だけ読み取ることができるデータをコピーするには、このオプションを使用します。他の回答で説明したように、<(cmd)はパイプを作成し、/dev/fd/62
コマンドラインに次の内容を入力します。
echo <(true)
/dev/fd/63
別の代替tee
は次の文字列です。
cmd <<<"$text"
Bashが検索可能なtmpファイルを生成し、そのファイルから入力をリダイレクトするようにしたい場合。 (しかし、関数内でstdinをファイルの先頭に巻き戻す方法がわかりません。cat /dev/stdin
同じファイルの場所を取得することは可能だと思います。)
答え3
tee
ファイル(/pipe)を2回読み込むのではなく、使用するように@Peter Cordesの提案を拡張すると、次のように関数を再構築できます。
bugless_part() {
tee sample.first >sample.second <"$1"
}
として実行すると、bugless_part <(echo "TEST")
「TEST」が2つのファイルに保存されます。