ไม่พบคำสั่งเมื่อใช้ sudo


146

ฉันมีสคริปต์ที่เรียกว่าfoo.shในโฟลเดอร์บ้านของฉัน

เมื่อฉันนำทางไปยังโฟลเดอร์นี้และป้อน./foo.shฉันจะได้รับ

-bash: ./foo.sh: Permission denied.

เมื่อฉันใช้sudo ./foo.shฉันได้รับ

sudo: foo.sh: command not found.

เหตุใดสิ่งนี้จึงเกิดขึ้นและฉันจะแก้ไขได้อย่างไร

คำตอบ:


151

ปฏิเสธการอนุญาต

ในการเรียกใช้สคริปต์ไฟล์จะต้องมีชุดบิตสิทธิ์การใช้งาน

เพื่อให้เข้าใจถึงการอนุญาตของไฟล์ Linux อย่างสมบูรณ์คุณสามารถศึกษาเอกสารสำหรับchmodคำสั่ง chmodคำย่อของโหมดการเปลี่ยนแปลงเป็นคำสั่งที่ใช้ในการเปลี่ยนการตั้งค่าการอนุญาตของไฟล์

หากต้องการอ่านเอกสาร chmod สำหรับระบบโลคัลของคุณให้รันman chmodหรือinfo chmodจากบรรทัดรับคำสั่ง เมื่ออ่านและเข้าใจแล้วคุณควรจะสามารถเข้าใจผลลัพธ์ของการรัน ...

ls -l foo.sh

... ซึ่งจะแสดงรายการสิทธิ์ในการอ่านเขียนและดำเนินการสำหรับเจ้าของไฟล์เจ้าของกลุ่มและคนอื่น ๆ ที่ไม่ใช่เจ้าของไฟล์หรือสมาชิกของกลุ่มที่ไฟล์นั้นอยู่ (บางครั้งกลุ่มสิทธิ์สุดท้ายจะถูกอ้างถึง เป็น "โลก" หรือ "อื่น ๆ ")

นี่คือบทสรุปของวิธีการแก้ไขข้อผิดพลาดการอนุญาตที่ถูกปฏิเสธในกรณีของคุณ

$ ls -l foo.sh                    # Check file permissions of foo
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.sh 
    ^^^ 
 ^^^ | ^^^   ^^^^^^^ ^^^^^
  |  |  |       |       | 
Owner| World    |       |
     |          |    Name of
   Group        |     Group
             Name of 
              Owner 

เจ้าของได้อ่านและเขียนการเข้าถึง rw แล้ว แต่ - บ่งชี้ว่าสิทธิ์การใช้งานจะหายไป

chmodแก้ไขคำสั่งที่ (กลุ่มและอื่น ๆ มีสิทธิ์อ่านตั้งไว้บนไฟล์เท่านั้นพวกเขาไม่สามารถเขียนหรือเรียกใช้งานได้)

$ chmod +x foo.sh               # The owner can set the executable permission on foo.sh
$ ls -l foo.sh                  # Now we see an x after the rw 
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.sh
   ^  ^  ^

foo.sh สามารถทำงานได้เท่าที่ Linux เกี่ยวข้อง

การใช้ผลลัพธ์ sudo ในไม่พบคำสั่ง

เมื่อคุณรันคำสั่งโดยใช้sudoคุณจะรันมันอย่างมีประสิทธิภาพในฐานะ superuser หรือ root

เหตุผลที่ผู้ใช้รากจะไม่พบคำสั่งของคุณเป็นไปได้ว่าPATHตัวแปรสภาพแวดล้อมสำหรับรากไม่รวมไดเรกทอรีที่foo.shตั้งอยู่ ดังนั้นจึงไม่พบคำสั่ง

ตัวแปรสภาพแวดล้อม PATH มีรายการไดเรกทอรีที่จะค้นหาคำสั่ง ผู้ใช้แต่ละคนตั้งค่าตัวแปร PATH ของตนเองตามความต้องการ เพื่อดูว่ามันถูกตั้งค่าให้ทำงาน

env | grep ^PATH

นี่คือตัวอย่างบางส่วนของการรันenvคำสั่งด้านบนก่อนเป็นผู้ใช้ธรรมดาและจากนั้นในฐานะผู้ใช้รูทที่ใช้ sudo

rkielty@rkielty-laptop:~$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

rkielty@rkielty-laptop:~$ sudo env | grep ^PATH
[sudo] password for rkielty: 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin

หมายเหตุว่าแม้ว่าที่คล้ายกันในกรณีนี้ไดเรกทอรีที่มีอยู่ในเส้นทางของผู้ใช้ที่ไม่ได้รับการยกเว้น (rkielty) และผู้ใช้ super จะไม่เหมือนกัน

ไดเร็กทอรีที่foo.shไม่มีอยู่ในตัวแปร PATH ของผู้ใช้รูทดังนั้นคำสั่งไม่พบข้อผิดพลาด


1
@Nakilon หากคุณใส่คำถามที่มีรายละเอียดครบถ้วนฉันควรจะแก้ไขปัญหาให้คุณต่อไป ปัญหาน่าจะเกิดขึ้นซึ่งเชลล์ (เชลล์คำสั่งแรกของคุณหรือเชลล์ที่เปิดตัวโดย sudo) ได้ประเมิน $ PWD
Rob Kielty

