รายการไฟล์ที่เข้าถึงโดยโปรแกรม


64

time เป็นคำสั่งที่ยอดเยี่ยมถ้าคุณต้องการที่จะคำนวณเวลาของ CPU ที่คำสั่งที่ได้รับ

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

ปัจจุบันฉันใช้:

#!/bin/bash

strace -ff -e trace=file "$@" 2>&1 | perl -ne 's/^[^"]+"(([^\\"]|\\[\\"nt])*)".*/$1/ && print'

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


เมื่อพิจารณาถึงการใช้งานของstraceคุณฉันถือว่าคุณสนใจ Linux เป็นพิเศษ แก้ไข?
Gilles

Linux เป็นข้อกังวลหลักของฉัน
Ole Tange

คำตอบ:


51

ฉันเลิกและเขียนโค้ดเครื่องมือของตัวเอง หากต้องการอ้างอิงจากเอกสาร:

SYNOPSIS
    tracefile [-adefnu] command
    tracefile [-adefnu] -p pid

OPTIONS
    -a        List all files
    -d        List only dirs
    -e        List only existing files
    -f        List only files
    -n        List only non-existing files
    -p pid    Trace process id
    -u        List only files once

straceมันก็แค่เอาท์พุทไฟล์เพื่อให้คุณไม่จำเป็นต้องจัดการกับการส่งออกจาก

https://gitlab.com/ole.tange/tangetools/tree/master/tracefile


ขอบคุณ! เอาต์พุตของ strace นั้นไม่สามารถอ่านได้อย่างแน่นอน ฉันไม่รู้ว่าจะหาเอกสารได้ที่ไหน - มันจะดีถ้ามีตัวเลือกความช่วยเหลือ -h / - ฉันขอขอบคุณตัวเลือกที่แสดงเฉพาะการแก้ไขไฟล์ไม่ใช่การเข้าถึง
Xerus

@Xerus โคลนgitlab.com/ole.tange/tangetoolsmake && sudo make installและเรียกใช้ man tracefileจากนั้นคุณสามารถเรียกใช้
Ole Tange

4
เครื่องมือที่ดี บรรจุมันเพื่อติดตั้ง: yum -y install https://extras.getpagespeed.com/release-el7-latest.rpmและyum -y install tracefile
Danila Vershinin

27

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

sudo strace -f -o foo.trace su user -c 'mycommand'

อีกวิธีที่น่าจะเร็วกว่าคือโหลดไลบรารีที่ล้อมรอบฟังก์ชันการเข้าถึงระบบไฟล์LD_PRELOAD=/path/to/libmywrapper.so mycommandไว้ล่วงหน้า LD_PRELOADตัวแปรสภาพแวดล้อมจะไม่ถูกส่งผ่านไปยังโปรแกรมเรียกด้วยการยกระดับสิทธิ์ คุณต้องเขียนโค้ดไลบรารีของ wrapper นั้น ( นี่คือตัวอย่างจาก“ การสร้างตัวคั่นของไลบรารีเพื่อความสนุกและผลกำไร” ) ฉันไม่รู้ว่ามีรหัสที่ใช้ซ้ำได้บนเว็บหรือไม่

หากคุณกำลังตรวจสอบไฟล์ในลำดับชั้นไดเรกทอรีเฉพาะคุณสามารถสร้างมุมมองของระบบไฟล์ด้วยLoggedFSเพื่อให้การเข้าถึงทั้งหมดผ่านมุมมองนั้นถูกบันทึก

loggedfs -c my-loggedfs.xml /logged-view
mycommand /logged-view/somedir

การกำหนดค่า LoggedFS เริ่มต้นด้วยการกำหนดค่าตัวอย่างที่ให้มาพร้อมกับโปรแกรมและอ่านLoggedFS ไวยากรณ์แฟ้มการกำหนดค่า

เป็นไปได้ก็คือลินุกซ์ระบบย่อยการตรวจสอบ ตรวจสอบให้แน่ใจภูตจะเริ่มต้นจากนั้นกำหนดสิ่งที่คุณต้องการเข้าสู่ระบบด้วยauditd auditctlการดำเนินการที่บันทึกไว้แต่ละครั้งจะถูกบันทึกเป็น/var/log/audit/audit.log(ในการแจกแจงทั่วไป) วิธีเริ่มดูไฟล์โดยเฉพาะ:

auditctl -a exit,always -w /path/to/file

หากคุณวางการเฝ้าดูในไดเรกทอรีไฟล์ในนั้นและไดเรกทอรีย่อยจะถูกเรียกซ้ำด้วยเช่นกัน ระวังอย่าดูไดเรกทอรีที่มีบันทึกการตรวจสอบ คุณสามารถ จำกัด การเข้าสู่กระบวนการบางอย่างดูauditctlหน้า man สำหรับตัวกรองที่มี คุณต้องเป็นรูทเพื่อใช้ระบบการตรวจสอบ


LD_PRELOADจะไม่ทำงานกับไบนารีแบบคงที่
เดวิดให้

6

ฉันคิดว่าคุณต้องการ lsof (อาจเป็นไปตาม grep ในโปรแกรมและเป็นเด็ก ๆ ) มันจะบอกคุณทุกไฟล์ที่กำลังถูกเข้าถึงบนระบบไฟล์ สำหรับข้อมูลเกี่ยวกับไฟล์ที่เข้าถึงได้โดยกระบวนการ ( จากที่นี่ ):

