ค้นหาไฟล์ปฏิบัติการโดยใช้คำสั่ง find


114

ฉันสามารถใช้พารามิเตอร์ / แฟล็กประเภทใดกับfindคำสั่งUnix เพื่อให้ฉันค้นหาไฟล์ปฏิบัติการได้


พิมพ์ 'man find' ฉันคิดว่า '-executable' เป็นตัวเลือกที่คุณต้องการ
sje397

3
find -executable... แต่นี่ไม่ได้รับประกันว่าทุกไฟล์ในรายการจะทำงานได้จริง
วิลเลียม

1
การใช้งานทั้งหมดไม่ได้findสร้างขึ้นเท่ากัน ตัวเลือกที่แนะนำโดย @ sje397 และ @William อาจไม่สามารถใช้ได้ ควรใช้โซลูชันที่ได้รับการยอมรับตามที่แสดงด้านล่างนี้
LS


ฉันไม่ชอบข้อเสนอทั้งหมดที่แสดงด้านล่างซึ่งขึ้นอยู่กับสิทธิ์ของไฟล์ อาร์กิวเมนต์: สำหรับระบบปฏิบัติการ GNU ของฉัน (Ubuntu) สามารถตั้งค่าสถานะ "x" (ปฏิบัติการได้) สำหรับไฟล์ข้อความ ASCII ไม่มีการเลียนแบบใดที่ป้องกันไม่ให้การดำเนินการนี้สำเร็จ มันต้องการข้อผิดพลาด / ข้อผิดพลาดเล็ก ๆ น้อย ๆ สำหรับไฟล์ที่ไม่ได้ตั้งใจหลายไฟล์เพื่อรับค่าสถานะ x ดังนั้นโซลูชันของ gniourf_gniourf จึงเป็นที่ชื่นชอบส่วนตัวของฉัน อย่างไรก็ตามมีข้อเสียเปรียบที่สำหรับไฟล์ปฏิบัติการที่รวบรวมข้ามคอมไพล์จำเป็นต้องมีโปรแกรมจำลองหรืออุปกรณ์เป้าหมาย

คำตอบ:


175

ในเวอร์ชัน GNU คุณสามารถใช้-executable:

find . -type f -executable -print

สำหรับการค้นหาเวอร์ชัน BSD คุณสามารถใช้-permร่วมกับ+และมาสก์ฐานแปด:

find . -type f -perm +111 -print

ในบริบทนี้ "+" หมายถึง "บิตใด ๆ เหล่านี้ถูกตั้งค่า" และ 111 คือบิตที่ดำเนินการ

โปรดทราบว่าสิ่งนี้ไม่เหมือนกับเพรดิเคต-executableใน GNU find โดยเฉพาะอย่างยิ่ง-executableการทดสอบว่าผู้ใช้ปัจจุบันสามารถเรียกใช้ไฟล์ได้ในขณะที่-perm +111ทดสอบว่ามีการตั้งค่าสิทธิ์ในการดำเนินการหรือไม่

GNU เวอร์ชันเก่ากว่ายังรองรับ-perm +111ไวยากรณ์ด้วย แต่เมื่อถึง4.5.12ไวยากรณ์นี้ไม่ได้รับการสนับสนุนอีกต่อไป แต่คุณสามารถใช้-perm /111เพื่อรับพฤติกรรมนี้ได้


ข้อผิดพลาดfind: invalid mode ‘+111’ใน findutils 4.5.11 4.fc20
sourcejedi

1
@sourcejedi ขอบคุณ จริงๆแล้วฉันกำลังพูดถึงการค้นหาเวอร์ชันที่ไม่ใช่ GNU เท่านั้น (โดยเฉพาะอย่างยิ่ง BSD) แต่ GNU เวอร์ชันเก่าพบว่ารองรับไวยากรณ์นั้นด้วยเช่นกัน ในเวอร์ชันที่ใหม่กว่าคุณจะต้องใช้/แทน+ไฟล์. ดูคำตอบที่อัปเดตสำหรับรายละเอียดเพิ่มเติม
Laurence Gonsalves

อันที่จริงฉันอ่านคำตอบของคุณผิด ขออภัยที่ทำให้ซับซ้อนมากขึ้น :).
sourcejedi

หากsymlinksไปยังแฟ้มที่ปฏิบัติการก็ควรจะพบรวมถึงตัวเลือก:-L find -L ...
mklement0

