Как объяснил @dessert , проблема в том, что в вашем скрипте нет строки Шебанга . Без шебанга по sudo
умолчанию будет пытаться запустить файл с помощью /bin/sh
. Я нигде не смог найти документально подтвержденный документ, но я подтвердил, проверив sudo
исходный код, где обнаружил в файле следующее pathnames.h
:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
Это означает «установить, если переменная _PATH_BSHELL
не определена, установить ее на /bin/sh
». Затем в configure
скрипте, включенном в исходный архив, мы имеем:
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
Этот цикл будет искать /bin/bash
, /usr/bin/sh
, /sbin/sh
, /usr/sbin/sh
или , /bin/ksh
а затем устанавливает _PATH_BSHELL
в какой был найден первый . Так как /bin/sh
был первым в списке и существует, _PATH_BSHELL
устанавливается в /bin/sh
. Результатом всего этого является то, что оболочкой по умолчанию, sudo
если не указано иное, является /bin/sh
.
Таким образом, по sudo
умолчанию будет запускаться что-то с использованием, /bin/sh
а в Ubuntu, которая является символической ссылкой dash
, на минимальную POSIX-совместимую оболочку:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
[[
Конструкция особенность Баш, оно не определено стандартом POSIX и не понимают dash
:
$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found
Подробно, в трех вызовах, которые вы пробовали:
./test.sh
Нет sudo
; в отсутствие строки shebang ваша оболочка попытается выполнить сам файл. Поскольку вы работаете bash
, это будет эффективно работать bash ./test.sh
и работать.
sudo su
с последующим ./test.sh
.
Здесь вы запускаете новую оболочку для пользователя root
. Это будет оболочка, определенная в $SHELL
переменной окружения для этого пользователя, а в Ubuntu оболочкой root по умолчанию является bash
:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
sudo ./test.sh
Здесь вы позволяете sudo
выполнить команду напрямую. Поскольку его оболочка по умолчанию такая же, /bin/sh
как объяснено выше, это заставляет его запускать сценарий /bin/sh
, который dash
не работает, поскольку dash
не понимает [[
.
Примечание : детали того, как sudo
устанавливает оболочку по умолчанию, кажутся немного более сложными. Я попытался изменить файлы, упомянутые в моем ответе, чтобы указать, /bin/bash
но sudo
все еще по умолчанию /bin/sh
. Поэтому в исходном коде должны быть другие места, где определена оболочка по умолчанию. Тем не менее, главное (что по sudo
умолчанию sh
) все еще остается в силе.
sudo su
. Просто бегиsudo -i
илиsudo -s
взамен.