จะทดสอบการเข้าถึงไฟล์โดยไม่รุกรานได้อย่างไร?


20

ในเชลล์สคริปต์ฉันจะทดสอบการเข้าถึงการเขียนไฟล์อย่างง่าย ๆ โดยไม่ต้องทำการบุกรุกโดยไม่ต้องพยายามแก้ไขไฟล์ได้อย่างไร?

ฉันสามารถแยกเอาท์พุทของstatแต่ดูเหมือนว่าซับซ้อนจริง ๆ และอาจเปราะแม้ว่าฉันไม่แน่ใจว่าผลลัพธ์สถิติแตกต่างกันในการใช้งานและเวลา

ฉันสามารถต่อท้ายไฟล์และดูว่าประสบความสำเร็จ แต่อาจเป็นอันตรายได้ด้วยเหตุผลสองประการที่ฉันนึกถึง:

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

คำตอบ:


29

เพียงแค่ใช้ - wธงชาติของtestutillity:

[ -w /path/to/file ] && echo "writeable" || echo "write permission denied"

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


1
แน่นอน! ฉันควรคิดที่จะตรวจสอบหน้าคนของการทดสอบ ขอขอบคุณ.
user50849

1
@qweilun มันเป็น shell builtin แต่คุณสามารถแสดง man page ผ่านman testหรือman [
chaos

5
@chaos มันเป็นทั้ง shell builtin และ executable ภายนอก - ลองtype -a
Volker Siegel

1
ต่อแหล่งที่มาtestใช้ซึ่งก็จะตรวจสอบบิตได้รับอนุญาตeuidaccess ไม่มีปัจจัยอื่น ๆ (เช่น SELinux) ที่สามารถห้ามการเข้าถึงเพื่อเขียน
zamnuts

2
@BroSlow &&และ||มีความสำคัญเท่ากัน พวกเขากำลังประเมินจากซ้ายไปขวา
Wildcard

11

วิธีอื่น:

if >> /path/to/file
then
    echo "writeable"
else
    echo "write permission denied"
fi

การดำเนินการนี้จะพยายามเปิดไฟล์สำหรับการต่อท้ายและหากประสบความสำเร็จให้ เรียกใช้คำสั่ง no (เช่นเรียกใช้คำสั่ง null ) ด้วยเอาต์พุตไปยังไฟล์ 

ระวังว่านี่จะสร้างไฟล์เปล่าถ้ามันไม่มีอยู่

-wดำเนินการของtestคำสั่งเพียงแค่อาจจะทำstat แล้วพยายามที่จะคิดออกว่ามันดูเหมือนว่าคุณควรมีการเข้าถึง ทางเลือกของฉัน (ด้านบน) มีความน่าเชื่อถือมากกว่าtestวิธีการในเงื่อนไขพิเศษบางอย่างเนื่องจากบังคับให้การตรวจสอบการเข้าถึงทำโดยเคอร์เนลแทนที่จะเป็นเชลล์ ตัวอย่างเช่น,

  • หากไฟล์อยู่ในระบบไฟล์ที่ไม่ใช่ Unix - โดยเฉพาะหากไฟล์นั้นถูกเมาท์จากเซิร์ฟเวอร์ไฟล์ที่ไม่ใช่ Unix จากระยะไกล - เนื่องจากstatอาจส่งคืนค่าโหมดที่ทำให้เข้าใจผิด
  • หากไฟล์อยู่บนระบบไฟล์ที่เมาท์แบบอ่านอย่างเดียว
  • หากไฟล์มี ACL และโหมดทำให้ดูเหมือนว่าคุณควรมีสิทธิ์เข้าถึง แต่ ACL ปฏิเสธหรือในทางกลับกัน
  • ถ้ากรอบความปลอดภัย (AppArmor, SELinux, …) ปฏิเสธการเข้าถึงไฟล์

3
ฉันเพิ่งทดสอบสิ่งนี้ (บนเดเบียน) ไม่ว่าเวลาจะเปลี่ยนแปลงไปหรือไม่และนั่นก็เป็นวิธีที่มันควรใช้กับยูนิกซ์ เวลาในการเข้าถึงควรได้รับการอัปเดตเฉพาะเมื่อคุณอ่านจากไฟล์เท่านั้นเวลาในการแก้ไขควรได้รับการอัปเดตเมื่อคุณเขียนไฟล์เท่านั้น รหัสนี้ไม่ได้ @Schwern: คุณมีการอ้างอิงสำหรับคำสั่งของคุณ? คุณเคยลองบ้างไหม?
G-Man กล่าวว่า 'Reinstate Monica'

2
PS @muru: ฉันพยายามtouchไฟล์ที่ฉันเป็นเจ้าของ แต่ไม่มีสิทธิ์เข้าถึงเพื่อเขียนและมันก็ประสบความสำเร็จ ฉันเดาว่ามันchmodเป็นไฟล์และchmodกลับมา ดังนั้นtouchดูเหมือนจะไร้ประโยชน์อย่างแน่นอนเป็นคำตอบสำหรับคำถาม
G-Man กล่าวว่า 'Reinstate Monica'

2
@ G-Man อาน่าสนใจ IIRC vimมีพฤติกรรมการเปลี่ยนการอนุญาตอย่างรวดเร็วเมื่อถูกบังคับให้เขียนไฟล์แบบอ่านอย่างเดียว ฉันจะตรวจสอบด้วยstrace, touch's openล้มเหลวด้วยEACCESแต่โทรตามมาที่จะutimensatประสบความสำเร็จซึ่งเป็นเหตุผลที่ผมคิดว่าtouchในการออกจากทั้งที่ประสบความสำเร็จ
muru

2
@muru: ขอบคุณสำหรับการตรวจสอบว่า utimensat(2)พูดว่า“ ข้อกำหนดการอนุญาต: 1. การเข้าถึงเพื่อเขียน (หรือ) 2. ID ผู้ใช้ที่มีประสิทธิภาพของผู้โทรต้องตรงกับเจ้าของไฟล์….”
G-Man กล่าวว่า 'Reinstate Monica'

3
ปัญหาอื่น ๆ เช่นสำหรับ Champignac's: >> fileไม่สามารถพกพาได้ (เช่นใช้ NULLCMD เป็น zsh) ให้ใช้true >> fileแทน และถ้าไฟล์เป็นชื่อที่มีชื่อก็จะมีผลข้างเคียงที่น่ารังเกียจ
Stéphane Chazelas

3

G-มนุษย์เป็นขวา: [ -w ]จะไม่เสมอบอกความจริง ที่นี่เพื่อจัดการกับไฟล์ที่ไม่ได้มีอยู่และการอนุญาตถูกปฏิเสธข้อความจากเชลล์:

( [ -e /path/to/file ] && >> /path/to/file ) 2> /dev/null && 
  echo writable || 
  echo not writable

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

จะสรุปได้อย่างไร? แม้ว่า[ -w ]จะไม่ได้บอกความจริงก็ตามมันเป็นคำสั่งเดียวที่มีจุดประสงค์ในการทำงาน หากไม่ดีเราจะตำหนิเขียนรายงานข้อผิดพลาดและจะใช้งานได้ในอนาคต ดีกว่าการตรวจสอบภายใต้เงื่อนไขที่การทำงานและการใช้งาน[ -w ]; เขียนรหัสพิเศษสำหรับกรณีพิเศษ วิธีแก้ไขปัญหามีเงื่อนไขของตนเอง

[ -w /path/to/file ]

ที่ดีที่สุดคือเบื้องต้น


3
หากไฟล์เป็นไพพ์ที่มีชื่อไฟล์จะหยุดทำงานหากไม่มีการอ่านและแม้ว่าจะมีผู้อ่านจะมีผลข้างเคียงที่น่ารังเกียจ test -wในการใช้งานส่วนใหญ่ใช้access(2)ดังนั้นควรจะเพียงพอที่จะทดสอบการอนุญาต
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.