ฉันใช้เวลาสักพักในการทำความเข้าใจผลของ "ไม่เหมือนกับเพรดิเคต -executable" และ "เพียงแค่ทดสอบว่ามีการตั้งค่าสิทธิ์ในการดำเนินการใด ๆ หรือไม่" นั่นหมายความว่า-perm +111อาจให้ผลบวกเท็จเช่นไฟล์ที่ผู้ใช้ปัจจุบันไม่สามารถดำเนินการได้จริง ไม่มีทางที่จะเลียนแบบไม่ได้-executableโดยการทดสอบสิทธิ์เพียงอย่างเดียวเพราะสิ่งที่จำเป็นคือการเกี่ยวข้องไฟล์ของผู้ใช้และกลุ่มตัวตนไปของผู้ใช้ปัจจุบัน
mklement0

35

เคล็ดลับสำหรับ @ gniourf_gniourfเพื่อล้างความเข้าใจผิดพื้นฐาน

ความพยายามในการนี้คำตอบที่จะให้ภาพรวมของคำตอบที่มีอยู่และเพื่อหารือเกี่ยวกับของพวกเขารายละเอียดปลีกย่อยและญาติเช่นเดียวกับการให้ข้อมูลพื้นฐานโดยเฉพาะอย่างยิ่งเกี่ยวกับการพกพา

การค้นหาไฟล์ที่เรียกใช้งานได้สามารถอ้างถึงกรณีการใช้งานที่แตกต่างกันสองกรณี :

  • ผู้ใช้เป็นศูนย์กลาง : ค้นหาไฟล์ที่มีปฏิบัติการโดยผู้ใช้ปัจจุบัน
  • ไฟล์ศูนย์กลางหาไฟล์ที่มี (อย่างใดอย่างหนึ่งหรือมากกว่า): บิตได้รับอนุญาตปฏิบัติการชุด

ทราบว่าในทั้งสถานการณ์มันอาจจะทำให้ความรู้สึกที่จะใช้find -L ...แทนเพียงfind ...เพื่อที่จะยังหาsymlinks เพื่อ executables

หมายเหตุว่าแฟ้มเป็นศูนย์กลางกรณีที่ง่าย - มองหา executables ที่มีสิทธิ์ในการปฏิบัติการตั้งค่าบิตสำหรับทั้งสามการรักษาความปลอดภัย (ผู้ใช้กลุ่มอื่น ๆ ) - จะโดยทั่วไปแต่ไม่จำเป็นต้องให้ผลผลิตผลเช่นเดียวกับสถานการณ์ที่ผู้ใช้เป็นศูนย์กลาง - และก็ สิ่งสำคัญคือต้องเข้าใจความแตกต่าง

ผู้ใช้เป็นศูนย์กลาง ( -executable)

  • คำตอบที่ได้รับการยอมรับ commendably แนะนำ-executableถ้าGNU findใช้ได้

    • GNU findมาพร้อมกับLinux distros ส่วนใหญ่
      • ในทางตรงกันข้ามแพลตฟอร์มที่ใช้ BSD รวมถึง macOS นั้นมาพร้อมกับ BSD find ซึ่งมีประสิทธิภาพน้อยกว่า
    • ตามที่สถานการณ์ต้องการให้-executableจับคู่เฉพาะไฟล์ที่ผู้ใช้ปัจจุบันสามารถดำเนินการได้ (มีกรณีขอบ[1] )
  • BSD findทางเลือกที่นำเสนอโดยคำตอบที่ได้รับการยอมรับ ( -perm +111) คำตอบที่แตกต่างกัน , ไฟล์คำถามศูนย์กลาง (เป็นคำตอบของตัวเองระบุ)

    • โดยใช้เพียง-permที่จะตอบผู้ใช้คำถามเป็นศูนย์กลางเป็นไปไม่ได้เพราะสิ่งที่จำเป็นคือการเกี่ยวข้องไฟล์ของผู้ใช้และกลุ่มตัวตนให้กับผู้ใช้ปัจจุบันในขณะที่-permสามารถทดสอบไฟล์สิทธิ์
      การใช้คุณสมบัติPOSIXfindเพียงอย่างเดียวไม่สามารถตอบคำถามได้หากไม่เกี่ยวข้องกับยูทิลิตี้ภายนอก
    • ดังนั้นที่ดีที่สุดที่-permสามารถทำ (ด้วยตัวเอง) เป็นประมาณ-executableของ บางทีอาจเป็นการประมาณที่ใกล้เคียงกว่าที่-perm +111เป็นอยู่-perm -111เพื่อค้นหาไฟล์ที่มีการตั้งค่าบิตปฏิบัติการสำหรับหลักการรักษาความปลอดภัยทั้งหมด (ผู้ใช้กลุ่มอื่น ๆ ) - สิ่งนี้ทำให้ฉันรู้สึกเหมือนสถานการณ์ในโลกแห่งความจริงทั่วไป นอกจากนี้ยังเป็นโบนัสที่สอดคล้องกับ POSIX ด้วย (ใช้find -Lเพื่อรวม symlinks ดูคำอธิบายเพิ่มเติมด้านล่าง):

      find . -type f -perm -111  # or: find . -type f -perm -a=x
  • คำตอบ gniourf_gniourf ของให้จริงเทียบเท่าแบบพกพาของ-executableใช้-exec test -x {} \;แม้ว่าค่าใช้จ่ายของการปฏิบัติงาน

    • การรวม -exec test -x {} \;กับ-perm +111(กล่าวคือไฟล์ที่มีชุดบิตที่ปฏิบัติการได้อย่างน้อยหนึ่งชุด) อาจช่วยให้ประสิทธิภาพที่execไม่จำเป็นต้องถูกเรียกใช้สำหรับทุกไฟล์ (ต่อไปนี้ใช้การค้นหา BSD find -perm +111/ GNU ที่สอดคล้องกับ POSIX -perm /111โปรดดูคำอธิบายเพิ่มเติมด้านล่าง) :

      find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print

