bash substituição de comando com redirecionamento: bad file descriptor

4

o seguinte comando funciona em traço, mas falha no bash com "Descritor de arquivo incorreto".

$ dash -c 'out=$(echo "to fd3" >&3; echo "to stdout") 3>&1; echo "out: $out"'
to fd3
out: to stdout

$ bash -c 'out=$(echo "to fd3" >&3; echo "to stdout") 3>&1; echo "out: $out"'
bash: 3: Bad file descriptor
out: to stdout

quando eu substituo a subestação de comando por um subshell, então parece funcionar em dash e bash.

$ dash -c '(echo "to fd3" >&3; echo "to stdout") 3>&1'
to fd3
to stdout

$ bash -c '(echo "to fd3" >&3; echo "to stdout") 3>&1'
to fd3
to stdout

versões:

$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-unknown-linux-gnu)

não sabe como obter a versão do traço. a página man no meu sistema é de 19 de janeiro de 2003.

pesquisa:

Eu olhei para cima como bash e traço executa um comando. isso é o que eu encontrei.

para o bash: link

para traço: link (seção "Comandos simples")

até onde eu entendo, ambos fazem expansões antes dos redirecionamentos. substituição de comando é uma expansão. então faz sentido que o descritor de arquivo 3 não esteja configurado na substituição do comando.

por que funciona em traço? por que não funciona em bash? é um bug no traço? ou bash? é uma construção válida?

    
por lesmana 05.10.2017 / 13:28

1 resposta

3

Se os redirecionamentos são realizados antes ou depois da expansão da atribuição é não especificado pelo POSIX quando não há comando , então ambos são válidos e você não pode confiar em nenhum deles. Então portável, você precisaria:

{ out=$(echo "to fd3" >&3; echo "to stdout"); } 3>&1

AT & T ksh e o shell Bourne se comportam como bash ; zsh , pdksh , yash se comportam como dash neste caso.

    
por 05.10.2017 / 13:32