Script Bash não funciona com 'sh'

3

Estou testando um script simples e estou me perguntando por que ele funciona bem quando executado no diretório: ./test.sh , mas quando eu tento com o comando "sh" sh test.sh não está funcionando:

test.sh: 3: test.sh: [[: not found
test.sh: 7: test.sh: [[: not found

Script:

#!/usr/bin/env bash

if [[ $1 = one ]]
        then
        printf "%b" "two\n" >&2
        exit 0
elif [[ $1 = two ]]
then
        printf "%b" "one\n" >&2
        exit 0
else
        printf "%b" "Specify argument: one/two\n"
        exit 1
fi
    
por HTF 21.06.2012 / 23:58

2 respostas

15

Resumo

sh é um programa diferente de bash .

Detalhe

O problema é que o shell Bourne ( sh ) não é o shell Bourne Again ( bash ). Ou seja, sh não entende o [[ pragma. Na verdade, ele não entende [ também. [ é um programa real ou link para / bin / test (ou / usr / bin / [ / usr / bin / test).

$ which [
/bin/[
$ ls -lh /bin/[
-r-xr-xr-x  2 root  wheel    42K Feb 29 17:11 /bin/[

Quando você executa seu script diretamente através de ./test.sh , você está chamando o script como o primeiro argumento para o programa especificado na primeira linha. Neste caso:

#!/usr/bin/env bash

Frequentemente, isso é diretamente o intérprete ( /bin/bash , ou qualquer outro número de outros interpretadores de script), mas no seu caso você está usando env para executar um programa em um ambiente modificado - mas esse argumento segue ainda é bash . Efetivamente, ./test.sh é bash test.sh .

Como sh e bash são shells diferentes com diferentes interpretações de sintaxe, você está vendo esse erro. Se você executar bash test.sh , deverá ver o que é esperado.

Mais informações

Outros apontaram nos comentários que /bin/sh pode ser um link ou outro shell. Historicamente, sh era o shell Bourne no antigo AT & T Unix e, na minha opinião, a descendência canônica. No entanto, isso é diferente nas variações do BSD e divergiu em outros sistemas baseados em Unix e distribuições ao longo do tempo. Se você estiver realmente interessado no funcionamento interno (incluindo como / bin / sh e / bin / bash podem ser o mesmo programa e se comportar de forma totalmente diferente), leia o seguinte:

SuperUser: Qual é a diferença entre bash e sh

Wikipedia: shell Bourne

    
por 22.06.2012 / 00:07
3

Como observado: / bin / sh normalmente (embora nem sempre) invoca um shell Bourne compatível com POSIX. Bash não é Bourne.

O Bash tentará emular Bourne quando invocado como 'sh' (como quando links simbólicos / bin / sh para / bin / bash), ou se $ POSIXLY_CORRECT for definido no ambiente de chamada, quando invocado com o --posix opção de invocação, ou quando 'set -o posix' foi executado. Isso permite testar um script / comando de shell Bourne para conformidade com POSIX.

Como alternativa, chame scripts / comandos de teste com um shell compatível com POSIX. 'dash' está próximo, o shell Korn (ksh) IIRC também oferece uma opção compatível com POSIX.

    
por 22.06.2012 / 00:57