ไฟล์เป็นศูนย์กลาง ( -perm)

  • หากต้องการคำตอบไฟล์คำถามเป็นศูนย์กลางก็คือ เพียงพอที่จะใช้ POSIX ที่สอดคล้องกับ-permหลัก (ที่รู้จักกันในการทดสอบใน GNU หาคำศัพท์)
    • -permช่วยให้คุณทดสอบการอนุญาตไฟล์ใด ๆไม่ใช่แค่ความสามารถในการดำเนินการ
    • สิทธิ์ที่จะระบุเป็นทั้งฐานแปดหรือโหมดสัญลักษณ์ โหมดฐานแปดคือตัวเลขฐานแปด (เช่น111) ในขณะที่โหมดสัญลักษณ์เป็นสตริง (เช่นa=x)
    • โหมดสัญลักษณ์ระบุหลักการรักษาความปลอดภัยเป็นu(ผู้ใช้) g(กลุ่ม) และo(อื่น ๆ ) หรือaเพื่ออ้างถึงทั้งสาม สิทธิ์ที่จะแสดงเป็นxสำหรับการปฏิบัติการเช่นและมอบหมายให้ผู้บริหารใช้ประกอบการ=, +และ-; สำหรับการสนทนาแบบเต็มรวมทั้งโหมดฐานแปดดูข้อมูลจำเพาะ POSIX สำหรับchmodยูทิลิตี้
    • ในบริบทของfind:
      • คำนำหน้าโหมดด้วย- (เช่น-ug=x) หมายถึง: จับคู่ไฟล์ที่มีสิทธิ์ทั้งหมดที่ระบุไว้ (แต่ไฟล์ที่ตรงกันอาจมีสิทธิ์เพิ่มเติม)
      • มีไม่มีคำนำหน้า (เช่น755) หมายถึง: แฟ้มที่มีการจับคู่นี้เต็มรูปแบบที่แน่นอนชุดของสิทธิ์
      • ข้อแม้ : ทั้งGNU find และ BSD พบว่าใช้คำนำหน้าเพิ่มเติมที่ไม่เป็นมาตรฐานพร้อมตรรกะที่กำหนด - อนุญาตบิตกำหนดใดๆ แต่ทำเช่นนั้นด้วยไวยากรณ์ที่เข้ากันไม่ได้ :
        • BSD ค้นหา: +
        • GNU ค้นหา: / [2]
      • ดังนั้นหลีกเลี่ยงส่วนขยายเหล่านี้หากโค้ดของคุณต้องพกพาได้
  • ตัวอย่างด้านล่างแสดงคำตอบแบบพกพาสำหรับคำถามต่างๆที่เน้นไฟล์เป็นศูนย์กลาง

ตัวอย่างคำสั่งไฟล์เป็นศูนย์กลาง

