วิธีหยุดสคริปต์ไม่ให้ทำงานหากไม่ใช่รูท (และ echo“ ไม่ทำงานเหมือนรูท! กำลังออกจาก…”)


17

นี่คือที่มาของฉัน:

#!/bin/bash

echo "Running script to free general cached memory!"
echo "";
echo "Script must be run as root!";
echo "";
echo "Clearing swap!";
swapoff -a && swapon -a;
echo "";
echo "Clear inodes and page file!";
echo 1 > /proc/sys/vm/drop_caches;
echo "";

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

ตัวอย่าง:

"Running script to free general cached memory!"
"Warning: script must be run as root or with elevated privileges!"
"Error: script not running as root or with sudo! Exiting..."

หากทำงานด้วยสิทธิ์ระดับสูงมันก็จะทำงานตามปกติ ความคิดใด ๆ ขอบคุณ!



2
@muru ยกเว้นคำถามอื่น ๆ ที่ตรงกันข้าม: สคริปต์ล้มเหลวหากทำงานในฐานะรูท
Stéphane Chazelas

3
@ StéphaneChazelasอ่าฉันไม่ดี หดกลับ
muru

ทางเลือกคือการ จำกัด ปริมาณของงานที่ดำเนินการrootโดย prefixing คำนำหน้าทุกคำสั่งที่ต้องทำงานเป็นด้วยroot sudo
reinierpost

คำตอบ:


46
#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

ผู้ใช้รูทมี UID 0 (ไม่คำนึงถึงชื่อของบัญชี "รูท") หาก UID ที่มีประสิทธิภาพส่งคืนโดยid -uไม่ใช่ศูนย์ผู้ใช้จะไม่เรียกใช้งานสคริปต์ด้วยสิทธิ์พิเศษระดับราก ใช้id -ruเพื่อทดสอบกับ ID จริง (UID ของผู้ใช้ที่เรียกใช้สคริปต์)

อย่าใช้ $EUIDในสคริปต์เนื่องจากอาจมีการแก้ไขโดยผู้ใช้ที่ไม่มีสิทธิ์:

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

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


1
หมายเหตุ: บน Solaris 5.10, /bin/id -uให้/bin/id: illegal option -- u Usage: id [-ap] [user]
jrw32982 สนับสนุนโมนิก้า

1
@ jrw32982 คุณควรมีสิทธิ์/usr/xpg4/binก่อน$PATHเพื่อรับการเข้าถึง POSIX ยูทิลิตี้บน Solaris
Kusalananda

1
ประเด็นก็คือ-uตัวเลือกที่idไม่เป็นสากลและดังนั้นการแก้ปัญหานี้เป็นสากลเฉพาะกับข้อแม้ที่ต้องมีเวอร์ชัน POSIX idเกิดขึ้นเป็นครั้งแรกในเส้นทางของคุณ
jrw32982 รองรับโมนิก้า

1
@ jrw32982 สำหรับสคริปต์ของคุณจะรับสาธารณูปโภค POSIX ที่ถูกต้องบน Solaris แก้ไข$PATHที่ด้านบนของสคริปต์เพื่อให้เป็นก่อน/usr/xpg4/bin /binหากคุณยืนยันในการใช้ที่ไม่ใช่ POSIX idแน่นอนว่าคุณจะต้องมีโซลูชันแบบพกพามากขึ้น
Kusalananda

1
@Harry ใช่ดังนั้นสคริปต์ที่สามารถใช้PATH=$( getconf PATH )หรือกำหนดเส้นทางเริ่มต้นอย่างชัดเจนอื่น ๆ idบางหรือใช้เส้นทางที่ชัดเจนสำหรับการโทร
Kusalananda

19

ฉันคิดว่าสิ่งที่คุณต้องการคือการตรวจสอบว่าคุณมีสิทธิ์ผู้ใช้ขั้นสูงหรือไม่นั่นคือรหัสผู้ใช้ที่มีประสิทธิภาพของคุณคือ 0

zshและbashทำให้พร้อมใช้งานใน$EUIDตัวแปรดังนั้นคุณสามารถทำได้:

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

ด้วยเชลล์ที่มีลักษณะคล้าย POSIX คุณสามารถใช้idคำสั่งมาตรฐาน:

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

โปรดทราบว่าทั้งหมดid -unหรือwhoamiหรือ$USERNAMEตัวแปรในzshคุณจะได้รับเป็นครั้งแรกชื่อผู้ใช้สำหรับ UID บนระบบที่มีผู้ใช้รายอื่นที่มี id 0 นั่นอาจไม่rootแม้ว่ากระบวนการนั้นจะเป็นลูกหลานของกระบวนการที่ได้รับการรับรองความถูกต้องrootแล้วก็ตาม

