ฉันจะหาไฟล์ที่เรียกใช้งานได้ภายใต้ไดเรกทอรีเฉพาะใน Linux ได้อย่างไร


156

ฉันจะหาไฟล์ที่เรียกใช้งานได้ภายใต้ไดเรกทอรีเฉพาะใน Linux ได้อย่างไร


นี่คือสคริปต์ BASH ชนิดหนึ่งซึ่งไม่เลวเลยคือสิ่งที่ฉันสามารถพูดได้ :) stackoverflow.com/a/20209457/2067125
AjayKumarBasuthkar

สิ่งที่เกี่ยวกับการใช้fileคำสั่งมาตรฐาน?
Breakthrough

4
สำหรับทุกคนที่ต้องการทำสิ่งนี้บนMac (ทดสอบบน OS X 10.9.5): ls -l | egrep '^[^d]..x..x..x.*$' รายการด้านบนจะแสดงรายการสิ่งที่เรียกใช้งานได้ทั้งหมด (สำหรับผู้ใช้ทั้งหมดและกลุ่ม) ในไดเรกทอรีปัจจุบัน หมายเหตุ : -executableตัวเลือกไม่ทำงานบน Mac ดังนั้นวิธีแก้ปัญหาข้างต้น
techfoobar


1
@techfoobar: คำถามนี้คลุมเครือ: มันหมายถึงไฟล์ที่มีรหัสที่สามารถเรียกใช้งานได้หรือว่าหมายถึงไฟล์ที่มีสิทธิ์ในการเรียกใช้งานได้หรือไม่? แต่ถึงแม้ว่าเราคิดว่าได้รับอนุญาตปฏิบัติการคือสิ่งที่เป็นที่ต้องการ (เป็นส่วนใหญ่ของการตอบสนองที่ดูเหมือนจะ) คำถามที่ไม่ได้บอกว่าโลกที่ปฏิบัติการ โซลูชันของคุณจะค้นหาไฟล์ (และฟีเจอร์ซ็อกเก็ต symlink ฯลฯ ) ที่ได้รับอนุญาตจากทั่วโลก แต่ไม่ใช่ 750 ( -rwxr-x---) ซึ่งยังคงใช้งานได้สำหรับผู้ใช้บางคน
G-Man

คำตอบ:


157

การตรวจสอบไฟล์เรียกทำงานสามารถทำได้ด้วย-perm(ไม่แนะนำ) หรือ-executable(แนะนำเนื่องจากต้องคำนึงถึง ACL) วิธีใช้-executableตัวเลือก:

find <dir> -executable

หากคุณต้องการค้นหาไฟล์ที่เรียกใช้งานได้เท่านั้นและไม่ใช่ไดเรกทอรีที่ค้นหาได้รวมกับ-type f:

find <dir> -executable -type f

23
Shebang ไม่ได้หมายความว่าพวกเขาจะปฏิบัติได้ มันบอกเราเท่านั้นว่าล่ามที่จะใช้ และโดยความหมายลินุกซ์“ไฟล์ปฏิบัติการ” มีไฟล์ที่มีปฏิบัติการ (x) ตั้งค่าบิต
knittl

2
การค้นหารุ่นใดรองรับประเภทนั้นสำหรับ -type ผู้ชายค้นหารายการ b, c, d, p, f, l, s และ D ในระบบของฉัน
innaM

2
เช่นเดียวกันที่นี่การค้นหาของฉันไม่มี-type xทั้ง
davr

7
หากคุณมีรุ่นเก่าของการค้นหา (อาจก่อน 4.3.8) ซึ่งขาดการค้นหาที่ใช้งานได้ -perm / u = x, g = x, o = x
ลุดวิก Weinzierl

8
find: invalid predicate -executable'ใน RHEL
SSH

33

ใช้-permตัวเลือกของ find นี่จะค้นหาไฟล์ในไดเรกทอรีปัจจุบันที่สามารถเรียกใช้งานได้โดยเจ้าของโดยสมาชิกกลุ่มหรือคนอื่น ๆ :

find . -perm /u=x,g=x,o=x

แก้ไข:

ฉันเพิ่งพบตัวเลือกอื่นที่มีอยู่อย่างน้อยใน GNU พบ 4.4.0:

find . -executable

สิ่งนี้จะทำงานได้ดียิ่งขึ้นเนื่องจาก ACL ได้รับการพิจารณาด้วย


