ฉันจะรันคำสั่ง 'sudo' ภายในสคริปต์ได้อย่างไร


84

หากต้องการแก้ไขด้วยตนเองฉันต้องพิมพ์คำสั่งนี้

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

มีที่ว่างก่อน 09:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql

ฉันจะเรียกใช้สิ่งนี้ภายในสคริปต์ได้อย่างไร

นอกจากนี้ยังมีคำสั่งอื่น ๆ อีกมากมาย แต่อันนี้ทำให้เกิดปัญหา


2
แค่ใส่ไว้ในสคริปต์ปัญหาคืออะไร?
Lie Ryan

6
@LieRyan - sudo รหัสผ่าน - สคริปต์จะไม่สามารถทำงานได้อย่างสมบูรณ์หากมีคนไม่ได้อยู่ที่นั่น
Wilf

ระบบของฉันทำงานได้ดีโดยไม่ต้องแจ้งให้ทราบ Ubuntu 16.04 ในเดือนตุลาคม 2017 คุณทำให้sudoersการตั้งค่าของคุณยุ่งเหยิง ไม่ใช่เรื่องใหญ่. มันแค่ต้องการการแก้ไข
SDsolar

1
@SDsolar ระบบของคุณคือสิ่งที่สับสน เป็นช่องโหว่ด้านความปลอดภัยเล็กน้อยที่จะไม่แจ้งรหัสผ่าน (ทำให้ผู้ใช้มีความเสี่ยงต่อการถูกโจมตีจากวิศวกรรมสังคมบางประเภท)
wizzwizz4

คำตอบ:


107

เป็นความคิดที่ดีที่จะมีsudoสคริปต์ภายใน ให้ลบsudoสคริปต์ออกและเรียกใช้สคริปต์ด้วยsudo:

sudo myscript.sh

ด้วยวิธีนี้คำสั่งทั้งหมดภายในสคริปต์จะทำงานด้วยสิทธิ์พิเศษของรูทและคุณจะต้องให้รหัสผ่านเพียงครั้งเดียวเมื่อเปิดใช้งานสคริปต์ หากคุณต้องการคำสั่งเฉพาะภายในสคริปต์เพื่อให้ทำงานโดยไม่มีsudoสิทธิ์คุณสามารถเรียกใช้ในฐานะผู้ใช้ปกติด้วย (ขอบคุณLie Ryan ):

sudo -u username command 

พื้นที่ที่ไม่เกี่ยวข้องก็ไม่ควรส่งผลกระทบต่อสิ่งที่มีเสมอช่องว่างระหว่างคำสั่งและข้อโต้แย้งของ


30
อาจจะมีคำสั่งในสคริปต์ที่ไม่จำเป็นต้องสิทธิ์รากคุณสามารถวางสิทธิ์รากชั่วคราวสำหรับคำสั่งเหล่านั้นโดยใช้ชื่อผู้ใช้ sudo -u
โกหกไรอัน

48
สคริปต์ที่ฉันเขียนจำนวนมากทำการโต้ตอบกับผู้ใช้ทั้งหมดและ / หรือการตรวจสอบข้อผิดพลาด จากนั้นหนึ่งคำสั่งในตอนท้าย - บางอย่างเช่น rsync ต้องถูกเรียกใช้ในฐานะรูท เหตุใดฉันจึงต้องการทำให้ทุกอย่างทำงานสูงขึ้นและปล่อยให้ตัวเองเปิดรหัสหลายบรรทัดซึ่งอาจมีข้อผิดพลาดร้ายแรงหรือช่องโหว่ที่มีการเข้าถึงรูท - โดยเฉพาะในขณะที่ทำการดีบั๊กเมื่อคำสั่งเพียงหนึ่งหรือสองคำเท่านั้น
โจ

2
@Joe ยุติธรรมพอ เปลี่ยน "ไม่เป็นความคิดที่ดี" เป็น "ไม่ค่อย"
terdon

10
@ Joe มีจุดที่ดีจริงๆที่นี่ นอกจากนี้เมื่อมีคนบอกว่าอย่าทำอย่างนั้นมันจะเป็นการดีที่จะรู้ว่าทำไมเป็นอย่างนั้นหรืออย่างน้อยในบริบทที่ฉันไม่ควรทำอย่างนั้นและทำไม
arainone

10
@terdon คุณไม่ได้ฟัง ฉันรู้ว่าถ้าคุณเรียกใช้สคริปต์ในฐานะที่เป็นรูทมันจะไม่พร้อมท์ให้คุณใส่ sudo ฉันกำลังเปรียบเทียบว่าการไม่เรียกใช้สคริปต์ในฐานะรูทและแทนที่การsudoโทรอย่างชัดเจนในสคริปต์เนื่องจากการยกระดับสคริปต์ทั้งหมดไปยังรูทอาจเป็นความคิดที่แย่มากหากมีการดำเนินการแคบ ๆ เพียงเล็กน้อยที่ต้องการรูท ในบริบทนั้นฉันตอบกลับความคิดเห็นของคุณโดยเฉพาะ: "ส่วนใหญ่เพราะนี่หมายความว่าคุณไม่สามารถเรียกใช้สคริปต์ได้โดยอัตโนมัติเนื่องจากคุณจะต้องป้อนรหัสผ่านทุกครั้งที่คุณถาม"
BeeOnRope

41

คุณสามารถแก้ไขsudoersไฟล์ได้

sudo visudoวิ่ง

เพิ่มรายการสำหรับชื่อผู้ใช้และสคริปต์ที่คุณต้องการเรียกใช้โดยไม่ต้องถามรหัสผ่าน

