Giới thiệu về lsof Trong Linux, nhiều đối tượng được coi là một tập tin, bất kể đối tượng thực sự là một tập tin, thiết bị, thư mục hoặc socket. Liệt kê một tập tin rất dễ dàng, lệnh ls sẽ làm được điều đó. Nhưng nếu một người dùng muốn xem các tập tin đang được mở bởi tiến trình nào của máy chủ web? Hoặc nếu người dùng muốn tìm hiểu các tập tin được mở ra trong một thư mục nào đó? Đó là nơi mà lệnh lsof được sử dụng. Hãy tưởng tượng lsof như một ls với việc bổ sung "opened file". Đầu tiên, chúng ta hãy nhìn vào kết quả đầu ra của lsof đã được rút ngắn:. Mã: COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root cwd DIR 254,1 4096 2 / init 1 root rtd DIR 254,1 4096 2 / init 1 root txt REG 254,1 36992 7077928 /sbin/init init 1 root mem REG 254,1 14768 7340043 /lib/x86_64-linux-gnu/libdl-2.13.so init 1 root mem REG 254,1 1603600 7340040 /lib/x86_64-linux-gnu/libc-2.13.so init 1 root mem REG 254,1 126232 7340078 /lib/x86_64-linux-gnu/libselinux.so.1 init 1 root mem REG 254,1 261184 7340083 /lib/x86_64-linux-gnu/libsepol.so.1 init 1 root mem REG 254,1 136936 7340037 /lib/x86_64-linux-gnu/ld-2.13.so init 1 root 10u FIFO 0,14 0t0 4781 /run/initctl Ý nghĩa các cột như sau: COMMAND – Thể hiện tiến trình mà tập tin đang mở thuộc về, trong ví dụ này tất cả mọi thứ liên quan đến init. PID – Số nhận dạng tiến trinh nói trên. USER – User quản lý tiến trình đang chạy. Đối với init, nó gần như luôn luôn root. FD – Các mô tả tập tin: cwd - Thư mục làm việc hiện tại (bạn có thể nhận thấy sự giống nhau với lệnh pwd dùng để xuất ra thư mục làm việc hiện tại). rtd - Thư mục root của một quá trình. txt - Một tập tin văn bản, điều này có thể là một tập tin cấu hình liên quan đến tiến trình hoặc các "mã nguồn" liên quan đến (hoặc thuộc về) tiến trình. mem - Một cái gọi là "bộ nhớ ánh xạ tập tin (memory mapped file)", có nghĩa là một phân đoạn của bộ nhớ ảo (read: RAM) đã được chỉ định cho một tập tin. Một số (10u) - số đại diện mô tả tập tin thực tế, các kí tự sau số là chế độ mà trong đó các tập tin được mở ra (r -Đọc, w- Viết, u - Đọc và viết) TYPE - Chỉ định các loại thực tế của tập tin, phổ biến nhất là: REG - Một tập tin thường xuyên. DIR - Một thư mục. FIFO - First in, first out. DEVICE - Số lượng lớn và nhỏ của thiết bị chứa tập tin. SIZE - Kích thước của tập tin, đơn vị byte. NODE - Số inode của tập tin. NAME - Tên của tập tin. Như đã đề cập ở trên, kết quả đầu ra của lsof đã được rút ngắn ở đây. Nếu không có bất kỳ đối số hoặc bộ lọc, lsof sẽ hiển thị hàng trăm dòng dữ liệu sẽ chỉ khiến bạn bối rối. Có hai phương pháp cơ bản để giải quyết vấn đề: Sử dụng một hoặc nhiều tùy chọn lsof để thu hẹp kết quả. Pipe kết quả đầu ra, ví dụ, grep. Trong khi lựa chọn thứ hai có vẻ thoải mái hơn vì bạn sẽ không cần phải nhớ các tùy chọn dòng lệnh lsof, tuy nhiên nó thường không được linh hoạt và hiệu quả, vì vậy chúng tôi sẽ sử dụng phương pháp đầu tiên. Hãy tưởng tượng rằng bạn muốn mở một tập tin với trình soạn thảo văn bản yêu thích của bạn, và trình soạn thảo văn bản cho bạn biết rằng nó chỉ có thể được mở ra ở chế độ chỉ đọc vì chương trình khác đang truy cập vào nó. lsof sẽ giúp bạn tìm ra ai là thủ phạm: Mã: lsof /path/to/your/file Điều này sẽ tạo ra một kết quả đầu ra tương tự như sau: Mã: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME vim 2679 root 5w REG 254,1 121525 6035622 /root/lsof.txt Rõ ràng, bạn quên đóng phiên làm việc cũ! Một vấn đề rất tương tự sẽ xảy ra khi bạn cố gắng để unmount một chia sẻ NFS và umount nói với bạn nó không thể bởi vì có một cái gì đó vẫn còn truy cập vào thư mục gắn kết. Một lần nữa, lsof có thể giúp bạn với việc xác định thủ phạm: Mã: lsof +D /path/to/your/directory/ Chú ý các dấu gạch chéo, rất là quan trọng. Nếu không lsof sẽ cho rằng đó là một tập tin thường xuyên chứ không phải thư mục. Kết quả đầu ra sẽ trông như thế này: Mã: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mocp 5637 music 4r REG 0,19 10147719 102367344 /home/Music/RMS_GNU_SONG.ogg Điều đó có nghĩa rằng quá trình mocp, với PID 5637, thuộc user music đã mở ra một tập tin gọi là RMS_GNU_SONG.ogg. Tuy nhiên, ngay sau khi đóng tiến trình đó, vẫn còn là một vấn đề - khối (volume) NFS không thể được unmounted. lsof có một tùy chọn -c hiển thị các tập tin sử dụng bởi một tiến trình tùy ý. Mã: lsof -c mocp Điều này sẽ tạo ra một kết quả đầu ra tương tự như sau: Mã: mocp 9383 music 4r REG 0,19 10147719 102367344 /home/Music/ANOTHER_RMS_GNU_SONG.ogg Trong ví dụ này, còn có một instance của mocp đang chạy, ngăn cản bạn unmount chia sẻ NFS. Sau khi đã tắt quá trình đó, bạn muốn chắc chắn rằng user music không có các tập tin khác đang được mở. lsof có một lá cờ -u cho hiển thị các tập tin được mở bởi một user cụ thể. Mã: lsof -u music Bạn cũng có thể chọn nhiều user, cách nhau bằng dấu phẩy: Mã: lsof -u music,moremusic Nếu bạn muốn xem các kết quả phù hợp các tiến trình mà được sở hữu bởi cả hai user trên, bạn sử dụng tùy chọn -a: Mã: lsof -au music, moremusic Kể từ khi cả hai người dùng đang ở trong nhóm musicusers, sau đó bạn cũng có thể liệt kê các tập tin dựa trên nhóm: Mã: lsof -g musicusers Bạn cũng có thể kết hợp các lệnh như sau: Mã: lsof -u music,moremusic -c mocp or lsof -u ^music +D /home/Music Trong dòng cuối cùng, chúng tôi đã thêm một tùy chọn đặc biệt ^, đó là viết tắt cho một logic NOT. Nếu đầu ra là trống rỗng sau khi chạy lệnh đó, thì unmount sẽ rất có thể thành công. Trong ví dụ trước, chúng tôi chủ yếu tập trung vào tập tin thông thường. Bây giờ chúng ta hãy tìm hiểu về các socket và kết nối mạng. Để liệt kê tất cả các kết nối mạng hiện có sử dụng lsof với tùy chọn -i: Mã: lsof -i Kết quả đầu ra trông như thế này: Mã: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME owncloud 3509 myuser 25u IPv4 44946 0t0 TCP strix.local:34217->myserver.vultr.com:https (ESTABLISHED) firefox 3612 myuser 82u IPv4 49663 0t0 TCP strix.local:43897->we-in-f100.1e100.net:https (ESTABLISHED) ssh 3784 myuser 3u IPv4 10437 0t0 TCP strix.local:51416->someserver.in:ssh (ESTABLISHED) wget 4140 myuser 3w IPv4 45586 0t0 TCP strix.local:54460->media.ccc.de:http (CLOSE_WAIT) Chỉ trừ một sự khác biệt: thay vì tên tập tin hoặc thư mục, cột MAME lúc này hiển thị thông tin kết nối. Mỗi kết nối bao gồm các phần sau đây: Protocol (Giao thức) Local hostname (tên máy chủ local) Source port of the connection (cổng nguồn của kết nối) Destination DNS name Destination port. Status of the connection (Tình trạng kết nối) Tùy chọn -i có thông số bổ sung. Bạn có thể xác định có hay không hiển thị tcp, udp hoặc kết nối icmp hay cổng nào đó: Mã: lsof -i :25 or lsof -i :smtp Một lần nữa, tham số có thể được kết hợp. Ví dụ sau đây ... Mã: lsof -i tcp:80 sẽ chỉ cho bạn thấy các kết nối TCP sử dụng cổng 80. Bạn cũng có thể kết hợp nó với các tùy chọn mà bạn đã biết từ các tập tin thông tin: Mã: lsof -a -u httpd -i tcp Điều này sẽ cho bạn thấy tất cả các kết nối TCP mở bởi user httpd. Sau đây sẽ chỉ cho bạn thấy các kết nối TCP mà state là "ESTABLISHED": Mã: lsof -i -s TCP:ESTABLISHED Để đọc thêm, sử dụng lệnh man lsof trên hệ thống của bạn.