บันทึก:

  • ตัวอย่างต่อไปนี้เป็นไปตาม POSIXซึ่งหมายความว่าควรทำงานในการใช้งานที่เข้ากันได้กับ POSIX รวมถึง GNU find และ BSD find โดยเฉพาะสิ่งนี้ต้องการ:
    • ไม่ใช้คำนำหน้าโหมดที่ไม่เป็นมาตรฐาน+หรือ/.
    • การใช้รูปแบบ POSIX ของไพรมารีตัวดำเนินการเชิงตรรกะ :
      • !สำหรับ NOT (GNU find และ BSD find also allow -not); หมายเหตุที่\!ใช้ในตัวอย่างเพื่อป้องกัน!การขยายประวัติเชลล์
      • -aสำหรับ AND (GNU find และ BSD find also allow -and)
      • -oสำหรับ OR (GNU find และ BSD find also allow -or)
  • ตัวอย่างนี้ใช้โหมดสัญลักษณ์เนื่องจากอ่านและจำได้ง่ายกว่า
    • ด้วยคำนำหน้าโหมด-การ=และ+ผู้ประกอบการสามารถนำมาใช้แทนกันได้ (เช่น-u=xเทียบเท่ากับ-u+x- ถ้าคุณใช้-xในภายหลัง แต่มีจุดใดในการทำเช่นนั้น)
    • ใช้,เพื่อเข้าร่วมโหมดบางส่วน และตรรกะโดยนัย เช่น-u=x,g=xหมายความว่าต้องตั้งค่าทั้งผู้ใช้และบิตที่ปฏิบัติการได้ของกลุ่ม
    • โหมดไม่สามารถตัวเองแสดงการจับคู่เชิงลบในความหมายของ "การแข่งขันเฉพาะในกรณีที่บิตนี้ไม่ได้ตั้งค่า" นั้น คุณต้องใช้แยกแสดงออกด้วยไม่หลัก-perm!
  • โปรดสังเกตว่าไพรมารีของ find (เช่น-printหรือ-permเรียกอีกอย่างว่าการกระทำและการทดสอบใน GNU find) จะเชื่อมโยงกับ-a(ตรรกะ AND) โดยปริยาย-oและอาจจำเป็นต้องมีวงเล็บ (Escape as \(และ\)สำหรับเชลล์) เพื่อใช้หรือตรรกะ
  • find -L ...แทนที่จะfind ...ใช้เพื่อจับคู่symlinks กับไฟล์ปฏิบัติการ
    • -Lแนะนำให้ค้นหาเพื่อประเมินเป้าหมายของ symlinks แทนที่จะเป็น symlink เอง ดังนั้นโดยไม่-L, -type fจะไม่สนใจ symlinks ทั้งหมด
# Match files that have ALL executable bits set - for ALL 3 security
# principals (u (user), g (group), o (others)) and are therefore executable
# by *anyone*.
# This is the typical case, and applies to executables in _system_ locations
# (e.g., /bin) and user-installed executables in _shared_ locations
# (e.g., /usr/local/bin), for instance. 
find -L . -type f -perm -a=x  # -a=x is the same as -ugo=x

# The POSIX-compliant equivalent of `-perm +111` from the accepted answer:
# Match files that have ANY executable bit set.
# Note the need to group the permission tests using parentheses.
find -L . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \)

# A somewhat contrived example to demonstrate the use of a multi-principial
# mode (comma-separated clauses) and negation:
# Match files that have _both_ the user and group executable bit set, while
# also _not_ having the other executable bit set.
find -L . -type f -perm -u=x,g=x  \! -perm -o=x

[1] คำอธิบาย-executableจากman findณ GNU พบ 4.4.2:

จับคู่ไฟล์ที่เรียกใช้งานได้และไดเร็กทอรีที่สามารถค้นหาได้ (ในความหมายของการแก้ปัญหาชื่อไฟล์) สิ่งนี้คำนึงถึงรายการควบคุมการเข้าถึงและสิ่งประดิษฐ์การอนุญาตอื่น ๆ ซึ่งการทดสอบ -perm ละเว้น การทดสอบนี้ใช้การเรียกระบบ access (2) และเซิร์ฟเวอร์ NFS ที่ทำแผนที่ UID (หรือ root-squashing) สามารถหลอกได้เนื่องจากระบบจำนวนมากใช้การเข้าถึง (2) ในเคอร์เนลของไคลเอ็นต์ดังนั้นจึงไม่สามารถใช้ประโยชน์จาก ข้อมูลการแมป UID ที่เก็บไว้บนเซิร์ฟเวอร์ เนื่องจากการทดสอบนี้ขึ้นอยู่กับผลลัพธ์ของการเรียกระบบ access (2) เท่านั้นจึงไม่มีการรับประกันว่าไฟล์ที่การทดสอบนี้ประสบความสำเร็จจะสามารถดำเนินการได้จริง