username ALL=(ALL) NOPASSWD: /path/to/script

2
ไม่ได้ผลสำหรับฉัน แต่ขอบคุณที่รู้ว่ามีสิ่งนี้อยู่ บางทีฉันอาจผิดไวยากรณ์
Chris K

5
ไม่แน่ใจว่ามีใครพูดถึงมัน แต่คุณต้องยุติเซสชันการเข้าสู่ระบบทั้งหมดของผู้ใช้นั้นหลังจากคุณแก้ไขsudoersไฟล์แล้ว
escape-llc

1
เพียงชี้แจงให้ชัดเจนที่นี่ไม่ใช่สคริปต์ที่มี "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql" บรรทัดที่ควรระบุไว้ในไฟล์ sudoers แต่คำสั่งplay_delete_data_patch.shหรือสิ่งอื่น ๆ ที่คุณต้องการให้ผู้ใช้และ / หรือพวกเขา สคริปต์เพื่อให้สามารถทำงานผ่าน sudo โดยไม่ต้องระบุรหัสผ่าน
MttJocy

19

คุณสามารถลองสิ่งที่ชอบ:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

นี่ไม่ใช่สิ่งที่ปลอดภัยที่สุดที่ต้องทำเนื่องจากคุณกำลังเขียนรหัสผ่าน sudoer เป็นข้อความธรรมดา เพื่อให้มีความปลอดภัยเพิ่มขึ้นอีกเล็กน้อยคุณสามารถสร้างตัวแปรและอ่านรหัสผ่าน sudo ลงในตัวแปรแล้วคุณสามารถดำเนินการคำสั่งดังนี้:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

นอกจากนี้หากคุณไม่คำนึงถึงคำสั่งทั้งหมดของคุณที่ถูกเรียกใช้ในฐานะรูทคุณสามารถดำเนินการสคริปต์ของคุณได้ง่ายsudoตามที่แนะนำไว้ก่อนหน้านี้

sudo ./myscript

การอ่านรหัสผ่านเป็นตัวแปรอย่างปลอดภัย:read -s PASSWORD
Tobias Uhmann

10

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

อย่างไรก็ตามในกรณีที่คุณต้องการปล่อยสิทธิพิเศษให้กับคำสั่งบางคำสั่งและเรียกใช้ในฐานะผู้ใช้จริงที่เรียกใช้คำสั่งด้วยsudoคุณสามารถตรวจสอบ$SUDO_USERตัวแปรเพื่อหาผู้ใช้ดั้งเดิม

นี่คือตัวอย่างสคริปต์ของวิธีที่คุณสามารถทำได้:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command

4

จริงๆแล้วมีวิธีที่ง่ายกว่ามากในการทำเช่นนี้ เพื่อความสะดวกในการพกพานี่คือการนำไปใช้ของฉัน แต่อย่าลังเลที่จะจัดการให้เหมาะกับความต้องการของคุณ

ป้อนรหัสผ่าน sudo ของคุณเป็นพารามิเตอร์เมื่อเริ่มสคริปต์จับภาพและสะท้อนกับแต่ละคำสั่งซึ่งจะแจ้งให้รหัสผ่าน sudo

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>

คุณสามารถเพิ่มพรอมต์และการจับภาพหลังจากสคริปต์ถูกไล่ออกดังนี้:

echo "enter the sudo password, please"
read PW

แต่ถ้ามีคนอื่นตรวจสอบสิ่งที่ทำงานบนโหนด; มีการเข้าถึงบันทึกที่สร้างขึ้นโดยมัน; หรือกำลังมองหาของคุณควรสุ่มเมื่อคุณทำการทดสอบซึ่งอาจส่งผลต่อความปลอดภัย

สิ่งนี้ยังทำงานกับการรันคำสั่ง / สคริปต์ที่ต้องการให้ใช่เพื่อดำเนินการต่อ:

echo $PW | yes | ./install.sh

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


นั่นช่างงดงามและเรียบง่ายกว่านี้มากฉันดีใจที่เลื่อนลงมาจนสุด! แก้ไข: รอนี้จะเพิ่มรหัสผ่านไปยังประวัติเทอร์มินัลของฉัน
งาน

1
วิธีขอชื่อผู้ใช้ / รหัสผ่านด้วยread: ryanstutorials.net/bash-scripting-tutorial/bash-input.phpนั่นควรหลีกเลี่ยงปัญหานี้
งาน

3
#!/bin/bash
# this declares that current user is a sudoer
sudo tee /etc/sudoers.d/$USER <<END
END

# write the content of your script here
sudo npm install hexo-cli -g
mkdir Untitled
sudo apt-get install python

# then to remove the sudo access from the current user
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k

0

คุณสามารถลองเพิ่มผู้ใช้ที่รันสคริปต์ไปยังไฟล์ sudoers:

#give permissions to the file
sudo chmod 700 /etc/sudoers.d/useradm

sudo visudo /etc/sudoers.d/useradm

#add the following text, changing "user" but your desired user
user ALL=(ALL)NOPASSWD:ALL

#return the right permissions to the file
sudo chmod 440 /etc/sudoers.d/useradm

โดยทั่วไปนี่เป็นวิธีที่ไม่ดี หากคุณกำลังจะเพิ่มกฎ sudo NOPASSWD โดยเฉพาะอย่างยิ่งสำหรับบัญชีที่ใช้การทำงานแบบอัตโนมัติคุณควรอย่างน้อยควร จำกัด ให้เป็นคำสั่งที่แน่นอนที่ถูกเรียกใช้ (และไม่ใช่ทั้งหมด)
Christopher Hunter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.