Troca STD {OUT, ERR} em um pipeline várias vezes

0

Com base em esta resposta , escrevi o seguinte que troca os descritores de arquivo 1 e 2:

 

swap12 :

#!/bin/bash
"$@" 3>&1 1>&2 2>&3 3>&-

Eu posso então operar em STDERR em um pipeline, por exemplo:

$ swap12 ls -ld /tmp /ooooooo | tr o X
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 19 root root 1400 Jul  1 17:14 /tmp

No entanto, a troca dos FDs não funciona várias vezes:

$ swap12 ls -ld /tmp /ooooooo | swap12 tr o X | tr o Z
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 19 root root 1400 Jul  1 17:14 /tmp

Acima, estou esperando que o segundo swap12 troque novamente STDOUT e STDRR, então o segundo tr operaria no STDOUT original de ls . Estou esperando ver:

$ swap12 ls -ld /tmp /ooooooo | swap12 tr o X | tr o Z
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 19 rZZt rZZt 1400 Jul  1 17:14 /tmp

Como posso alcançar o que estou procurando?

Tenho a sensação de que meu problema se deve à alteração dos descritores de arquivos em subshells. Haveria uma vantagem para implementação como zsh global alias -g alias? (Mas como a implementação de bash pareceria?)

    
por Tom Hale 01.07.2018 / 12:23

2 respostas

3

Normalmente, stderr vai diretamente para o terminal e stdout vai para o canal:

          ls stdout -->
ls -ld /tmp /ooooooo | tr o X
 |
 v ls stderr (to terminal)

Depois de trocá-los, stdout vai para o terminal e não para o pipe:

                 ls stderr -->
swap12 ls -ld /tmp /ooooooo | tr o X
        |
        v ls stdout

A troca de stdout / stderr do tr não envolve o stderr de ls resultante, pois foi redirecionado para fora do pipeline anteriormente.

                 ls stderr -->   tr stderr -->
swap12 ls -ld /tmp /ooooooo | swap12 tr o X | tr o Z
        |                             |
        v ls stdout                   v tr stdout

Se você quiser processar os stdout e stderr de ls separadamente, você pode usar a substituição de processos (deve funcionar no Bash e no Zsh):

$ ls -ld /tmp /ooooooo 2> >(tr o X)  > >(tr o Z) 
ls: cannXt access '/XXXXXXX': NX such file Xr directXry
drwxrwxrwt 25 rZZt rZZt 4096 Jul  1 14:40 /tmp/
    
por 01.07.2018 / 13:43
0

O canal conectou ls.stderr a tr1.stdin . Em seguida, você troca tr1.stdout e tr1.stderr e canaliza tr1.stderr para tr2.stdin tr2 não encontra o s, portanto, não faz nada.

O segundo swap12 não deve e não desfaz o primeiro.

Você pretendia fazer ./swap12 ./swap12 ls -ld /tmp /ooooooo | tr o X . Isso desfaz a troca.

    
por 01.07.2018 / 12:38

Tags