não pode acessar a saída padrão de um comando

3

Estou usando este formato de comando:

cmd0 > >(cmd1) 2> >(cmd2)

O cmd2 precisa retornar os dados ao zenity enquanto processa alguns dados, mas o zenity nunca ouve os ecos. Parece que os ecos são perdidos porque o cmd2 é delimitado pelo (..) . Um esboço do meu código é mostrado abaixo. casos 1 e 3 funcionam bem. Zenity nunca recebe o eco do caso 2. Eu verifiquei que o caso 2 faz eco corretamente, enviando também os dados para um arquivo. Eu estou procurando um método para ecoar os dados para zenity durante a leitura.

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
}
    
por daniel 17.10.2015 / 12:51

2 respostas

2

Seu problema é que você está redirecionando stderr antes redirecionando o stdout. Deve funcionar se você trocá-los. Para ilustrar, considere os seguintes scripts. foo.sh é impresso em stderr e stdout:

#!/usr/bin/env bash
## foo.sh

## Print "out" to standard output
echo out
## Print "error" to standard error
echo error >&2

bar.sh lê a entrada:

#!/usr/bin/env bash
## bar.sh

read input
## Print your input
echo "bar.sh read: $input"

E o mesmo acontece com baz.sh :

#!/usr/bin/env bash
## baz.sh

read input
## Print your input
echo "baz.sh read: $input"

Agora, se eu executar esses três como você parece estar tentando fazer e passar sua saída para um loop while , ele funcionará como esperado:

$ foo.sh 2> >(bar.sh) > >(baz.sh) | while read line; do echo "$line"; done
bar.sh read: error
baz.sh read: out

No entanto, falha se você fizer o inverso:

$ foo.sh > >(bar.sh) 2> >(baz.sh) | while read line; do echo "$line"; done
bar.sh read: out
    
por 17.10.2015 / 15:57
0

Essa é uma cadeia de redirecionamento muito tola que você uniu aqui. Eu não entendo o que você está realmente tentando fazer lá, mas você definitivamente interpretou erroneamente a fonte do seu problema. Talvez isso te dê uma ideia:

[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]

É claro que echo não escreve para o stdout do loop while - você o substitui nesse comando com qualquer canal command1 quando você faz:

> >(command1) 2> >(command2)

Redirecionamentos são processados em ordem - da esquerda para a direita para cada comando. E cada uma dessas substituições de processos que você faz afeta o mesmo comando .

Estou disposto a apostar que o que você está realmente tentando fazer é muito mais perto de:

command0 | command1 2>&1 >/dev/null | command2
    
por 17.10.2015 / 15:46