6
@ Rob: ดังนั้นวิธีที่จะทำให้sudoเป็นPATHเช่นเดียวกับผู้ใช้?
Tom

1
@Rob: ฉันได้พบวิธีในระหว่างนี้ (ดูคำตอบของฉันด้านล่าง)
ทอม

1
ฉันชอบวิธีที่คุณอธิบาย! ขอบคุณ :)
Kasparov92

1
@Tom คุณสามารถเปลี่ยน secure_path ใน / etc / sudoers ได้
DennisLi

98

โซลูชันอื่น ๆ ที่ฉันเคยเห็นที่นี่จนถึงตอนนี้มีพื้นฐานมาจากคำจำกัดความของระบบบางอย่าง แต่ในความเป็นจริงเป็นไปได้ที่จะsudoใช้ปัจจุบันPATH(พร้อมenvคำสั่ง) และ / หรือส่วนที่เหลือของสภาพแวดล้อม (พร้อม-Eตัวเลือก) เพียงแค่เรียกใช้ :

sudo -E env "PATH=$PATH" <command> [arguments]

ในความเป็นจริงเราสามารถสร้างนามแฝงได้จาก:

alias mysudo='sudo -E env "PATH=$PATH"'

(อาจเป็นไปได้ที่จะตั้งชื่อนามแฝงเองsudoโดยแทนที่ชื่อเดิมsudo)


3
ฉันชอบโซลูชันนี้ทอมเพราะคุณทำงานอย่างมีสติกับคำร้องขอ sudo แบบอื่น สิ่งสำคัญคือต้องคำนึงถึงตัวแปร PATH ที่ใช้อยู่ตลอดเวลาไม่ว่าจะด้วยวิธีใด (และมีจำนวนมาก) ที่ตั้งค่าไว้
Rob Kielty

4
ฉันเชื่อว่านี่เป็นทางออกที่ถูกต้องและเป็นมาตรฐานมากที่สุดสำหรับcommand not foundปัญหาที่พบใน Ubuntu distro ขอบคุณชาย
Omar Tariq

คุณสามารถเพิ่มนามแฝงของคุณ./bashrcเพื่อบันทึกระหว่างเซสชัน
จอร์จ

19

ตรวจสอบsecure_pathบน sudo

[root@host ~]# sudo -V | grep 'Value to override'
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin

หาก$PATHมีการใช้แทนที่visudoและแก้ไข/etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

ขอบคุณ! นั่นช่วยในการไขปริศนาของ sudo ที่ไม่สามารถรันคำสั่งได้
Evgeny Goldin

7
  1. ตรวจสอบว่าคุณได้รับอนุญาตให้ใช้สคริปต์ กล่าวคือchmod +x foo.sh
  2. ตรวจสอบว่าบรรทัดแรกของสคริปต์นั้นเป็น#!/bin/shบางอย่าง
  3. สำหรับ sudo คุณอยู่ในไดเรกทอรีที่ไม่ถูกต้อง ตรวจสอบกับsudo pwd

5

คุณยังสามารถสร้างซอฟต์ลิงค์ไปยังสคริปต์ของคุณในหนึ่งในไดเรกทอรี ( /usr/local/binตัวอย่าง) ในพา ธ ของผู้ใช้ขั้นสูง จากนั้นจะสามารถใช้งานได้กับ sudo

chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo

ลองดูที่คำตอบนี้เพื่อให้ได้แนวคิดว่าจะใส่ไดเร็กตอรี่ใด


2

ดูเหมือนว่า linux จะพูดว่า "ไม่พบคำสั่ง" แม้ว่าคุณจะให้เส้นทางไปยังไฟล์อย่างชัดเจนก็ตาม

[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
sudo: /tmp/uid.sh: command not found
1
[veeam@jsandbox ~]$ chmod +x /tmp/uid.sh
[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
0

มันเป็นข้อผิดพลาดที่ทำให้เข้าใจผิดบ้าง แต่ก็อาจถูกต้องทางเทคนิค ไฟล์ไม่ใช่คำสั่งจนกว่าจะสามารถเรียกใช้งานได้และไม่สามารถพบได้


1

ตกลงนี่คือโซลูชันของฉัน: ใน ~ / .bash_aliases เพียงเพิ่มสิ่งต่อไปนี้:

# ADDS MY PATH WHEN SET AS ROOT
if [ $(id -u) = "0" ]; then
   export PATH=$PATH:/home/your_user/bin 
fi

Voila! ตอนนี้คุณสามารถรันสคริปต์ของคุณเองด้วย sudo หรือตั้งเป็น ROOT โดยไม่ต้องทำการส่งออก PATH = $ PATH: / home / your_user / bin ทุกครั้ง

โปรดสังเกตว่าฉันต้องมีความชัดเจนเมื่อเพิ่ม PATH ของฉันเนื่องจาก HOME สำหรับ superuser คือ / root



1

มีคำตอบที่ดีเลิศข้างต้น หากหลังจากลองแล้วคุณยังคงcommand not foundลองเส้นทางไฟล์ทั้งหมดอีกครั้ง:

sudo /home/user/path/to/foo.sh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.