วิธีการแก้“ ปฏิเสธสิทธิ์” เมื่อใช้ sudo ด้วยการเปลี่ยนเส้นทางใน Bash


137

เมื่อใช้ sudo เพื่ออนุญาตให้แก้ไขไฟล์ฉันได้รับ 'สิทธิ์ถูกปฏิเสธ' เป็นประจำ

ตัวอย่างเช่นเมาส์ของฉันสั่นเทาและซบเซาดังนั้นฉันต้องการปิดการใช้งานการลงคะแนน:

sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf

ฉันขอรหัสผ่านจากนั้นรับ:

bash: /etc/modprobe.d/local.conf: Permission denied

ดังนั้นฉันจึงพยายามเปลี่ยนแปลงชั่วคราวเพื่อปิดใช้งานการลงคะแนนเลือกตั้งโดยใช้:

sudo echo N> /sys/module/drm_kms_helper/parameters/poll

แต่ระบบตอบกลับด้วย:

bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied

ความคิดใด ๆ

คำตอบ:


156

การเปลี่ยนเส้นทางขาออก (ผ่าน>ผู้ประกอบการ) จะกระทำโดยเปลือกไม่ได้โดยก้อง คุณต้องเข้าสู่ระบบในฐานะ root

sudo -i

จากนั้นคุณสามารถใช้การเปลี่ยนเส้นทาง

echo N> /sys/module/drm_kms_helper/parameters/poll

มิฉะนั้นคุณสามารถเรียกใช้ bash string ด้วย sudo

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"

1
คุณไม่สามารถรันเสียงสะท้อนด้วย sudo ได้ไหม? สิ่งที่เกี่ยวกับผลลัพธ์ที่ฉันได้รับ:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89

คุณสามารถเขียนลงไฟล์ echo "some" "mallhre มันกำลังใช้ท่อ .. นั่นคือปัญหา
shantanu

4
ตกลงถ้าเป็นกรณีนั้นโปรดอัปเดตคำตอบของคุณเพื่อสะท้อนว่าการรันเสียงสะท้อนนั้นเป็นปัญหาในกรณีนั้นเท่านั้น
saji89

คุณไม่สามารถเรียกใช้เชลล์บิวด์อินechoอย่าง sudo ได้เว้นแต่คุณจะทำสิ่งใดสิ่งหนึ่งเช่นsudo bash -c 'echo …'; อย่างไรก็ตามระบบ POSIX มักจะให้echoคำสั่งจากภายนอกเช่น/bin/echoบน OS X ซึ่ง sudo สามารถดำเนินการได้โดยไม่ต้องใช้ rigamarole ดังนั้นechoคำสั่งที่คุณมักจะเรียกใช้และechoคำสั่งที่คุณรันด้วย sudo อาจเป็นสองคำสั่งที่แตกต่างกัน แต่คล้ายกัน
kojiro

หากเป็นเช่นนั้นเหตุใดคำตอบของคำถามนี้จึงแนะนำให้สะท้อนเสียง askubuntu.com/questions/840431/…
Harsha

75

เปลี่ยนเส้นทางการส่งออกจะกระทำโดยเปลือกจากการที่คำสั่งที่ได้รับการเรียก ดังนั้นแบ่งทุกอย่างออกเป็นชิ้น ๆ นี่คือสิ่งที่เกิดขึ้น *:

  • เชลล์เรียกใช้sudo echo "options drm_kms_helper poll=N"ซึ่งรันsudoคำสั่งด้วยecho "options drm_kms_helper poll=N"บรรทัดรับคำสั่ง

  • sudo ขอรหัสผ่านเปิดเชลล์ superuser และเรียกใช้echo "options drm_kms_helper poll=N"ซึ่งเรียกใช้echoคำสั่งผ่านมัน"options drm_kms_helper poll=N"

  • echo รันด้วยrootสิทธิพิเศษพิมพ์สตริงไปยังเอาต์พุตมาตรฐาน

  • echoคำสั่งสิ้นสุด, superuser shell exits, sudoterminates

  • เชลล์ที่คำสั่งถูกเรียกใช้รวบรวมเอาต์พุตและพยายามเปลี่ยนทิศทางไป/etc/modprobe.d/local.confที่ซึ่งสามารถเขียนได้โดย root เท่านั้น ได้รับข้อผิดพลาด "สิทธิ์ถูกปฏิเสธ"

สำหรับวิธีแก้ไขนี้ให้ดูที่ @shantanu answer


