วิธีการเรียกใช้สองคำสั่งใน sudo


152

มีวิธีใดบ้างที่ฉันจะเรียกใช้คำสั่ง Db2 สองคำสั่งจากบรรทัดคำสั่งได้? (พวกเขาจะถูกเรียกจากexecคำสั่งPHP )

  1. db2 connect to ttt (โปรดทราบว่าเราจำเป็นต้องมีการเชื่อมต่ออยู่สำหรับคำสั่งที่สอง
  2. db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

ฉันลองสิ่งนี้:

sudo -su db2inst1 db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'

คำสั่งแรกดำเนินการอย่างถูกต้อง แต่คำสั่งที่สองล้มเหลวพร้อมกับข้อความแสดงข้อผิดพลาด SQL1024N A database connection does not exist. SQLSTATE=08003

โปรดทราบว่าฉันต้องเรียกใช้สิ่งนี้ในฐานะผู้ใช้ php คำสั่งsudo -u db2inst1 idในฐานะผู้ใช้phpให้ผลลัพธ์ที่ถูกต้องแก่ฉัน


โปรดแสดงความคิดเห็นว่าทำไมคุณต้องการปิดคำถามนี้ ขอบคุณ.
Radek

1
โหวตปิดสำหรับการโยกย้ายไปยังเซิร์ฟเวอร์ผิดเนื่องจากเป็นคำถามการบริหารระบบไม่ใช่การเขียนโปรแกรม
bdonlan

คำตอบ:


157

sudo สามารถเรียกใช้หลายคำสั่งผ่านเชลล์ตัวอย่างเช่น:

$ sudo -s - 'whoami; ฉันเป็นใคร'
ราก
ราก

คำสั่งของคุณจะเป็นเช่น:

sudo -u db2inst1 -s - "db2 เชื่อมต่อกับ ttt; db2 ชุดอัพเดทการติดต่อ EMAIL_ADDRESS = 'mytestaccount@gmail.com'"

หากเวอร์ชั่น sudo ของคุณใช้งานไม่ได้กับเครื่องหมายอัฒภาคด้วย -s (เห็นได้ชัดว่าไม่ใช่ถ้าคอมไพล์ด้วยตัวเลือกบางตัว) คุณสามารถใช้

sudo - sh -c 'whoami; ฉันเป็นใคร'

ซึ่งโดยทั่วไปแล้วจะทำสิ่งเดียวกัน แต่ทำให้คุณตั้งชื่อเชลล์อย่างชัดเจน


12
นี้ไม่ได้ทำงานบนเดเบียนที่มีเสถียรภาพ (บีบ) ทุบตีล่าสุด:sudo -s -- '/usr/bin/whoami; /usr/bin/whoami' /bin/bash: /usr/bin/whoami; /usr/bin/whoami: No such file or directory
กล้าหาญ

11
@Valor คุณสามารถใช้sudo -- sh -c 'whoami; whoami;เป็นวิธีแก้ปัญหาเมื่อ "sudo -s" เสีย ฉันได้อัพเดตคำตอบแล้วเช่นกัน
wjl

6
+1 สำหรับเวอร์ชันที่แก้ไขซึ่งแสดงตัวอย่าง "- sh -c" ขอบคุณ!
JD

4
คุณช่วยอธิบายได้ไหมว่าทำไมคุณถึงต้องการ "-"
Vic Seedoubleyew

7
@VicSeedoubleyew การ--ระบุจุดสิ้นสุดของพารามิเตอร์เพื่อsudoให้ทุกอย่างเป็นส่วนหนึ่งของคำสั่ง; โดยไม่ได้มีปากเสียงเช่นอาจจะตีความเป็นอาร์กิวเมนต์ไปยัง-c sudoสิ่งนี้ใช้ได้กับโปรแกรมบรรทัดคำสั่งส่วนใหญ่ (แต่ไม่ใช่ทั้งหมด) สำหรับตัวอย่างอื่น (ไม่ใช่ - sudo) การลบไฟล์ที่เรียกว่า-fคุณไม่สามารถเรียกใช้ได้rm -fใช่ไหม! แต่คุณสามารถเรียกใช้เพื่อลบไฟล์ที่เรียกว่าrm -- -f -f
wjl

176

สำหรับคำสั่งของคุณคุณสามารถอ้างถึงตัวอย่างต่อไปนี้:

sudo sh -c 'whoami; whoami'


14
ฉันได้พบสิ่งนี้เป็นทางเลือกที่เชื่อถือได้มากขึ้น
Nick


42

หากคุณต้องการจัดการคำพูด:

sudo -s -- <<EOF
id
pwd
echo "Done."
EOF

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

8

ทางเลือกอื่นที่ใช้evalเพื่อหลีกเลี่ยงการใช้ subshell:

sudo -s eval 'whoami; whoami'

หมายเหตุ: คำตอบอื่น ๆ ที่ใช้sudo -sล้มเหลวเนื่องจากคำพูดถูกส่งผ่านไปยังทุบตีและเรียกใช้เป็นคำสั่งเดียวดังนั้นจำเป็นต้องตัดคำพูดด้วย eval evalอธิบายได้ดีกว่านี้คือคำตอบดังนั้น

การอ้างถึงคำสั่งต่าง ๆ นั้นง่ายขึ้นเช่นกัน:

$ sudo -s eval 'whoami; whoami; echo "end;"'
root
root
end;

และหากคำสั่งจำเป็นต้องหยุดการทำงานหากล้มเหลวให้ใช้ double-ampersands แทน semi-colons:

$ sudo -s eval 'whoami && whoamit && echo "end;"'
root
/bin/bash: whoamit: command not found

3

-sตัวเลือกที่ไม่ได้ทำงานให้ฉัน-iทำ

นี่คือตัวอย่างของวิธีที่ฉันสามารถอัปเดตขนาดบันทึกจากทุบตีของฉัน:

sudo -u [user] -i -- sh -c 'db2 connect to [database name];db2 update db cfg for [database name] using logsecond 20;db2 update db cfg for [database name] using logprimary 20;'

1

บนเทอร์มินัลพิมพ์:

$ sudo bash

จากนั้นเขียนคำสั่งได้มากเท่าที่คุณต้องการ พิมพ์exitเมื่อคุณทำเสร็จ

หากคุณต้องการทำให้เป็นอัตโนมัติให้สร้างscript.shไฟล์และเรียกใช้:

$ sudo ./script.sh

1

ในหัวข้อที่เกี่ยวข้องเล็กน้อยฉันต้องการทำ sudo แบบหลายคำสั่งเดียวกันผ่าน SSH แต่ไม่มีการทำงานใด ๆ ข้างต้น

ตัวอย่างบน Ubuntu

$ ssh host.name sudo sh -c "whoami; whoami"
[sudo] password for ubuntu:
root
ubuntu

เคล็ดลับที่ค้นพบที่นี่คือการอ้างคำสั่งสองครั้ง

$ ssh host.name sudo sh -c '"whoami; whoami"'
[sudo] password for ubuntu:
root
root

ตัวเลือกอื่น ๆ ที่ใช้งานได้:

ssh host.name sudo sh -c "\"whoami; whoami\""
ssh host.name 'sudo sh -c "whoami; whoami"'

โดยหลักการแล้วจำเป็นต้องใช้ double-quotes เพราะฉันคิดว่า client shell ที่ SSH ทำงานอยู่จะตัดชุดคำพูดที่อยู่ด้านนอกสุดออกมา ผสมและจับคู่อัญประกาศกับความต้องการของคุณ (เช่นตัวแปรต้องถูกส่งผ่าน) อย่างไรก็ตาม YMMV พร้อมเครื่องหมายคำพูดโดยเฉพาะหากคำสั่งระยะไกลมีความซับซ้อน ในกรณีนี้เครื่องมืออย่าง Ansible จะเป็นตัวเลือกที่ดีกว่า


1

หากคุณรู้รหัสผ่านรูทคุณสามารถลองได้

su -c "<command1> ; <command2>"  

sudo su -c "<command1> ; <command2>" หากคุณไม่ทราบรหัสผ่านรากใช้
Dag Høidahl

0

คำตอบข้างต้นจะไม่ยอมให้คุณพูดในเครื่องหมายคำพูด วิธีนี้จะ:

sudo -su nobody umask 0000 \; mkdir -p "$targetdir"

ทั้งคำสั่ง umask และคำสั่ง mkdir-รันด้วยผู้ใช้ 'none'


คุณสามารถใช้เครื่องหมายคำพูดเดี่ยวและคู่และหนีออกมาได้
Radek

ตกลงแล้วทำไมล่ะตอนนี้สิ่งสำคัญที่ข้าตั้ง umask ไว้ในคำสั่งนี้มันไม่มีผลอะไรเลย?
Michael
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.