无法从命令访问标准输出

无法从命令访问标准输出

我正在使用这个命令格式:

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"

现在,如果我像您试图做的那样运行这三个并将它们的输出传递到循环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]

当然echo不会写入while循环的标准输出 - 您可以在该命令中将其替换为任何管道command1当你这样做时会读到:

> >(command1) 2> >(command2)

重定向按顺序处理 - 每个命令从左到右。您所做的每一个流程替换都会影响相同的命令

我愿意打赌你真正想做的事情更接近于:

command0 | command1 2>&1 >/dev/null | command2

相关内容