lsof -n -p `pidof your_app`

11
แต่มันเป็นเพียงแค่ภาพรวม สิ่งที่ฉันต้องการคือไฟล์ที่พยายามเข้าถึง คิดว่าสถานการณ์ที่โปรแกรมปฏิเสธที่จะเริ่มเพราะมันบอกว่า "ไฟล์ที่หายไป" ฉันจะค้นหาไฟล์ที่ต้องการได้อย่างไร?
Ole Tange

2

ฉันลองtracefileมัน สำหรับฉันมันให้แมตช์น้อยกว่าของฉันstrace ... | sed ... | sort -uมาก ฉันเพิ่มลง-s256ในstrace(1)command line แล้ว แต่ก็ไม่ได้ช่วยอะไรมาก ...

จากนั้นฉันก็ลองloggedfsมัน ครั้งแรกมันล้มเหลวเนื่องจากฉันไม่ได้อ่าน / เขียนการเข้าถึงไดเรกทอรีฉันพยายามเข้าสู่ระบบด้วย หลังจากทำchmod 755ชั่วคราวฉันได้รับความนิยม ...

แต่สำหรับฉันการทำสิ่งต่อไปนี้ดูเหมือนว่าจะทำงานได้ดีที่สุด:

inotifywait -m -r -e OPEN /path/to/traced/directory

จากนั้นประมวลผลผลลัพธ์หลังจากประมวลผลดอกเบี้ย

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

แก้ไข: inotifywait ไม่ได้รับการเข้าถึง symlink (เพียงแค่เป้าหมายหลังจากแก้ไข symlink แล้ว) ฉันโดนสิ่งนี้เมื่อฉันเก็บถาวรไลบรารีที่เข้าถึงได้โดยโปรแกรมสำหรับใช้ในอนาคต ใช้การแฮ็กโกล perl แบบพิเศษบางอย่างเพื่อเลือก symlink ตามไลบรารี่ที่ได้รับการแจ้งเตือนเพื่อให้งานเสร็จในกรณีนั้น

EDIT2: อย่างน้อยเมื่อ inotifying ไฟล์และ symlinks ตัวเองจากบรรทัดคำสั่ง inotifywait (เช่นinotifywait -m file symlinkหรือinotifywait symlink file) เอาท์พุทจะแสดงการเข้าถึงที่หนึ่งเป็นครั้งแรกในบรรทัดคำสั่ง (ไม่ซึ่งfileการsymlinkที่มีการเข้าถึง) inotifywait ไม่รองรับ IN_DONT_FOLLOW - ซึ่งเมื่อฉันลองใช้โดยทางโปรแกรมทำให้ผู้ใช้เห็นการเข้าถึงfile(ซึ่งอาจหรืออาจจะไม่เป็นสิ่งที่คาดหวัง ... ) โดยไม่คำนึงถึงลำดับในบรรทัดคำสั่ง


"สำหรับฉันมันมีการจับคู่น้อยกว่าของฉันมาก" คุณสามารถแชร์ตัวอย่างของการtracefileขาดการเข้าถึงไฟล์ได้หรือไม่?
Ole Tange

ฉันไม่แน่ใจว่าสิ่งที่คุณถามว่า:) ... ถ้าฉันพยายามดูไฟล์ภายใน / path / to / traced / directory / ฉันเห็นเปิดใน inotify output ... แต่สถิติ (1) ing ไฟล์ที่ฉันดูเหมือน ที่จะได้รับผลไม่ในบางกรณีที่ฉันพยายาม (ผมสงสัยว่าทำไมมีเนื้อหาบางไดเรกทอรีแคชหลบซ่อนตัวที่อ่านจากมุมมอง)
โทมิ Ollila

ฉันแสดงความคิดเห็นในการโพสต์ fanotify ด้านล่าง (ฉันมีชื่อเสียงเพียง 21 แม้ว่าฉันมีบัญชีมานานกว่าทศวรรษที่ต้อง 50 สำหรับการแสดงความคิดเห็นมักจะเป็นอุปสรรคสำหรับฉัน ... ) - fanotify เป็นสิ่งที่ดี แต่ไม่สามารถ ไปรอบ ๆ ปัญหา dereference symlink (เช่นในกรณีของ symlink ไฟล์สุดท้ายที่เข้าถึงได้โดยการอ่าน / proc / self / fd / <fd> .. ต่อไป +1: ตอบคำตอบ: D
Tomi Ollila

1

ในขณะที่มันอาจให้การควบคุมไม่เพียงพอ (ยัง?) ฉันได้เขียนโปรแกรมซึ่งอย่างน้อยก็ตอบสนองความต้องการของคุณได้บางส่วนโดยใช้ fanotify ของ linux-kernel และไม่แชร์เพื่อตรวจสอบเฉพาะไฟล์ที่แก้ไข (หรืออ่าน) โดยกระบวนการเฉพาะและลูก ๆ . เมื่อเทียบกับ strace มันค่อนข้างเร็ว (;

สามารถดูได้ที่ https://github.com/tycho-kirchner/shournal

ตัวอย่างบนเปลือก:

$ shournal -e sh -c 'echo hi > foo1; echo hi2 > foo2'
$ shournal -q --history 1
  # ...
  Written file(s):                                                                                                                                                                              
 /tmp/foo1 (3 bytes) Hash: 15349503233279147316                                                                                                                                             
 /tmp/foo2 (4 bytes) Hash: 2770363686119514911    
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.