Como o @dessert explicou , o problema aqui é que seu script não tem uma linha shebang . Sem um shebang, sudoo padrão é tentar executar o arquivo usando /bin/sh. Não consegui encontrá-lo documentado em nenhum lugar, mas confirmei verificando o sudocódigo-fonte onde 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_BSHELLnão estiver definida, defina-a como /bin/sh". Então, no configurescript 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
Este circuito irá procurar /bin/bash, /usr/bin/sh, /sbin/sh, /usr/sbin/shou /bin/kshe, em seguida, define o _PATH_BSHELLque o que foi encontrado pela primeira vez . Como /bin/shfoi o primeiro na lista e existe, _PATH_BSHELLestá definido como /bin/sh. O resultado de tudo isso é que o shell padrão, a sudomenos que seja definido de outra forma, é /bin/sh.
Portanto, sudoo padrão será executar as coisas usando /bin/she, no Ubuntu, que é um link simbólico para dash, um mínimo de shell compatível com POSIX:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
A [[construção é um recurso bash, não é definido pelo padrão POSIX e não é entendido 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
Não sudo; na ausência de uma linha shebang, seu shell tentará executar o próprio arquivo. Como você está executando bash, isso funcionará bash ./test.she funcionará efetivamente .
sudo suseguido por ./test.sh.
Aqui, você está iniciando um novo shell para o usuário root. Este será o shell definido na $SHELLvariável de ambiente 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á deixando sudoexecutar o comando diretamente. Como seu shell padrão é /bin/shcomo explicado acima, isso faz com que ele execute o script /bin/sh, o que é dashe falha desde que dashele não entende [[.
Nota : os detalhes de como sudodefine o shell padrão parecem um pouco mais complexos. Tentei alterar os arquivos mencionados na minha resposta para apontar para, /bin/bashmas sudoainda era o padrão /bin/sh. Portanto, deve haver outros lugares no código-fonte em que o shell padrão está definido. No entanto, o ponto principal (que o sudopadrão é sh) ainda permanece.
sudo su. Basta executarsudo -iou emsudo -svez disso.