(*) - ในขณะที่ลำดับข้างต้นช่วยให้เข้าใจว่าทำไมคำสั่งล้มเหลวในความเป็นจริงสิ่งที่เกิดขึ้นค่อนข้างออกคำสั่ง: เปลือกเดิมสังเกตเห็นการเปลี่ยนเส้นทางและพยายามที่จะเปิดไฟล์สำหรับการเขียนก่อนที่จะเรียกsudo ...คำสั่ง เมื่อเปิดไฟล์ล้มเหลวเชลล์ไม่ได้เรียกใช้คำสั่งที่ควรจะเขียนไปยังไฟล์ (ขอบคุณ @PanosRontogiannis เพื่อชี้ให้เห็นสิ่งนี้)

นี่คือการทดสอบอย่างรวดเร็ว:

$ touch ./onlyroot.txt
$ sudo chown root:root ./onlyroot.txt
$ sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied

ในการทดสอบด้านบนwhoami | tee who.txtกำลังจะสร้างไฟล์ชื่อwho.txtที่มีคำว่า "root" อย่างไรก็ตามเมื่อการเปลี่ยนเส้นทางเอาต์พุตล้มเหลวในเชลล์การเรียกไฟล์ "who.txt" ก็หายไปเช่นกันเพราะคำสั่งไม่ได้ถูกเรียกใช้


มีโอกาสมากขึ้นที่เชลล์ 'ส้อม' ตัวเองและพยายามที่จะเปิด /etc/modprobe.d/local.conf ก่อนที่จะพยายาม 'exec' sudo ซึ่งหมายความว่า 4 ขั้นตอนแรกที่คุณอธิบายไม่เคยเกิดขึ้นจริงเพราะไฟล์ไม่สามารถเปิดได้
Panos Rontogiannis

1
@PanosRontogiannis: ขอบคุณฉันได้อัปเดตคำตอบแล้ว
Sergey

60

การเพิ่มคำตอบของ Shantanu:

... หรือคุณสามารถใช้teeคำสั่งเช่นนี้:

sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10

หรือถ้ามันออกคำสั่ง:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll

3
1 ในการเข้าสู่ระบบเป็นรากเป็นความคิดที่ดีสำหรับการทำงานด้วยตนเองและจริงๆความคิดที่ดีสำหรับงานสคริปต์
l0b0

2
นอกจากนี้sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nullหากคุณไม่ต้องการให้พิมพ์stdoutด้วย
Fabian Tamp

16

วิธีที่ฉันไม่ได้เห็นในที่นี้คือการเรียกใช้ commandline ทั้งหมดในเชลล์ของมันเอง sudomanpage ตัวเองให้เห็นตัวอย่างของวิธีการนี้:

เพื่อให้รายการการใช้งานของไดเรกทอรีใน / พาร์ทิชันที่บ้าน โปรดทราบว่าสิ่งนี้จะรันคำสั่งใน sub-shell เพื่อให้ cd และ file redirection ทำงาน

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"

ว้าวขอบคุณ. วิธีง่ายๆ
ความยืดหยุ่น

4

ตัวเลือกอื่นคือใช้ไฟล์ชั่วคราว สิ่งนี้มีประโยชน์ในสคริปต์ทุบตี

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever

3

sudo dd of=

หากต้องการผนวกตามที่คุณต้องการ:

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc

หรือเพื่อสร้างไฟล์ใหม่ตั้งแต่ต้น:

echo inbytes | sudo dd of=outfile

ข้อดี:

  • ดีกว่าteeเนื่องจากไม่มีการ/dev/nullเปลี่ยนเส้นทาง
  • ดีกว่าshเนื่องจากไม่มี subshell ที่ชัดเจน (แต่อันที่หนึ่งสำหรับการเปลี่ยนเส้นทาง)
  • ddมีตัวเลือกที่ทรงพลังมากมายเช่นstatus=progressเพื่อดูความคืบหน้าของการถ่ายโอน

ทำงานได้เพราะ sudo ส่งต่อ stdin ไปยังคำสั่ง


1
ดีจัง. เราคิดว่าddเป็นวิธีการที่เราเขียนทับระบบไฟล์ที่ยิ่งใหญ่ครั้งหนึ่งของเราและไม่ได้ตระหนักถึงมันสำหรับงานทางโลกเช่นกัน - และคำสั่งอื่น ๆ ในฐานะที่เป็นรูทก็เป็นอันตรายเช่นกันหากใช้กับไฟล์ / อุปกรณ์ผิด ชอบsudo tee , sudo ddของหลักสูตรจะยังทำงานร่วมกับที่นี่สตริงsudo dd of=outfile <<<'hello world'เช่น [ขอบคุณสำหรับการแก้ไข NB ด้วยsh -c 'cmd', shเป็น subprocess ที่เป็น shell, แต่ไม่ใช่ subshell จริงๆยกเว้นในกรณีที่คำสั่งภายนอกทั้งหมดเริ่มต้นเป็นหนึ่งเดียว]
Eliah Kagan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.