2
สิ่งนี้ใช้ได้กับการค้นหารุ่นที่ใหม่กว่าเท่านั้น สิ่งที่มาโดยค่าเริ่มต้นกับ CentOS ให้ข้อผิดพลาดfind: invalid mode / u = x, g = x, o = x'`
davr

12
จากนั้นคุณควรลองรุ่น "-perm +" ซึ่งเลิกใช้แล้วใน GNU find: find -perm +111 "
innaM

ดูเหมือนว่า-perm /111อาจเป็นรุ่นพกพามากที่สุด
สกอตต์

12

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

ทดสอบบนmacOS 10.12.5

find . -perm +111 -type f

1
ทำงานใน RHEL 5 ด้วย
JoséTomás Tocino

นี่เป็นตัวแปรเดียวที่ฉันสามารถใช้กับ OS X 10.14, ขอบคุณ
Justin

3

ฉันมีวิธีอื่นในกรณีที่สิ่งที่คุณต้องการคือการทำอะไรกับไฟล์ที่ปฏิบัติการได้และไม่จำเป็นต้องบังคับให้ค้นหาเพื่อกรองตัวเอง:

for i in `find -type f`; do [ -x $i ] && echo "$i is executable"; done

ฉันชอบสิ่งนี้เพราะไม่ขึ้นอยู่กับ-executableว่าเป็นแพลตฟอร์มใด และมันไม่ได้ขึ้นอยู่กับ-permว่าเป็นบิต arcane ซึ่งเป็นแพลตฟอร์มเฉพาะบิตและตามที่เขียนไว้ข้างต้นต้องการไฟล์ที่สามารถเรียกใช้งานได้สำหรับทุกคน (ไม่ใช่แค่คุณ)

-type fเป็นสิ่งสำคัญเพราะในไดเรกทอรี * ระวังจะต้องมีการปฏิบัติการที่จะเดินข้าม, และอื่น ๆ ของแบบสอบถามที่อยู่ในfindคำสั่งหน่วยความจำมีประสิทธิภาพมากขึ้นคำสั่งของคุณจะ

อย่างไรก็ตามเพียงเสนอวิธีอื่นเนื่องจาก * ระวังคือดินแดนแห่งแนวทางนับพันล้าน


(0) คุณชอบแบบไหนความลับและถูกต้องหรือใช้งานง่ายและมีข้อบกพร่อง? ฉันชอบที่ถูกต้อง (1)  คำตอบ innaM ของเนื้อเรื่องfind -permพบแฟ้มที่มีใด ๆดำเนินการชุดบิตได้รับอนุญาต (2) ตรงกันข้ามคำตอบนี้จะค้นหาเฉพาะไฟล์ที่ผู้ใช้ปัจจุบันได้รับอนุญาตให้ใช้ จริงอยู่นั่นอาจเป็นสิ่งที่ OP ต้องการ แต่ก็ไม่ชัดเจน ... (ต่อ)
สกอตต์

(ต่อ) ... (3) เพื่อความชัดเจนคุณอาจต้องการที่จะเปลี่ยน`…`ไป$(…)- เห็นนี้ , นี้และนี้ (4) แต่ไม่ได้ทำfor i in $(find …); do …; มันล้มเหลวในชื่อไฟล์ที่มีช่องว่าง find … -exec …แต่จะทำอย่างไร (5) และเมื่อคุณทำงานกับตัวแปรเชลล์ให้อ้างอิงพวกเขาเสมอ (ในเครื่องหมายคำพูดคู่) เว้นแต่คุณจะมีเหตุผลที่ดีที่จะไม่ทำและคุณแน่ใจว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่
สกอตต์

@ สกอตต์ตกลงฉันยืนแก้ไข :) ฉันอ่าน-permข้อโต้แย้งที่ต้องการทั้งสามไม่ใช่หนึ่งในนั้น นอกจากนี้ขอขอบคุณสำหรับข้อมูลในการปกป้องอาร์กิวเมนต์ของเชลล์นั่นคือทั้งหมดที่ฉันไม่ทราบ
Mark McKenna

@MarkMcKenna คุณมีการพิมพ์ผิดในนั้น: for i in ค้นหา - ประเภท f ; do [ -x $i ] && echo "$i is executable"; done; คุณไม่มีส่วน <dir> ซึ่งฉันใช้จุด (.)
Devy

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

2
สิ่งนี้ทำอะไร
DerMike