[2] GNU พบเวอร์ชันที่เก่ากว่า 4.5.12ยังอนุญาตให้ใช้คำนำหน้า+แต่นี่เป็นครั้งแรกที่เลิกใช้งานและในที่สุดก็ถูกลบออกเนื่องจากการรวม+กับโหมดสัญลักษณ์จะให้ผลลัพธ์ที่ไม่คาดคิดเนื่องจากถูกตีความว่าเป็นมาสก์สิทธิ์ที่แน่นอน หากคุณ (ก) ทำงานในรุ่นก่อน 4.5.12 และ (ข) จำกัด ตัวเองให้ฐานแปดโหมดเท่านั้นคุณจะได้รับไปกับการใช้+กับทั้ง GNU ค้นหาและ BSD หา แต่ก็ไม่ได้เป็นความคิดที่ดี


2
คำตอบ SO ที่ครอบคลุมที่สุดเท่าที่เคยมีมา? ;)
andynormancx

@andynormancx :) ในแง่ของจำนวน bullet point ที่แท้จริงฉันสามารถเสนอคู่แข่งรายนี้ได้
mklement0

11

เพื่อให้มีความเป็นไปได้อื่น1ในการค้นหาไฟล์ที่เรียกใช้งานได้โดยผู้ใช้ปัจจุบัน:

find . -type f -exec test -x {} \; -print

(คำสั่งทดสอบที่นี่คือคำสั่งที่พบใน PATH ซึ่งเป็นไปได้มาก/usr/bin/testไม่ใช่ในตัว)


1ใช้สิ่งนี้เฉพาะในกรณีที่-executableธงของfindไม่พร้อมใช้งาน! สิ่งนี้แตกต่างจาก-perm +111โซลูชันอย่างละเอียด


2
วิธีนี้ใช้งานได้ แต่ค่อนข้างช้า นอกจากนี้ยังขึ้นอยู่กับเปลือกคุณอาจจะต้องตัดหรือหลบหนีเจ้าของสถานที่ชื่อไฟล์เหมือนหรือ'{}' \{\}
Ionoclast Brigham

1
@ mklement0 สิ่งนี้จะไม่พบคำสั่งที่ฉันสามารถเรียกใช้งานได้เช่น-executableทำหรือเหมือนกับคำสั่งของฉัน
gniourf_gniourf

1
ขอบคุณ @gniourf_gniourf - ฉันมีความเข้าใจผิดอยู่ที่นั่นจริงๆ ฉันพิมพ์ความคิดเห็นอื่น ๆ ของคุณที่นี่เพราะฉันอย่างน้อยตอนนี้ลบคำตอบของฉัน (บางทีอาจจะถูกให้ฟื้นคืนชีพถ้ามีบางสิ่งบางอย่างรอด): " find . -type f -perm -u=xจะไม่เทียบเท่าของ-executable: -executableตรงกับไฟล์ทั้งหมดที่ผู้ใช้สามารถดำเนินการและเหล่านี้รวมถึงg+xถ้าฉันอยู่ในกลุ่มที่เหมาะสมหรือo+xจริงๆแล้ว-perm -u=xจะพบไฟล์จำนวนมากที่ผู้ใช้ไม่สามารถเรียกใช้งานได้และพลาดบางส่วนที่ผู้ใช้สามารถดำเนินการได้ "
mklement0

1
@IonoclastBrigham: ในขณะที่การต้องเสนอราคา{}เป็นสิ่งจำเป็น (และการอ้างถึงไม่เจ็บ) ในทางปฏิบัติไม่จำเป็นในกระสุนแบบ POSIX และcsh. คุณรู้หรือเปลือกหอยซึ่งจะมีการถูกต้อง?
mklement0

4
@IonoclastBrigham: น่าสนใจขอบคุณ; ดังนั้นในfish, {}ต้องแน่นอนหนีเป็นอย่างใดอย่างหนึ่งหรือ'{}' \{\}โปรดทราบว่าbash, kshและzshให้ชนิดเดียวกันของการขยายตัวรั้ง; อย่างไรก็ตามพวกเขาพิมพ์โทเค็นที่ไม่ได้ใส่เครื่องหมายคำพูด{} ตามที่เป็นอยู่ (ดังนั้น: ไม่จำเป็นต้องหลบหนี) เนื่องจากไม่ถือว่าเป็นนิพจน์วงเล็บปีกกาที่ถูกต้อง (ต้องใช้อย่างน้อย2โทเค็นหรือนิพจน์ลำดับตัวเลขที่ถูกต้อง) ในขณะที่fish ถือว่า{}เป็นวงเล็บปีกกาที่ถูกต้องนิพจน์ที่ส่งผลให้สตริงว่าง
mklement0

