ในฐานะที่เป็น@dessert อธิบายปัญหาที่นี่เป็นที่สคริปต์ของคุณไม่ได้มีสาย shebang โดยไม่ต้อง shebang ที่จะเริ่มต้นกับความพยายามที่จะเรียกใช้ไฟล์โดยใช้sudo /bin/shฉันไม่พบเอกสารใด ๆ เลย แต่ฉันยืนยันด้วยการตรวจสอบsudoซอร์สโค้ดที่ฉันพบสิ่งต่อไปนี้ในไฟล์pathnames.h:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
ซึ่งหมายความว่า "ตั้งค่าหาก_PATH_BSHELLไม่ได้กำหนดตัวแปรตั้งเป็น/bin/sh" จากนั้นในconfigureสคริปต์ที่รวมอยู่ใน tarball แหล่งที่มาเรามี:
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 นั่นคือ symlink 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 เชลล์เริ่มต้นของรูทคือ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แทน