Câu trả lời:
Bất cứ khi nào bạn đọc một tệp bên dưới /proc
, điều này sẽ gọi một số mã trong kernel để tính toán văn bản để đọc làm nội dung tệp. Thực tế là nội dung được tạo nhanh chóng giải thích lý do tại sao hầu hết tất cả các tệp đều có thời gian được báo cáo như bây giờ và kích thước của chúng được báo cáo là 0 - ở đây bạn nên đọc 0 vì không hiểu biết. Không giống như các hệ thống tệp thông thường, hệ thống tệp được gắn trên /proc
, được gọi là Procfs , không tải dữ liệu từ đĩa hoặc phương tiện lưu trữ khác (như FAT, ext2, zfs, giật) hoặc qua mạng (như NFS, Samba, Nott) và không gọi mã người dùng (không giống như FUSE ).
Procfs có mặt trong hầu hết các đơn vị không thuộc BSD. Nó bắt đầu cuộc sống của mình tại Phòng thí nghiệm Bell của AT & T trong phiên bản UNIX 8 như một cách để báo cáo thông tin về các quy trình (và ps
thường là một máy in đẹp cho thông tin đọc qua /proc
). Hầu hết các cài đặt Procfs đều có một tệp hoặc thư mục được gọi /proc/123
để báo cáo thông tin về quy trình với PID 123. Linux mở rộng hệ thống tệp Proc với nhiều mục khác báo cáo trạng thái của hệ thống, bao gồm cả ví dụ của bạn /proc/cpuinfo
.
Trước đây, Linux đã /proc
mua các tệp khác nhau cung cấp thông tin về trình điều khiển, nhưng việc sử dụng này hiện không được ủng hộ /sys
và /proc
hiện đang phát triển chậm. Các mục nhập thích /proc/bus
và /proc/fs/ext4
duy trì vị trí tương thích ngược, nhưng các giao diện tương tự mới hơn được tạo bên dưới /sys
. Trong câu trả lời này, tôi sẽ tập trung vào Linux.
Điểm nhập cảnh đầu tiên và thứ hai của bạn cho tài liệu về /proc
Linux là:
proc(5)
trang người đàn ông ;/proc
thống tập tin trong tài liệu kernel .Điểm vào thứ ba của bạn, khi tài liệu không bao gồm nó, đang đọc nguồn . Bạn có thể tải xuống nguồn trên máy của mình, nhưng đây là một chương trình lớn và LXR , tài liệu tham khảo chéo của Linux, là một trợ giúp lớn. (Có rất nhiều biến thể của LXR; phiên bản đang chạy lxr.linux.no
là đẹp nhất nhưng không may là trang này thường bị sập.) Cần có một ít kiến thức về C, nhưng bạn không cần phải là lập trình viên để theo dõi giá trị bí ẩn .
Việc xử lý cốt lõi của /proc
các mục là trong fs/proc
thư mục. Bất kỳ tài xế nào cũng có thể đăng ký các mục trong /proc
(mặc dù như được chỉ ra ở trên, điều này hiện không được ủng hộ /sys
), vì vậy nếu bạn không tìm thấy những gì bạn đang tìm kiếm fs/proc
, hãy tìm mọi nơi khác. Trình điều khiển gọi các chức năng khai báo trong include/linux/proc_fs.h
. Các phiên bản kernel lên tới 3.9 cung cấp các chức năng create_proc_entry
và một số trình bao bọc (đặc biệt create_proc_read_entry
) và các phiên bản kernel 3.10 trở lên chỉ cung cấp thay thế proc_create
và proc_create_data
(và một vài thứ nữa).
Lấy /proc/cpuinfo
ví dụ, một tìm kiếm cho "cpuinfo"
dẫn bạn đến các cuộc gọi đến proc_create("cpuinfo, …")
trong fs/proc/cpuinfo.c
. Bạn có thể thấy rằng mã này có khá nhiều mã soạn sẵn: vì hầu hết các tệp dưới /proc
chỉ đổ một số dữ liệu văn bản, có các hàm trợ giúp để làm điều đó. Chỉ có một seq_operations
cấu trúc và phần thịt thực sự nằm trong cpuinfo_op
cấu trúc dữ liệu, phụ thuộc vào kiến trúc, thường được định nghĩa trong arch/<architecture>/kernel/setup.c
(hoặc đôi khi là một tệp khác). Lấy x86 làm ví dụ, chúng tôi đã dẫn đến arch/x86/kernel/cpu/proc.c
. Có chức năng chính làshow_cpuinfo
, trong đó in ra nội dung tập tin mong muốn; phần còn lại của cơ sở hạ tầng là để cung cấp dữ liệu cho quá trình đọc với tốc độ mà nó yêu cầu. Bạn có thể thấy dữ liệu được lắp ráp khi đang di chuyển từ dữ liệu theo các biến khác nhau trong nhân, bao gồm một vài số được tính khi đang di chuyển, chẳng hạn như tần số CPU .
Một phần lớn /proc
là thông tin trên mỗi quá trình /proc/<PID>
. Các mục này được đăng ký trong fs/proc/base.c
, trong tgid_base_stuff
mảng ; một số chức năng đăng ký ở đây được xác định trong các tập tin khác. Hãy xem xét một vài ví dụ về cách tạo ra các mục này:
cmdline
được tạo bởi proc_pid_cmdline
trong cùng một tập tin. Nó định vị dữ liệu te trong quá trình và in ra.clear_refs
, không giống như các mục chúng ta đã thấy cho đến nay, có thể ghi nhưng không thể đọc được. Do đó, các proc_clear_refs_operations
cấu trúc xác định một clear_refs_write
chức năng nhưng không có chức năng đọc.cwd
là một liên kết tượng trưng (một liên kết hơi kỳ diệu), được khai báo bởi proc_cwd_link
, nó tìm kiếm thư mục hiện tại của quy trình và trả về nó dưới dạng nội dung liên kết.fd
là một thư mục con. Các hoạt động trên chính thư mục được xác định trong proc_fd_operations
cấu trúc dữ liệu (chúng được soạn sẵn ngoại trừ chức năng liệt kê các mục, proc_readfd
liệt kê các tệp đang mở của quy trình) trong khi các thao tác trên các mục nằm trong `Proc_fd_inode_operations .Một lĩnh vực quan trọng khác /proc
là /proc/sys
, đó là một giao diện trực tiếp sysctl
. Đọc từ một mục trong hệ thống phân cấp này trả về giá trị của giá trị sysctl tương ứng và viết sẽ đặt giá trị sysctl. Các điểm vào cho sysctl là trong fs/proc/proc_sysctl.c
. Sysctls có hệ thống đăng ký riêng của họ với register_sysctl
và bạn bè.
Khi cố gắng hiểu rõ hơn về loại phép thuật nào đang xảy ra đằng sau hậu trường, người bạn thân nhất của bạn strace
. Học cách vận hành công cụ này là một trong những điều tốt nhất bạn có thể làm để có được sự đánh giá tốt hơn cho những gì ma thuật điên rồ đang xảy ra đằng sau hậu trường.
$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536) = 0
close(3) = 0
...
Từ đầu ra trên, bạn có thể thấy đó /proc/cpuinfo
chỉ là một tệp thông thường, hoặc ít nhất sẽ xuất hiện là một tệp. Vì vậy, hãy đào sâu hơn.
Nhìn vào tập tin, nó có vẻ như "chỉ là một tập tin".
$ ls -l /proc/cpuinfo
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo
Nhưng hãy xem xét kỹ hơn. Chúng tôi nhận được gợi ý đầu tiên của chúng tôi rằng nó đặc biệt, lưu ý kích thước của tệp là 0 byte.
# 2 - với chỉ số ..Nếu bây giờ chúng ta xem tệp bằng cách sử dụng, stat
chúng ta có thể nhận được gợi ý tiếp theo rằng có gì đó đặc biệt /proc/cpuinfo
.
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
Birth: -
chạy số 2
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
Birth: -
Lưu ý thời gian truy cập, sửa đổi và thay đổi? Họ tiếp tục thay đổi cho mỗi lần truy cập. Điều này rất bất thường khi cả 3 sẽ thay đổi như thế. Trừ khi chỉnh sửa các thuộc tính dấu thời gian của tệp thường giữ nguyên.
# 3 - với tệp ..Một manh mối khác cho thấy tệp này là bất cứ thứ gì ngoại trừ một tệp thông thường:
$ file /proc/cpuinfo
/proc/cpuinfo: empty
Nếu đó là một số biểu hiện của một đường ống có tên, nó sẽ hiển thị tương tự như một trong các tệp sau:
$ ls -l /dev/initctl /dev/zero
prw-------. 1 root root 0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero
$ file /dev/initctl /dev/zero
/dev/initctl: fifo (named pipe)
/dev/zero: character special
Nếu chúng ta chạm vào một emptyfile
, /proc/cpuinfo
có vẻ giống như một tập tin hơn thì một đường ống:
$ touch emptyfile
$ ls -l emptyfile
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile
emptyfile: empty
# 4 - với thú cưỡi ..
Vì vậy, tại thời điểm này chúng ta cần lùi lại một bước và thu nhỏ một chút. Chúng tôi đang xem một tệp cụ thể nhưng có lẽ chúng ta nên xem hệ thống tệp mà tệp này nằm trong đó. Và để làm điều này, chúng ta có thể sử dụng mount
lệnh.
$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
OK, vì vậy loại hệ thống tập tin là loại proc
. Vì vậy, /proc
một loại hệ thống tệp khác nhau, đó là gợi ý của chúng tôi rằng các tệp bên dưới /proc
là đặc biệt. Chúng không chỉ là việc bạn chạy các tập tin mill. Vì vậy, hãy tìm hiểu thêm một số thông tin về những gì làm cho proc
hệ thống tập tin đặc biệt.
Hãy xem mount
trang người đàn ông của:
Hệ thống tập tin Proc không được liên kết với một thiết bị đặc biệt và khi gắn nó, một từ khóa tùy ý, chẳng hạn như Proc có thể được sử dụng thay vì một đặc điểm kỹ thuật của thiết bị. (Lựa chọn thông thường không có gì kém may mắn hơn: thông báo lỗi 'không bận rộn' từ umount có thể gây nhầm lẫn.)
Và nếu chúng ta xem proc
trang của người đàn ông:
Hệ thống tệp Proc là một hệ thống tệp giả được sử dụng làm giao diện cho các cấu trúc dữ liệu kernel. Nó thường được gắn tại / Proc. Hầu hết trong số đó là chỉ đọc, nhưng một số tệp cho phép thay đổi các biến nhân.
Một chút nữa xuống trong cùng một trang người đàn ông:
/ Proc / cpuinfo
Đây là một tập hợp các mục phụ thuộc kiến trúc CPU và hệ thống, cho mỗi kiến trúc được hỗ trợ một danh sách khác nhau. Hai mục phổ biến là bộ xử lý cung cấp số CPU và bogomips; một hằng số hệ thống được tính trong quá trình khởi tạo kernel. Máy SMP có thông tin cho từng CPU. Lệnh lscpu (1) tập hợp thông tin của nó từ tệp này.
Ở dưới cùng của trang man là một tham chiếu đến một tài liệu kernel mà bạn có thể tìm thấy ở đây, có tiêu đề: THE / Proc FILESYSTEM . Trích dẫn từ tài liệu đó:
Hệ thống tệp Proc hoạt động như một giao diện cho các cấu trúc dữ liệu nội bộ trong kernel. Nó có thể được sử dụng để có được thông tin về hệ thống và thay đổi các tham số kernel nhất định khi chạy (sysctl).
Vậy chúng ta đã học được gì ở đây? Được cho /proc
là được gọi là hệ thống tệp giả và cũng là "giao diện cho cấu trúc dữ liệu nội bộ", có thể an toàn khi cho rằng các mục trong đó không phải là tệp thực, mà chỉ là các biểu hiện được tạo ra trông giống như tệp, nhưng thực sự không phải vậy.
Tôi sẽ kết thúc với trích dẫn này dường như đã từng là phiên bản trước của man 5 proc
khoảng năm 2004 nhưng vì bất kỳ lý do gì không còn được bao gồm. LƯU Ý: Tôi không chắc tại sao nó bị xóa vì nó mô tả rất độc đáo /proc
:
Thư mục / Proc trên các hệ thống GNU / Linux cung cấp giao diện giống như hệ thống tệp cho kernel. Điều này cho phép các ứng dụng và người dùng tìm nạp thông tin từ và đặt giá trị trong kernel bằng thao tác I / O của hệ thống tệp thông thường.
Hệ thống tệp Proc đôi khi được gọi là hệ thống tệp giả thông tin quy trình. Nó không chứa các tệp `` real '' mà là thông tin hệ thống thời gian chạy (ví dụ: bộ nhớ hệ thống, các thiết bị được gắn, cấu hình phần cứng, v.v.). Vì lý do này, nó có thể được coi là một trung tâm điều khiển và thông tin cho kernel. Trong thực tế, khá nhiều tiện ích hệ thống chỉ đơn giản là gọi đến các tệp trong thư mục này. Ví dụ, lệnh lsmod, liệt kê các mô-đun được nạp bởi kernel, về cơ bản giống như 'cat / Proc / mô-đun' trong khi lspci, liệt kê các thiết bị được kết nối với bus PCI của hệ thống, giống như 'cat / Proc / pci '. Bằng cách thay đổi các tệp nằm trong thư mục này, bạn có thể thay đổi các tham số kernel trong khi hệ thống đang chạy.
Nguồn: Hệ thống tập tin giả
strace -o catcpuproc.txt cat /proc/cpuinfo
Câu trả lời được đưa ra bởi @slm là rất toàn diện, nhưng tôi nghĩ rằng một lời giải thích đơn giản hơn có thể đến từ một sự thay đổi trong quan điểm.
Trong việc sử dụng hàng ngày, chúng ta có thể coi các tập tin là những thứ vật lý, tức là. khối dữ liệu được lưu trữ trên một số thiết bị. Điều này làm cho các tệp như / Proc / cpuinfo trở nên rất bí ẩn và khó hiểu. Tuy nhiên, tất cả đều có ý nghĩa hoàn hảo nếu chúng ta nghĩ về các tệp như một giao diện ; một cách để gửi dữ liệu vào và ra khỏi một số chương trình.
Các chương trình gửi và nhận dữ liệu theo cách này là hệ thống tệp hoặc trình điều khiển (tùy thuộc vào cách bạn xác định các thuật ngữ này, có thể quá rộng hoặc quá hẹp định nghĩa). Điểm quan trọng là một số chương trình này sử dụng thiết bị phần cứng để lưu trữ và truy xuất dữ liệu được gửi qua giao diện này; nhưng không phải tất cả.
Một số ví dụ về hệ thống tệp không sử dụng thiết bị lưu trữ (ít nhất là trực tiếp) là:
Hệ điều hành Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) là một ví dụ cực đoan về việc sử dụng các tệp làm giao diện lập trình chung.