9

คุณสามารถใช้-executableแฟล็กทดสอบ:

-executable
              Matches files which are executable  and  directories  which  are
              searchable  (in  a file name resolution sense).

4
-executable เป็นตัวเลือกที่ไม่รู้จัก
จริงๆแล้ว

4
นั่นจะเป็นส่วนขยาย GNU Find หรือไม่? เนื่องจากแท็กเป็น Unix ไม่ใช่ Linux อย่างน้อยที่สุดจึงต้องมีการจัดทำเป็นเอกสารส่วนขยาย GNU เช่นนี้
Jonathan Leffler

3
ตัวเลือกนี้ไม่ได้รับการสนับสนุนโดยคำสั่งค้นหา BSD ที่พบอย่างน้อยใน OS X นี่คือส่วนขยาย GNU แต่อาจได้รับการสนับสนุนโดยรสชาติอื่น ๆ ของการค้นหา
Ionoclast Brigham

FWIW ฉันพบว่าสิ่งนี้ไม่ได้อยู่ที่ sles 10 แต่เป็น sles> = 11 (ถูกไฟไหม้เล็กน้อย)
Peter Turner

โปรดทราบว่าสิ่งนี้ไม่ได้รับตัวอย่างทั้งหมด ในกรณีของฉันฉันมีไฟล์ที่ฉันเป็นเจ้าของ-rw-r-xr-xซึ่ง-executableตรวจไม่พบ
Dezza

2

สิ่งนี้ได้ผลสำหรับฉันและคิดจะแบ่งปัน ...

find ./ -type f -name "*" -not -name "*.o" -exec sh -c '
    case "$(head -n 1 "$1")" in
      ?ELF*) exit 0;;
      MZ*) exit 0;;
      #!*/ocamlrun*)exit0;;
    esac
exit 1
' sh {} \; -print

13
อีกหลายพันเคสเท่านั้นและคุณจะมีนวัตกรรมใหม่file!
tripleee

@tripleee +1. ส่วนขยายนี้ยอดเยี่ยม:find ./ -mime application/x-sharedlib -o -mime application/x-dosexec
Daniel Alder

@ แดเนียลอัลเดอร์เจอรุ่นไหนครับ? ฉันไม่พบตัวเลือก -mime in find (GNU findutils) 4.4.2
AjayKumarBasuthkar

@tripleee +1. การใช้ 'file' & / 'mimetype' เป็นความคิดที่ดีหรือค้นหาเวอร์ชันที่รองรับ -mime จะดีกว่านอกจากนี้ยังสงสัยว่า 'file' / 'mimetype' มีตัวเลือกในการกรองและแสดงเฉพาะไฟล์ปฏิบัติการหรือไม่
AjayKumarBasuthkar

2
find . -executable -type f

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

chmod a+x image.jpg

การค้นหาด้านบนจะคิดว่า image.jpg เป็นไฟล์ที่เรียกใช้งานได้แม้ว่ามันจะเป็นภาพ jpeg ที่มีชุดบิตการดำเนินการก็ตาม

โดยทั่วไปฉันจะแก้ไขปัญหานี้:

find . -type f -executable -exec file {} \; | grep -wE "executable|shared object|ELF|script|a\.out|ASCII text"

หากคุณต้องการให้ find พิมพ์ข้อมูลโดมเกี่ยวกับไฟล์ปฏิบัติการคุณสามารถทำสิ่งนี้ได้:

find . -type f -executable -printf "%i.%D %s %m %U %G %C@ %p" 2>/dev/null |while read LINE
do
  NAME=$(awk '{print $NF}' <<< $LINE)
  file -b $NAME |grep -qEw "executable|shared object|ELF|script|a\.out|ASCII text" && echo $LINE
done

