Como @dessert explicou , o problema aqui é que o seu script não tem um linha shebang . Sem um shebang, sudo
será o padrão para tentar executar o arquivo usando /bin/sh
. Não consegui encontrá-lo documentado em nenhum lugar, mas confirmei verificando o código-fonte sudo
, no qual encontrei o seguinte no arquivo pathnames.h
:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
Isso significa "definir se a variável _PATH_BSHELL
não estiver definida, defina como /bin/sh
". Em seguida, no script configure
incluído no tarball de origem, temos:
for p in "/bin/bash" "/usr/bin/sh" "/sbin/sh" "/usr/sbin/sh" "/bin/ksh" "/usr/bin/ksh" "/bin/bash" "/usr/bin/bash"; do
if test -f "$p"; then
found=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $p" >&5
$as_echo "$p" >&6; }
cat >>confdefs.h <<EOF
#define _PATH_BSHELL "$p"
EOF
break
fi
done
Esse loop procurará /bin/bash
, /usr/bin/sh
, /sbin/sh
, /usr/sbin/sh
ou /bin/ksh
e, em seguida, definirá a _PATH_BSHELL
para o que tiver sido encontrado primeiro . Como /bin/sh
foi o primeiro da lista e existe, _PATH_BSHELL
está definido como /bin/sh
. O resultado de tudo isso é que o shell padrão de sudo
, a menos que seja definido de outra forma, é /bin/sh
.
Portanto, sudo
será o padrão para executar as coisas usando /bin/sh
e, no Ubuntu, é um link simbólico para dash
, um shell compatível com POSIX mínimo:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
A construção [[
é um recurso bash, não é definida pelo padrão POSIX e não é entendida por dash
:
$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found
Em detalhes, nas três invocações que você tentou:
-
./test.sh
Sem sudo
; na ausência de uma linha shebang, seu shell tentará executar o arquivo em si. Como você está executando bash
, isso irá executar bash ./test.sh
e funcionar.
-
sudo su
seguido por ./test.sh
.
Aqui, você está iniciando um novo shell para o usuário root
. Este será qualquer shell definido na variável de ambiente $SHELL
para esse usuário e, no Ubuntu, o shell padrão do root é bash
:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
-
sudo ./test.sh
Aqui, você está permitindo que sudo
execute o comando diretamente. Como o shell padrão é /bin/sh
, conforme explicado acima, isso faz com que ele execute o script com /bin/sh
, que é dash
e falha, pois dash
não entende [[
.
Nota : os detalhes de como sudo
define o shell padrão parecem ser um pouco mais complexos. Tentei alterar os arquivos mencionados na minha resposta para apontar para /bin/bash
, mas sudo
ainda estava sendo padronizado para /bin/sh
. Portanto, deve haver alguns outros locais no código-fonte em que o shell padrão está definido. No entanto, o ponto principal (que sudo
padroniza para sh
) ainda permanece.