@DerMike เป็นวิธีหนึ่งในการค้นหาไฟล์ที่เรียกใช้งานได้ในไดเรกทอรีปัจจุบันรวมถึงไฟล์. so แม้ว่าไฟล์จะไม่ถูกทำเครื่องหมายว่าสามารถเรียกใช้งานได้ก็ตาม
AjayKumarBasuthkar

ฉันหมายความว่าทำยังไงดี?
DerMike

มันอ่านจากส่วนหัวของไฟล์ที่จะค้นพบทุกไฟล์ไบนารีหรือไฟล์สคริปต์มีส่วนหัว
AjayKumarBasuthkar

เท่าที่ฉันรู้-name "*"ไม่มีผลในfind- ปกติจะพบไฟล์ทั้งหมดที่ไม่ได้ถูกกำจัดโดยการทดสอบ
G-Man

1

ในฐานะที่เป็นแฟนตัวยงของสายการบินเดียว ...

find /usr/bin -executable -type f -print0 | xargs file | grep ASCII

การใช้ 'xargs' เพื่อรับเอาต์พุตจากคำสั่ง find (ใช้ print0 เพื่อให้แน่ใจว่ามีการจัดการชื่อไฟล์ที่มีช่องว่างอย่างถูกต้อง) ตอนนี้เรามีรายการไฟล์ที่สามารถเรียกใช้งานได้และเราให้ไฟล์เหล่านี้ทีละไฟล์เป็นพารามิเตอร์สำหรับคำสั่ง 'ไฟล์' จากนั้น grep สำหรับคำว่า ASCII เพื่อละเว้นไบนารี โปรดแทนที่ - ปฏิบัติการในคำสั่ง find ด้วยสไตล์ที่คุณต้องการ (ดูคำตอบก่อนหน้า) หรือสิ่งที่ใช้ได้กับ 'NIX OS ของคุณ

ฉันต้องการข้างต้นเพื่อค้นหาไฟล์ที่มี eval ในสคริปต์ที่เป็นของ root ดังนั้นสร้างรายการต่อไปนี้เพื่อช่วยค้นหาจุดอ่อนการเพิ่มระดับความลับที่ผู้ใช้รูทใช้งานสคริปต์ด้วยพารามิเตอร์ที่ไม่ปลอดภัย ...

echo -n "+ Identifying script files owned by root that execute and have an eval in them..."
find /  -not \( -path /proc -prune \)  -type f -executable -user root -exec grep -l eval {} \; -exec file {} \; | grep ASCII| cut -d ':' -f1 > $outputDir"/root_owned_scripts_with_eval.out" 2>/dev/null &

สิ่งนี้จะไม่ทำงานหากสคริปต์มีอักขระที่ไม่ใช่ ASCII รายงานการเข้ารหัสเพื่อให้สคริปต์หลามสามารถรายงานว่า file สามารถทำงานได้ดีขึ้นในการตรวจจับผู้ที่ไม่ใช่ไบนารี a /usr/bin/python script, UTF-8 Unicode text executablefind ... | xargs file -b | grep -v '^ELF'
xenoid

0

ฉันสร้างฟังก์ชั่นใน~/.bashrcคืนนี้เพื่อค้นหาไฟล์ปฏิบัติการที่ไม่ได้อยู่ในเส้นทางของระบบและไม่ใช่ไดเรกทอรี:

# Quickly locate executables not in the path
xlocate () {
    locate -0r "$1" | xargs -0 -I{} bash -c '[[ -x "$1" ]] && [[ ! -d "$1" ]] \
        &&  echo "executable: $1"'  _  {}
} # xlocate ()

ข้อดีคือมันจะค้นหา Linux distros สามตัวและการติดตั้ง Windows ภายในfindไม่กี่วินาทีโดยที่คำสั่งใช้เวลา 15 นาที

ตัวอย่างเช่น:

$ time xlocate llocate
executable: /bin/ntfsfallocate
executable: /home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/bin/ntfsfallocate
executable: /mnt/clone/home/rick/restore/mnt/e/bin/llocate
executable: /mnt/clone/usr/bin/fallocate
executable: /mnt/e/bin/llocate
executable: /mnt/old/bin/ntfsfallocate
executable: /mnt/old/usr/bin/fallocate
executable: /usr/bin/fallocate

real    0m0.504s
user    0m0.487s
sys     0m0.018s

หรือสำหรับไดเรกทอรีทั้งหมดและทั้งหมดคือหมวดย่อย:

$ time xlocate /mnt/e/usr/local/bin/ | wc -l
65

real    0m0.741s
user    0m0.705s
sys     0m0.032s
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.