ในตัวอย่างข้างต้นชื่อพา ธ เต็มของไฟล์จะอยู่ในช่องสุดท้ายและต้องแสดงตำแหน่งที่คุณค้นหาด้วย awk "NAME = $ (awk '{print $ NF}' <<< $ LINE)" หากชื่อไฟล์อยู่ที่อื่นใน ค้นหาสตริงเอาต์พุตที่คุณต้องแทนที่ "NF" ด้วยตำแหน่งตัวเลขที่ถูกต้อง หากตัวคั่นของคุณไม่ใช่ช่องว่างคุณต้องบอก awk ด้วยว่าตัวคั่นของคุณคืออะไร


1

มันจึงเป็นเรื่องไร้สาระที่ว่านี้ไม่ได้เป็นซุปเปอร์ง่าย ... ให้อยู่คนเดียวไปไม่ได้เลย ยกมือขึ้นฉันเลื่อนไปที่ Apple / Spotlight ...

mdfind 'kMDItemContentType=public.unix-executable'

อย่างน้อยก็ใช้ได้!


สิ่งที่ควรรู้เกี่ยวmdfindกับ OSX โปรดทราบว่าคำสั่ง uour รายงาน executables Unix สำหรับระบบทั้งหมด mdfind -onlyin . 'kMDItemContentType=public.unix-executable'จำกัด ผลลัพธ์ไว้ที่แผนผังย่อยของไดเร็กทอรีปัจจุบัน จุดสนใจเล็กน้อย: ไม่รองรับการ จำกัด การค้นหาเฉพาะไดเร็กทอรีเฉพาะ (โดยไม่มีโฟลเดอร์ย่อย) ดูเหมือนว่า Symlinksไปยังไฟล์ปฏิบัติการจะไม่รวมอยู่ด้วย อยากรู้อยากเห็นเมื่อmdfindพบไฟล์ที่สามารถเรียกใช้งานได้การลบบิตที่เรียกใช้งานได้ในภายหลังจะไม่ถูกหยิบขึ้นมา
mklement0

ฉันคิดว่าฉันพบข้อบกพร่องในการที่ Spotlight ตรวจจับ / ตรวจไม่พบไฟล์ Unix ที่ปฏิบัติการได้ ผมเคยยื่นข้อผิดพลาดกับแอปเปิ้ลและยังที่openradar.me/20162683 ฉันขอแนะนำให้คุณและใครก็ตามที่สนใจในฟังก์ชันนี้ - โปรดแจ้งข้อผิดพลาดที่bugreport.apple.com
mklement0

(ขออภัยสำหรับความคิดเห็นที่วุ่นวายหวังว่าตอนนี้จะถูกต้องแล้ว) mdfind -onlyin . 'kMDItemContentType=public.unix-executable'มีพฤติกรรมเหมือนfind . -type f -perm +111 -printทำ นั่นคือพบไฟล์ที่มีชุดบิตปฏิบัติการใด ๆซึ่งอาจให้ผลบวกเท็จ (แม้ว่าจะไม่เป็นปัญหาในทางปฏิบัติก็ตาม) - เพื่อค้นหาเฉพาะไฟล์ที่ปฏิบัติการได้โดยผู้ใช้ปัจจุบันที่ใช้ BSD find โปรดดูคำตอบของ @ gniourf_gniourf การfindใช้โซลูชันพื้นฐานมีข้อดีคือคุณสามารถค้นหาsymlinksไปยังไฟล์ปฏิบัติการได้เช่นกันหากต้องการ (ตัวเลือก-L) ซึ่งmdfindดูเหมือนจะไม่สามารถทำได้
mklement0

1
@ mklement0 คำตอบของฉันละทิ้งการปรุงแต่ง - เพื่อลองตอกกลับบ้าน - แต่ใช่คุณแทบจะไม่เคยใช้แบบฟอร์มนี้ "ไม่มีการปรุงแต่ง" เลย อีกทางเลือกหนึ่ง - ไม่แน่ใจว่ามันเกิดขึ้นมาหรือเปล่า- เป็นglobbing เก่า ๆ .. ls /Applications/**/*(*)ในzshเปลือก
Alex Gray

ขอบคุณสำหรับzshเคล็ดลับที่มีประโยชน์- ไม่รู้ว่า; (ดูเหมือนว่าคุณสามารถอย่างใดอย่างหนึ่งตรงกับ executables ( *) หรือ symlinks ( @) แต่ไม่ใช่ทั้งสองอย่างใช่มั้ย?) สำหรับประเด็นเดิมของคุณ: ขอย้ำ: find . -type f -perm +a=xจะทำในสิ่งที่mdfindคำสั่งของคุณทำในขณะที่ให้ความยืดหยุ่นมากขึ้น คุณยังสามารถจัดรูปแบบใหม่ให้สอดคล้องกับ POSIX
mklement0