$USERจะมักจะให้ผู้ใช้ที่รับรองความถูกต้อง แต่อาศัยมันเป็นเปราะค่อนข้าง มันไม่ได้ถูกกำหนดโดยเชลล์ แต่มักจะถูกกำหนดโดยคำสั่งการรับรองความถูกต้อง (เช่นlogin, su(ในระบบ GNU / Linux, ไม่จำเป็นต้องเป็นแบบอื่น) sudo,, sshd(อย่างน้อยจาก openssh อย่างน้อย) ... ) ไม่เสมอไป (การเปลี่ยน uid ไม่ได้ตั้งค่าตัวแปรนั้นโดยอัตโนมัติ แต่จะต้องทำอย่างชัดเจนโดยแอปพลิเคชันที่เปลี่ยน uid) และมันอาจถูกแก้ไขโดยกระบวนการอื่น ๆ ในบรรพบุรุษของเชลล์ด้วย $LOGNAMEด้วยข้อแม้เดียวกันมีความน่าเชื่อถือมากกว่าที่ระบุโดย POSIX (มีพื้นเพมาจาก FIPS 151-2)


12

คุณสามารถใช้$USERหรือwhoamiเพื่อตรวจสอบผู้ใช้ปัจจุบัน

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

1
NP ผมขอแนะนำให้อย่างแท้จริงเพียงแค่การอ่านตรงผ่านคู่มือการทุบตี [ gnu.org/software/bash/manual/bashref.html] จริงๆแล้วมันเป็นเรื่องง่ายที่พร้อมอย่างน่าประหลาดใจ สำหรับคำตอบนี้โดยเฉพาะอย่างยิ่งผมขอแนะนำให้อ้างอิง: 3.2.4.2 Conditional Constructs 3.5.4 Command Substitution
Jesse_b

9
คำสั่งที่id -uมีหรือไม่มี-nตัวเลือกเป็นทางเลือกในการใช้ whoami หากไม่มี -n และเปรียบเทียบกับศูนย์จะเป็นการจับคู่ที่ดีกว่ากับการทดสอบที่เคอร์เนลกำลังทำอยู่ เคอร์เนลทั้งหมดใส่ใจคือ id ไม่ใช่ชื่อจากไฟล์รหัสผ่าน
รัส

6
ฉันเชื่อว่าการใช้$(id -u)ดีกว่า ในบางกรณี (ที่เป็นอันตราย) $USERอาจผิด
Basile Starynkevitch

1
สำหรับผู้ที่สนใจลิงค์ที่ให้บริการโดย @Jesse_b: มีการพิมพ์ผิด ควรเป็นgnu.org/software/bash/manual/bashref.html
Kryten

1
ระบบบางระบบไม่ใช้ "root" เป็นชื่อของบัญชีที่มีสิทธิพิเศษที่มี uid 0 QNAP จะถือว่าเป็นหนึ่งเดียว ดังนั้นคุณควรตรวจสอบ uid 0 เท่านั้นไม่ใช่ชื่อบัญชีรูท
roaima

10

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

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

แต่คุณสามารถลองการดำเนินการและออกด้วยข้อความที่เป็นประโยชน์หากล้มเหลว:

if ! ( swapoff -a && swapon -a )
then
  echo "Failed to clear swap (rerun as root?)" >&2
  exit 1
fi

if ! echo 1 > /proc/sys/vm/drop_caches
then 
  echo "Failed to free page cache (rerun as root?)" >&2
  exit 1
fi

ผู้ใช้ที่ไม่ใช่รูทปิดการสลับหรือไม่
Kusalananda

2
ใช่. คุณสามารถตั้งค่านี้ด้วย SELinux ในทำนองเดียวกันคุณสามารถปิดการใช้งานกระบวนการรูทได้
ผู้ชายคนนั้นอีกคน

1
คุณอาจไม่ต้องการexitหลังจากสิ่งที่ล้มเหลวในกรณีที่ผู้ใช้ต้องการทำมากที่สุดเท่าที่จะทำได้ด้วยสิทธิ์ปัจจุบันของพวกเขา (. แต่สำหรับระบบทั่วไปที่ทั้งหมดนี้ต้องใช้รากออกจะเป็นประโยชน์มากขึ้น / น้อยที่มีเสียงดัง)
ปีเตอร์ Cordes

2
ฉันจะไม่ไปไกลถึงจะบอกว่ามันเป็น "การปฏิบัติที่ไม่ดี" เพื่อตรวจสอบว่าคุณรูทหรือไม่ โดยเฉพาะอย่างยิ่งถ้าเป็นว่าสิ่งที่คุณต้องการที่จะรู้ว่า ฉันคิดว่าคุณควรตรวจสอบว่าคุณมีสิทธิ์เพียงพอที่จะทำสิ่งที่คุณต้องการหรือไม่
Erik Bennett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.