Como explicó @dessert , el problema aquí es que su script no tiene una línea shebang . Sin un shebang, por sudo
defecto intentará ejecutar el archivo usando /bin/sh
. No pude encontrarlo documentado en ninguna parte, pero lo confirme comprobando el sudo
código fuente donde encontré lo siguiente en el archivo pathnames.h
:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
Esto significa "establecer si la variable _PATH_BSHELL
no está definida, establecerla en /bin/sh
". Luego, en el configure
script incluido en el tarball fuente, tenemos:
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 bucle buscará /bin/bash
, /usr/bin/sh
, /sbin/sh
, /usr/sbin/sh
o /bin/ksh
y selecciona el _PATH_BSHELL
que lo que se encontró por primera vez . Dado que /bin/sh
fue el primero en la lista y existe, _PATH_BSHELL
se establece en /bin/sh
. El resultado de todo esto es que el shell predeterminado de a sudo
menos que se defina lo contrario es /bin/sh
.
Por lo tanto, sudo
se ejecutará de manera predeterminada las cosas usando /bin/sh
y, en Ubuntu, que es un enlace simbólico a dash
un shell compatible con POSIX mínimo:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
La [[
construcción es una característica bash, no está definida por el estándar POSIX y no se entiende por dash
:
$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found
En detalle, en las tres invocaciones que probaste:
./test.sh
No sudo
; en ausencia de una línea shebang, su shell intentará ejecutar el archivo en sí. Como está ejecutando bash
, esto funcionará bash ./test.sh
y funcionará de manera efectiva .
sudo su
seguido de ./test.sh
.
Aquí, está comenzando un nuevo shell para el usuario root
. Esto será cualquier shell definido en la $SHELL
variable de entorno para ese usuario y, en Ubuntu, el shell predeterminado de root es bash
:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
sudo ./test.sh
Aquí, está permitiendo sudo
ejecutar el comando directamente. Dado que su shell predeterminado es /bin/sh
como se explicó anteriormente, esto hace que ejecute el script con /bin/sh
, que es dash
y falla, ya dash
que no comprende [[
.
Nota : los detalles de cómo sudo
establece el shell predeterminado parecen ser un poco más complejos. Traté de cambiar los archivos mencionados en mi respuesta para señalar /bin/bash
pero sudo
todavía estaba predeterminado /bin/sh
. Por lo tanto, debe haber otros lugares en el código fuente donde se define el shell predeterminado. Sin embargo, el punto principal (que por sudo
defecto es sh
) sigue en pie.
sudo su
. Solo corresudo -i
o en susudo -s
lugar.