Như @dPlay đã giải thích , vấn đề ở đây là tập lệnh của bạn không có dòng shebang . Nếu không có shebang, sudo
sẽ mặc định chạy tệp bằng cách sử dụng /bin/sh
. Tôi không thể tìm thấy tài liệu ở bất cứ đâu, nhưng tôi đã xác nhận bằng cách kiểm tra sudo
mã nguồn nơi tôi tìm thấy sau đây trong tệp pathnames.h
:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
Điều này có nghĩa là "đặt nếu biến _PATH_BSHELL
không được xác định, đặt thành /bin/sh
". Sau đó, trong configure
tập lệnh có trong tarball nguồn, chúng ta có:
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
Vòng lặp này sẽ tìm kiếm /bin/bash
, /usr/bin/sh
, /sbin/sh
, /usr/sbin/sh
hay /bin/ksh
và sau đó thiết lập _PATH_BSHELL
để bất cứ đã được tìm thấy đầu tiên . Vì /bin/sh
là cái đầu tiên trong danh sách và nó tồn tại, _PATH_BSHELL
được đặt thành /bin/sh
. Kết quả của tất cả điều này là lớp vỏ mặc định sudo
trừ khi có quy định khác /bin/sh
.
Vì vậy, sudo
sẽ mặc định chạy mọi thứ bằng cách sử dụng /bin/sh
và trên Ubuntu, đó là một liên kết tượng trưng đến dash
, trình bao tương thích POSIX tối thiểu:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
Cấu [[
trúc là một tính năng bash, nó không được xác định bởi tiêu chuẩn POSIX và không được hiểu bởi dash
:
$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found
Cụ thể, trong ba lời mời bạn đã thử:
./test.sh
Không sudo
; trong trường hợp không có dòng shebang, shell của bạn sẽ cố gắng tự thực thi tệp. Vì bạn đang chạy bash
, điều này sẽ chạy bash ./test.sh
và làm việc hiệu quả .
sudo su
theo sau ./test.sh
.
Tại đây, bạn đang bắt đầu một trình bao mới cho người dùng root
. Đây sẽ là bất kỳ shell nào được xác định trong $SHELL
biến môi trường cho người dùng đó và trên Ubuntu, shell mặc định của root là bash
:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
sudo ./test.sh
Ở đây, bạn đang cho phép sudo
thực hiện lệnh trực tiếp. Vì lớp vỏ mặc định của nó /bin/sh
như được giải thích ở trên, điều này khiến nó chạy tập lệnh với /bin/sh
, dash
và nó không thành công do dash
không hiểu [[
.
Lưu ý : các chi tiết về cách sudo
đặt shell mặc định có vẻ phức tạp hơn một chút. Tôi đã thử thay đổi các tệp được đề cập trong câu trả lời của mình để trỏ đến /bin/bash
nhưng sudo
vẫn được mặc định /bin/sh
. Vì vậy, phải có một số vị trí khác trong mã nguồn nơi vỏ mặc định được xác định. Tuy nhiên, điểm chính ( sudo
mặc định là sh
) vẫn đứng.
sudo su
. Chỉ cần chạysudo -i
hoặcsudo -s
thay vào đó.