Subshell e substituição de processo

0

Desculpas se esta é uma questão básica - Eu estou preso tentando resolver um problema maior, e se resume a como um script de shell é invocado - diretamente ( shellScript.sh ) ou usando sh shellScript.sh .

Aqui está um modelo para o problema:

Quando executo no bash:

cat <(echo 'Hello')

vejo a saída

Hello

Mas quando eu uso:

sh -c "cat <(echo 'Hello')"

Eu vejo erros:

sh: -c: line 0: syntax error near unexpected token '('
sh: -c: line 0: 'cat <(echo 'Hello')'

Eu tentei escapar de < , ( e ) em várias combinações, mas não vejo a saída em nenhum lugar. O que estou perdendo aqui?

Meu problema real é que estou passando um <() como um argumento de entrada para um script python dentro de um script shell, e enquanto funciona bem quando invoco o script shell usando apenas o nome, se eu usar sh para invocá-lo, recebo erros semelhantes ao que mostrei acima.

Obrigado!

    
por Ram RS 09.05.2017 / 22:16

1 resposta

4

A substituição de processos é um recurso originado no shell Korn nos anos 80 (em ksh86). Na época, só estava disponível em sistemas que tinham suporte para arquivos /dev/fd/<n> .

Mais tarde, o recurso foi adicionado a zsh (desde o início: 1990) e bash (em 1993). zsh estava usando pipes nomeados temporários para implementá-lo, enquanto bash estava usando /dev/fd/<n> quando disponível e pipes nomeados de outra forma. zsh passou a usar /dev/fd/<n> quando disponível em 2.6-beta17 em 1996.

O suporte para a substituição de processos por meio de pipes nomeados em sistemas sem /dev/fd foi adicionado somente a ksh in ksh93u+ em 2012. O clone de domínio público de ksh não é compatível.

Até onde sei, nenhum outro shell parecido com o Bourne o suporta ( rc , es , fish , shells não semelhantes a Bourne suportam, mas com uma sintaxe diferente). yash tem uma <(...) de construção, mas isso é para redirecionamento de processo .

Embora bastante útil, o recurso nunca foi padronizado pelo POSIX. Então, não se pode esperar encontrá-lo em sh , então não deve usá-lo em um script sh .

Embora o comportamento de <(...) não seja especificado em POSIX, (portanto não haveria nenhum problema em retê-lo), bash desativa o recurso quando chamado como sh ou quando chamado com POSIXLY_CORRECT=1 em seu ambiente.

Portanto, se você tiver um script que use <(...) , deverá usar um shell que suporte o recurso para interpretá-lo como zsh , bash ou AT & T ksh (claro, você precisa certifique-se de que o resto da sintaxe do script também seja compatível com esse shell).

Em qualquer caso:

cat <(cmd)

Pode ser escrito:

cmd | cat

Ou apenas

cmd

Para um comando diferente de cat (que precisa receber dados por meio de um arquivo fornecido como argumento), em sistemas com /dev/fd/x , você sempre pode fazer:

something | that-cmd /dev/stdin

Ou se você precisar que o stdin de that-cmd seja preservado:

{ something 3<&- | that-cmd /dev/fd/4 4<&0 <&3 3<&-; } 3<&0 
    
por 09.05.2017 / 22:58