1

คำตอบง่ายๆก็คือ "ไฟล์ปฏิบัติการของคุณอยู่ในไดเร็กทอรีที่มีอยู่ในตัวแปร PATH ของคุณ" แต่นั่นจะไม่พบไฟล์ปฏิบัติการของคุณและอาจพลาดไฟล์ปฏิบัติการจำนวนมากไปได้

ฉันไม่รู้เกี่ยวกับ mac มากนัก แต่ฉันคิดว่า "mdfind 'kMDItemContentType = public.unix-executable'" อาจพลาดสิ่งต่างๆเช่นสคริปต์ที่ตีความ

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

find . -type f -perm +111 -print

เมื่อได้รับการสนับสนุนตัวเลือก "-executable" จะสร้างตัวกรองเพิ่มเติมเพื่อดู acl และอาร์ติแฟกต์สิทธิ์อื่น ๆ แต่ในทางเทคนิคแล้วไม่แตกต่างจาก "-pemr +111" มากนัก

บางทีการค้นหาในอนาคตจะรองรับ "-magic" และให้คุณมองอย่างชัดเจนสำหรับไฟล์ที่มีรหัสเวทมนตร์ที่เฉพาะเจาะจง ... แต่คุณจะต้องระบุเพื่อปรับรหัสเวทย์มนตร์รูปแบบที่ปฏิบัติการได้ทั้งหมด

ฉันไม่รู้วิธีง่ายๆที่ถูกต้องในทางเทคนิคใน unix


1

ดังนั้นหากคุณต้องการค้นหาประเภทไฟล์ปฏิบัติการ (เช่นสคริปต์, ไบนารี ELF ฯลฯ .. ฯลฯ ) ไม่ใช่แค่ไฟล์ที่มีสิทธิ์ในการดำเนินการคุณอาจต้องการทำสิ่งนี้มากกว่านี้ (ซึ่งไดเรกทอรีปัจจุบันสามารถแทนที่ด้วยอะไรก็ได้ ไดเรกทอรีที่คุณต้องการ):

 gfind . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print

หรือสำหรับผู้ที่ไม่ได้ใช้ macports (ผู้ใช้ linux) หรือติดตั้ง gnu find ตามที่คุณต้องการ:

 find . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print

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


กฎที่แน่นอนสำหรับใบเสนอราคาที่นี่ค่อนข้างทึบดังนั้นฉันจึงจบลงด้วยการลองผิดลองถูก แต่ฉันชอบที่จะได้ยินคำอธิบายที่ถูกต้อง


0

ฉันมีปัญหาเดียวกันและคำตอบอยู่ในซอร์สโค้ด dmenu : ยูทิลิตี้ stest ที่สร้างขึ้นเพื่อจุดประสงค์นั้น คุณสามารถรวบรวมไฟล์ 'stest.c' และ 'arg.h' และมันควรจะใช้งานได้ มีหน้าคนสำหรับการใช้งานที่ฉันใส่ไว้เพื่อความสะดวก:

STEST(1)         General Commands Manual         STEST(1)

NAME
       stest - filter a list of files by properties

SYNOPSIS
       stest  [-abcdefghlpqrsuwx]  [-n  file]  [-o  file]
       [file...]

DESCRIPTION
       stest takes a list of files  and  filters  by  the
       files'  properties,  analogous  to test(1).  Files
       which pass all tests are printed to stdout. If  no
       files are given, stest reads files from stdin.

OPTIONS
       -a     Test hidden files.

       -b     Test that files are block specials.

       -c     Test that files are character specials.

       -d     Test that files are directories.

       -e     Test that files exist.

       -f     Test that files are regular files.

       -g     Test  that  files  have  their set-group-ID
              flag set.

       -h     Test that files are symbolic links.

       -l     Test the contents of a directory  given  as
              an argument.

       -n file
              Test that files are newer than file.

       -o file
              Test that files are older than file.

       -p     Test that files are named pipes.

       -q     No  files are printed, only the exit status
              is returned.

       -r     Test that files are readable.

       -s     Test that files are not empty.

       -u     Test that files have their set-user-ID flag
              set.

       -v     Invert  the  sense  of  tests, only failing
              files pass.

       -w     Test that files are writable.

       -x     Test that files are executable.

EXIT STATUS
       0      At least one file passed all tests.

       1      No files passed all tests.

       2      An error occurred.

SEE ALSO
       dmenu(1), test(1)

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