Как объяснил @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взамен.