it-swarm-vi.com

Liệt kê các tập tin được truy cập bởi một chương trình

time là một lệnh tuyệt vời nếu bạn muốn tìm ra thời gian CPU mà một lệnh đã cho mất bao nhiêu thời gian.

Tôi đang tìm kiếm một cái gì đó tương tự có thể liệt kê các tập tin được truy cập bởi một chương trình và con của nó. Hoặc trong thời gian thực hoặc như một báo cáo sau đó.

Hiện tại tôi đang sử dụng:

#!/bin/bash

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

nhưng nó không thành công nếu lệnh chạy liên quan đến Sudo. Nó không thông minh lắm (sẽ rất tuyệt nếu nó chỉ có thể liệt kê các tệp hiện có hoặc có vấn đề về quyền hoặc nhóm chúng thành các tệp được đọc và các tệp được ghi). Ngoài ra strace là chậm, vì vậy nó sẽ tốt với sự lựa chọn nhanh hơn.

65
Ole Tange

Tôi đã từ bỏ và mã hóa công cụ của riêng tôi. Để trích dẫn từ các tài liệu của nó:

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

Nó chỉ xuất ra các tệp để bạn không cần phải xử lý đầu ra từ strace.

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

56
Ole Tange

Bạn có thể theo dõi các cuộc gọi hệ thống bằng strace, nhưng thực sự có một hình phạt tốc độ không thể tránh khỏi. Bạn cần chạy strace với quyền root nếu lệnh chạy với các đặc quyền nâng cao:

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

Một phương pháp khác có khả năng nhanh hơn là tải trước một thư viện bao quanh các chức năng truy cập hệ thống tập tin: LD_PRELOAD=/path/to/libmywrapper.so mycommand. Các LD_PRELOAD biến môi trường sẽ không được chuyển đến các chương trình được gọi với các đặc quyền nâng cao. Bạn sẽ phải viết mã của thư viện trình bao bọc đó ( đây là một ví dụ từ các bộ chuyển đổi thư viện của Tòa nhà để giải trí và kiếm lợi nhuận ); Tôi không biết nếu có mã tái sử dụng có sẵn trên web.

Nếu bạn đang theo dõi các tệp trong một hệ thống phân cấp thư mục cụ thể, bạn có thể tạo chế độ xem hệ thống tệp với LoggedFS sao cho tất cả các truy cập thông qua chế độ xem đó được ghi lại.

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

Để định cấu hình LoggedFS, hãy bắt đầu với cấu hình mẫu được gửi cùng với chương trình và đọc Cú pháp tệp cấu hình LoggedFS .

Một khả năng khác là Linux's hệ thống con kiểm toán . Đảm bảo auditd daemon được khởi động, sau đó định cấu hình những gì bạn muốn đăng nhập với auditctl . Mỗi thao tác được ghi lại được ghi lại trong /var/log/audit/audit.log (trên các bản phân phối điển hình). Để bắt đầu xem một tập tin cụ thể:

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

Nếu bạn đặt đồng hồ trên một thư mục, các tệp trong đó và các thư mục con của nó sẽ được xem theo cách đệ quy. Cẩn thận không xem thư mục chứa nhật ký kiểm toán. Bạn có thể hạn chế đăng nhập vào một số quy trình nhất định, xem trang man auditctl để biết các bộ lọc có sẵn. Bạn cần phải root để sử dụng hệ thống kiểm toán.

Tôi nghĩ rằng bạn muốn lsof (có thể được dẫn đến một grep trên chương trình và đó là trẻ em). Nó sẽ cho bạn biết mọi tập tin hiện đang được truy cập trên hệ thống tập tin. Để biết thông tin về các tệp được truy cập theo quy trình ( từ đây ):

lsof -n -p `pidof your_app`
7
unclejamil

Tôi đã thử tracefile. Đối với tôi, nó đã cho ít trận đấu hơn nhiều so với strace ... | sed ... | sort -u Của riêng tôi. Tôi thậm chí đã thêm -s256 Vào dòng lệnh strace(1) nhưng nó không giúp được gì nhiều ...

Sau đó, tôi đã thử loggedfs. Đầu tiên nó thất bại vì tôi không có quyền truy cập đọc/ghi vào thư mục mà tôi đã cố gắng đăng nhập với nó. Sau khi thực hiện chmod 755 tạm thời tôi đã nhận được một số lượt truy cập ...

Nhưng, đối với tôi, làm như sau có vẻ hiệu quả nhất:

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

Và sau đó xử lý đầu ra sau khi chạy quá trình quan tâm.

Điều này không bắt được các tập tin truy cập bên ngoài của thư mục theo dõi cũng không biết liệu một số quy trình khác có truy cập cùng một cây thư mục hay không, nhưng trong nhiều trường hợp, đây là công cụ đủ tốt để có được công việc làm xong.

EDIT: inotifywait không bắt được quyền truy cập symlink (chỉ các mục tiêu sau khi symlink được giải quyết). Tôi đã bị ảnh hưởng bởi điều này khi tôi lưu trữ các thư viện được truy cập bởi một chương trình để sử dụng trong tương lai. Đã sử dụng một số hack toàn cầu Perl bổ sung để chọn các liên kết tượng trưng dọc theo các thư viện được thông báo để hoàn thành công việc trong một trường hợp cụ thể đó.

EDIT2: ít nhất là khi tự kích hoạt các tệp và liên kết tượng trưng từ dòng lệnh inotifywait (ví dụ: inotifywait -m file symlink Hoặc inotifywait symlink file) Sẽ hiển thị quyền truy cập vào cái đầu tiên trong dòng lệnh (bất kể đó là file trong số symlink được truy cập). inotifywait không hỗ trợ IN_DONT_FOLLOW - điều mà khi tôi thử lập trình chỉ khiến người ta thấy quyền truy cập vào file (có thể, hoặc có thể, không phải là điều người ta mong đợi ...) bất kể thứ tự trong dòng lệnh

2
Tomi Ollila

Mặc dù nó có thể không cung cấp cho bạn đủ quyền kiểm soát (chưa?) . So với strace, nó khá nhanh (;

Nó có thể được tìm thấy trên https://github.com/tycho-kirchner/shournal

Ví dụ về Shell:

$ 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    
1
spawn