Executar o script bash do curl falhou enquanto o arquivo foi bem-sucedido

2

Eu tenho um script install.sh essencialmente se parece com isto:

#!/bin/bash

if [[ ! -f "/usr/bin/jq" ]]; then
  apt-get update && apt-get install -y jq
fi

echo $(date) >> install.log

Se eu colocá-lo em um servidor e executá-lo assim:

curl -s0 https://myserver.com/install.sh | bash

após a saída apt-get do crazy, ela não executará a última linha echo , em vez disso, ela imprimirá a linha echo $(date) >> test.log como saída. Enquanto se eu salvar o install.sh no disco e executar ./install.sh , ele será executado conforme o esperado. a linha de eco é executada e o install.log é anexado.

Para continuar reproduzindo esse problema, eu o executo localmente assim:

cat install.sh | bash

também tem o mesmo problema.

Eu corro apt-get remove jq manualmente antes de cada teste. Se jq estiver instalado, ambos funcionarão conforme o esperado. Então, por que é diferente de executá-lo a partir do download vs. executá-lo a partir do arquivo local?

Gravei um pequeno vídeo para demonstrar esse problema: link

    
por Elgs Qian Chen 03.12.2015 / 11:23

1 resposta

1

Geralmente bash não se importa se está lendo seus comandos de um arquivo (como em bash foo ) ou de STDIN (como em bash <foo ). No entanto, agora você inicia um comando ( apt-get ) que por si só quer perguntar ao usuário e usa, sim, STDIN para fazer isso.

Portanto, coisas estranhas acontecem: o bash lê os comandos do STDIN e os executa um por um. Agora, um dos comandos lê a partir de STDIN e, bem, lê a próxima linha do arquivo. Depois, o bash lê a próxima linha do STDIN e, portanto, pula o comando já lido pelo outro comando.

Este pequeno script demonstrará o que está acontecendo:

echo "hello"
read -p "how do you do? "
echo "I understand"
echo "you are '$REPLY'."
echo "bye"

Salve-o em um arquivo e execute-o primeiro como bash -x foo e depois como bash -x <foo .

A mesma coisa acontecerá no seu exemplo.

Uma solução seria usar a substituição de processos:

bash -x <(cat foo)

ou, no seu caso, simplesmente:

bash <(curl -s0 https://myserver.com/install.sh)

Algumas observações:

Sempre que algum script de shell faz coisas estranhas, use bash -x para ver o que está acontecendo.

Escrever cat foo| ... é conhecido como Uso inútil do gato . Apenas use o redirecionamento.

    
por 03.12.2015 / 21:58

Tags