sh está avaliando código bash do shell pai e dividindo

3

Eu tenho este código em um script bash :

r2g(){

   echo "executable is: $0"  # "/bin/bash"

  (
      set -e;
      r2g_internal "$@" \
       2> >( while read line; do echo "r2g error: $line"; done ) \
       1> >( while read line; do echo "r2g: $line"; done )
  )

    exit_code="$?"
    if [[ "$exit_code" != "0" ]]; then
        echo "something experienced an error, to see log, run: r2g_view_log";
        return 1;
    fi
}

o que está acontecendo é que depois que r2g_internal é executado, sh é iniciado por algum processo e aparentemente tenta enviar o bash env, e eu recebo seu erro de sintaxe estranho de sh:

r2g error: sh: r2g: line 2: syntax error near unexpected token '>'
r2g error: sh: r2g: line 2: ' r2g_internal "$@" 2> >( while read line; do echo "r2g error: $line"; done ) > >( while read line; do echo "r2g: $line"; done ) );'
r2g error: sh: error importing function definition for 'r2g'

Eu fiz um vídeo demonstrando o problema: link

e um acompanhamento de vídeos: link

quando npm install é executado, algum sh process deve ser iniciado por npm .. git também parece ativar um processo sh às vezes quando executo comandos git, e o mesmo tipo de erro de sintaxe é exibido no terminal nesse caso.

Eu não consigo descobrir por que um processo sh iniciado via bash tentaria, então, fornecer algum código bash a partir do shell pai / env?

O vídeo torna o problema mais claro (espero).

se eu chamar unset -f r2g , o problema desaparece imediatamente. Então eu acho que /bin/sh está chamando minha função r2g, mas eu não sei como ou por quê.

Aqui está a fonte para r2g e r2g_internal juntos: link

    
por Alexander Mills 09.05.2018 / 02:36

2 respostas

3

Isso provavelmente não resolverá seu problema, apenas tire um momento para algumas notas, muito tempo para um comentário:

  • Se você não precisa fazer isso, não estruture seu código como uma única linha, estou citando:

    r2g_internal "$@"  2> >( while read line; do echo "r2g error: $line"; done ) 1> >( while read line; do echo "r2g: $line"; done )
    

    É ilegível para os outros e até para você eu suspeito.

  • Vou começar do começo:

    Não vejo shebang como:

    #!/bin/bash
    

    ou

    #!/bin/sh
    

    e assim por diante.

  • Se você não precisa do Bash, mas este script de shell parece precisar dele, use POSIX sh para fins de portabilidade.

  • Como exit_code é usado apenas uma vez, você pode evitá-lo.

  • Você não precisa citar o número sempre. Nesta instância "$?" .

  • Evite [[ .. ]] específico do Bash e use o comando de teste clássico. Neste caso:

    if [ $? -ne 0 ]
    
  • Você não precisa de ponto-e-vírgula no final da linha, você pode usar estrutura como esta:

    if [ $? -ne 0 ]
    then
        echo "something experienced an error, to see log, run: r2g_view_log"
        return 1
    fi
    
  • Use a opção -r com read . Leia mais sobre este tópico aqui .

  • Eu fiz alguns ajustes, confira, por favor.

  • Não tenho certeza se isso é intencional, mas suponho que não; onde você usou return 1 , pelo que eu posso ver, deve ser exit 1 .

  • A shebang pode conter set -e da seguinte forma:

    #!/bin/bash -e
    

Reescrito com base no acima:

#!/bin/bash -e

r2g()
{

    echo "executable name is: $0"

    r2g_internal "$@" 2> >( while read -r line; do echo "r2g error: $line"; done ) >( while read -r line; do echo "r2g: $line"; done )

    if [ $? -ne 0 ]
    then
        echo "something experienced an error, to see log, run: r2g_view_log"
        exit 1
    fi

}
    
por 09.05.2018 / 10:31
-1

Sem ofensa, mas você já tentou ler e entender a mensagem de erro:

syntax error near unexpected token '>'

Diz explicitamente que seu código contém erros óbvios: 2> >( . ' > ' é direcionar a saída padrão para o arquivo. Você está tentando direcionar a saída de r2g_internal para a leitura do script a partir da entrada padrão. Você deve usar ' | ' not '>'.

E mais um erro - você pode direcionar stdout e stderr para separar arquivos, mas não é possível direcioná-los facilmente a scripts separados. Você terá que escrevê-los primeiro em arquivos e processá-los separadamente.

r2g_internal "$@" 1> stdout.txt 2> stderr.txt
cat stderr.txt | ( while read line; do echo "r2g error: $line"; done )
cat stdout.txt | ( while read line; do echo "r2g: $line"; done )
    
por 09.05.2018 / 12:55