Як пояснив @dessert , проблема тут полягає в тому, що у вашого сценарію немає рядка shebang . Без шебангу, 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
замість цього.