วิธีทดสอบว่าเจ้าของไฟล์สามารถเรียกใช้งานได้หรือไม่ ** ไม่จำเป็นต้องเป็นฉัน **

นี่ไม่ใช่คำถามที่ซ้ำกัน

สมมติว่าฉันมี

  1. เส้นทางเต็ม
  2. ไปยังไฟล์ปกติชื่อ target
  3. ที่ อาจ เป็นของ ผู้ใช้รายอื่น
  4. และสภาพแวดล้อมอาจถูกถอดออก (busybox ที่เปิดใช้งานน้อยมาก)

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

นี่เป็นบริบททางวิชาชีพ ไม่ใช่การบ้าน

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

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

[ -x "$path" ] บอกฉันเท่านั้นว่า ฉัน สามารถดำเนินการได้หรือไม่

ls -l "$path" และการตรวจสอบว่าอักขระตัวที่สี่คือ x ดูเปราะบางเกินไปหรือไม่: -rwxrw-rw- 1 otheruser group 26 Jun 13 10:57 target

ls -F "$path" และการตรวจสอบว่าลงท้ายด้วย * ดูดีขึ้นเล็กน้อย: target* สภาพแวดล้อมเดียวที่ฉันทดสอบนั้นคำนึงถึงว่าใครคือเจ้าของที่แท้จริง... แต่นี่ไม่รู้สึกว่าเป็นวิธีที่ดีที่สุด...


person user1011471    schedule 13.06.2018    source แหล่งที่มา
comment
จะเกิดอะไรขึ้นถ้า fs ติดตั้ง noexec? วิธีนี้จะป้องกันไม่ให้ผู้ใช้เรียกใช้ไฟล์โดยไม่คำนึงถึงสิทธิ์   -  person that other guy    schedule 13.06.2018
comment
ฉันได้แก้ไขเพื่อให้ชัดเจนว่านี่ไม่ใช่รายการที่ซ้ำกัน (เหตุผลของฉันในการพิจารณาออก [ -x "$path" ] นั้นเพียงพอที่จะแยกแยะได้ในทางเทคนิค ฉันคิดว่า) โปรแกรมของฉันคือเครื่องมือตรวจสอบความถูกต้อง และต้องการให้แน่ใจว่าเจ้าของไฟล์แต่ละไฟล์ในไดเร็กทอรีนั้นสามารถเรียกใช้งานได้โดยเจ้าของรายนั้น ฉันไม่คิดว่ากลุ่มจะนับเพราะฉันทิ้งสิทธิ์ผู้ใช้ในสิ่งที่ฉันเป็นเจ้าของซึ่งมีกลุ่ม (ของฉัน) และชุด x อื่น ๆ และฉันไม่สามารถดำเนินการได้ ไม่มีการบ้าน จำเป็นต้องแข็งแกร่งและจัดการกับสภาพแวดล้อม Linux ที่แปลกหรือเก่าทุกประเภท   -  person user1011471    schedule 14.06.2018


คำตอบ (3)


permissions=$(stat -c "%a" target)
permissions=$(( ${permissions: -3: 1} % 2 ))

stat ให้สิทธิ์แก่คุณในไฟล์เป็นฐานแปด จากนั้นเราต้องการเพียงอักขระสำหรับการอนุญาตของเจ้าของ (ทางเทคนิคที่สามจากขวา ไม่ใช่อักขระตัวแรก) จากนั้นจำเป็นต้องตรวจสอบว่าเป็นเลขคี่หรือไม่ (ปฏิบัติการในฐานแปดคือ 1 บิต)

หากสิทธิ์เป็น 1 แสดงว่าเจ้าของสามารถเรียกใช้งานได้ ถ้าเป็น 0 ก็ไม่ใช่

สภาพแวดล้อมที่เก่ากว่าอาจต้องใช้นิพจน์ทางคณิตศาสตร์แทน:

permissions=$(stat -c "%a" $target)
if [ $((0$permissions & 0100)) -ne 0 ]; then
    # executable by owner
else
    # not executable by owner
fi
person jeremysprofile    schedule 13.06.2018
comment
@thatotherguy นั่นเป็นการใช้สตริงย่อยของ val เริ่มต้นที่ 3 อักขระจากด้านขวาสุดหรือไม่? หากเป็นเช่นนั้น อาร์กิวเมนต์ถัดไปไม่ใช่ความยาวและควรเป็น 1 แทนที่จะเป็น -2 หรือ ... ฉันผิดอะไรเมื่อพูดถึงเรื่องนั้น -2? - person user1011471; 14.06.2018
comment
@ user1011471 คุณสามารถลองทดสอบโค้ดด้วยตัวเองและตรวจสอบว่าใช้งานได้ - person jeremysprofile; 14.06.2018
comment
@ user1011471 wiki.bash-hackers.org/syntax/pe#negative_length_value - person jeremysprofile; 15.06.2018
comment
โอ้. ใช้งานได้ตั้งแต่ Bash 4.2-alpha ในการแก้ไข OP ในภายหลังของฉัน ฉันพูดถึงความจำเป็นในการรองรับสภาพแวดล้อมแบบเก่าที่บ้าคลั่ง ซึ่งในกรณีนี้ 1 จะดีกว่าใช่ไหม - person user1011471; 15.06.2018
comment
@ user1011471 ใช่ ฉันเชื่อว่าการชดเชยเชิงลบอาจไม่ทำงานใน bash เวอร์ชันเก่าที่เพียงพอด้วยซ้ำ (แต่ฉันอาจคิดผิด ฉันไม่สามารถหาแหล่งสำรองความรู้สึกนั้นได้) - person jeremysprofile; 15.06.2018
comment
หากคุณเพิ่ม 1 เป็นทางเลือกที่ใช้ได้กับเครื่องรุ่นเก่า ฉันจะยอมรับคำตอบนี้ นั่นคือสิ่งที่ฉันใช้ในที่สุด - person user1011471; 15.06.2018
comment
@ user1011471 เปลี่ยนแปลงแล้ว 1 นั้นถูกต้องทั้งสองวิธี ดังนั้นจึงไม่จำเป็นต้องเป็นทางเลือกอื่นจริงๆ - person jeremysprofile; 15.06.2018
comment
อีกทางเลือกหนึ่งคือ if (( 0$val & 0100)); then echo "executable by owner"; fi - person that other guy; 15.06.2018

คุณสามารถใช้ find หากคุณไม่ต้องการแยกวิเคราะห์ผลลัพธ์ของบางสิ่ง:

if find ${path} -prune -perm -u+x | grep -q ''; then
  echo "Executable by owner"
else
  echo "Not executable by owner"
fi

ตัวเลือก -perm ช่วยให้คุณตรวจสอบว่า user (เจ้าของ) ปฏิบัติการได้หรือไม่ และตัวเลือก -prune จะป้องกันการลงไปยังไดเร็กทอรีหาก ${path} เป็นไดเร็กทอรี ดังนั้นเราจึงสามารถตรวจสอบพาธที่กำหนดได้ด้วยตัวเอง

person Brandon Miller    schedule 13.06.2018

ls -l "$path" และตรวจสอบสิทธิ์กลุ่มแรก (สิทธิ์ของเจ้าของ) หากมี x อยู่ในนั้น แสดงว่าเจ้าของไฟล์สามารถเรียกใช้งานได้

person Athanasios Emmanouilidis    schedule 13.06.2018
comment
คุณแสดงออกอย่างไร (ตรวจสอบกลุ่มแรกของการอนุญาตสำหรับ x) ในเชลล์สคริปต์ - person user1011471; 13.06.2018