Come ha spiegato @dessert , il problema qui è che la tua sceneggiatura non ha una linea shebang . Senza shebang, sudo
per impostazione predefinita tenterà di eseguire il file utilizzando /bin/sh
. Non sono riuscito a trovarlo documentato da nessuna parte, ma ho confermato controllando il sudo
codice sorgente in cui ho trovato quanto segue nel file pathnames.h
:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
Questo significa "imposta se la variabile _PATH_BSHELL
non è definita, impostala su /bin/sh
". Quindi, nello configure
script incluso nel tarball sorgente, abbiamo:
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
Questo ciclo cercherà /bin/bash
, /usr/bin/sh
, /sbin/sh
, /usr/sbin/sh
o /bin/ksh
e quindi imposta la _PATH_BSHELL
a seconda di quale è stato trovato prima . Poiché è /bin/sh
stato il primo nell'elenco ed esiste, _PATH_BSHELL
è impostato su /bin/sh
. Il risultato di tutto ciò è che la shell predefinita è sudo
se non diversamente definito /bin/sh
.
Quindi, sudo
per impostazione predefinita , eseguirà le cose usando /bin/sh
e, su Ubuntu, che è un collegamento simbolico a dash
una shell minima compatibile con POSIX:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
Il [[
costrutto è una funzione bash, non è definito dallo standard POSIX e non è compreso da dash
:
$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found
Nel dettaglio, nelle tre invocazioni che hai provato:
./test.sh
No sudo
; in assenza di una riga shebang, la shell tenterà di eseguire il file stesso. Dal momento che stai funzionando bash
, questo funzionerà bash ./test.sh
e funzionerà efficacemente .
sudo su
seguito da ./test.sh
.
Qui, stai avviando una nuova shell per l'utente root
. Questo sarà qualunque shell definita nella $SHELL
variabile d'ambiente per quell'utente e, su Ubuntu, la shell predefinita di root è bash
:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
sudo ./test.sh
Qui, stai lasciando sudo
eseguire direttamente il comando. Poiché la sua shell predefinita è /bin/sh
come spiegato sopra, questo fa sì che esegua lo script /bin/sh
, che è dash
e non riesce poiché dash
non capisce [[
.
Nota : i dettagli di come sudo
imposta la shell predefinita sembrano essere un po 'più complessi. Ho provato a cambiare i file menzionati nella mia risposta per puntare a, /bin/bash
ma sudo
era ancora predefinito /bin/sh
. Quindi ci devono essere altri posti nel codice sorgente in cui è definita la shell predefinita. Tuttavia, il punto principale ( sudo
predefinito sh
) rimane valido.
sudo su
. Basta correresudo -i
osudo -s
invece.