私は次のコマンド形式を使用しています。
cmd0 > >(cmd1) 2> >(cmd2)
Cmd2は一部のデータを処理するときにデータをzenityにエコーする必要がありますが、zenityはエコーを聞くことができません。 cmd2がによって生成されたため、エコーが失われたようです(..)
。以下に私のコードの概要を示します。ケース1と3は正常に機能します。 Zenityはケース2からエコーを受信しません。データをファイルに転送し、ケース2が正しくエコーされていることを確認しました。私は読みながらデータをzenityにエコーする方法を探しています。
function() {
while [ "$nf" -lt "$num_of_files" ]; do
((nf=$nf+1))
case "$process" in
1)
while read -d$'\r' str1; do
(commands ... )
echo "$percent_update"
done
;;
2) #feed the standout of cmd0 to cmd1 and the standerr of cmd0 to cmd2
command0 > >(command1) 2> >(command 2 ....
while read -d$'%' str1; do
percent=$(echo "$str1" | sed 's/\x08//g' | sed 's/ //g')
percent=$(scaler "$percent" "$nf" "$num_of_files")
echo "$percent_update"
echo "$percent_update" >>just to verify data exists & is good.txt
done)
;;
3)
(more commands)
echo percent
;;
esac
done | zenity --progress --percentage=0 --auto-close
}
答え1
問題はstderrをリダイレクトしていることです。今後標準出力をリダイレクトします。切り替えると動作します。これを説明するために、次のスクリプトを検討してください。foo.sh
stderrとstdoutで印刷する:
#!/usr/bin/env bash
## foo.sh
## Print "out" to standard output
echo out
## Print "error" to standard error
echo error >&2
bar.sh
入力を読む:
#!/usr/bin/env bash
## bar.sh
read input
## Print your input
echo "bar.sh read: $input"
またこれですbaz.sh
:
#!/usr/bin/env bash
## baz.sh
read input
## Print your input
echo "baz.sh read: $input"
今、あなたがしたいように、これら3つを実行して出力をループに渡すと、期待while
どおりに機能します。
$ foo.sh 2> >(bar.sh) > >(baz.sh) | while read line; do echo "$line"; done
bar.sh read: error
baz.sh read: out
しかし逆にすれば失敗します。
$ foo.sh > >(bar.sh) 2> >(baz.sh) | while read line; do echo "$line"; done
bar.sh read: out
答え2
これはあなたが結びついた非常に愚かなリダイレクトチェーンです。私は実際に何をしたいのか理解していませんが、問題の原因を間違いなく誤解しています。たぶんこれはあなたにアイデアを与えるでしょう:
[mikeserv@desktop top]$ > >(sed 's/^/hey there:\t/') 2> >(ls -l /dev/fd/*)
ls: cannot access /dev/fd/10: No such file or directory
ls: cannot access /dev/fd/255: No such file or directory
ls: cannot access /dev/fd/3: No such file or directory
hey there: lr-x------ 1 mikeserv mikeserv 64 Oct 17 06:38 /dev/fd/0 -> pipe:[10484689]
hey there: l-wx------ 1 mikeserv mikeserv 64 Oct 17 06:38 /dev/fd/1 -> pipe:[10484688]
hey there: lrwx------ 1 mikeserv mikeserv 64 Oct 17 06:38 /dev/fd/2 -> /dev/pts/3
hey there: l-wx------ 1 mikeserv mikeserv 64 Oct 17 06:38 /dev/fd/63 -> pipe:[10484688]
もちろん、ループのstdoutはecho
作成されませんwhile
。コマンドのパイプに置き換えることができます。command1
これにより、次の内容を読むことができます。
> >(command1) 2> >(command2)
リダイレクトは順次処理されます(各コマンドは左から右へ)。すべてのプロセスの交換は影響を与えます。同じコマンド。
私はあなたが本当にやりたいことが次に近いと確信しています。
command0 | command1 2>&1 >/dev/null | command2