Điều gì sẽ là một mô tả đơn giản hơn về mô tả tập tin so với Wikipedia? Tại sao họ được yêu cầu? Nói, lấy các quy trình shell làm ví dụ và làm thế nào để áp dụng nó?
Liệu một bảng quy trình có chứa nhiều hơn một mô tả tập tin. Nếu đúng thì tại sao?
Điều gì sẽ là một mô tả đơn giản hơn về mô tả tập tin so với Wikipedia? Tại sao họ được yêu cầu? Nói, lấy các quy trình shell làm ví dụ và làm thế nào để áp dụng nó?
Liệu một bảng quy trình có chứa nhiều hơn một mô tả tập tin. Nếu đúng thì tại sao?
Câu trả lời:
Nói một cách đơn giản, khi bạn mở một tệp, hệ điều hành sẽ tạo một mục để thể hiện tệp đó và lưu trữ thông tin về tệp đã mở đó. Vì vậy, nếu có 100 tệp được mở trong HĐH của bạn thì sẽ có 100 mục trong HĐH (ở đâu đó trong kernel). Các mục này được đại diện bởi các số nguyên như (... 100, 101, 102 ....). Số mục này là mô tả tập tin. Vì vậy, nó chỉ là một số nguyên đại diện duy nhất cho một tệp được mở trong hệ điều hành. Nếu quy trình của bạn mở 10 tệp thì bảng Quy trình của bạn sẽ có 10 mục nhập cho mô tả tệp.
Tương tự như vậy khi bạn mở một ổ cắm mạng, nó cũng được biểu thị bằng một số nguyên và nó được gọi là Bộ mô tả ổ cắm. Tôi hy vọng bạn hiểu.
/proc
mọi lúc.
open()
sẽ cung cấp cho bạn bộ mô tả tệp 3, ngay cả khi một quá trình đang chạy khác xảy ra có một bộ mô tả tệp 3. Xem định nghĩa POSIX củaopen()
: "Hàm open () sẽ trả về một bộ mô tả tệp cho tệp được đặt tên là thấp nhất mô tả tập tin hiện không mở cho quá trình đó . " (nhấn mạnh thêm).
Bộ mô tả tệp là một thẻ điều khiển mờ được sử dụng trong giao diện giữa không gian người dùng và nhân để xác định tài nguyên tệp / ổ cắm. Do đó, khi bạn sử dụng open()
hoặc socket()
(gọi hệ thống để giao diện với kernel), bạn sẽ được cung cấp một bộ mô tả tệp, đó là một số nguyên (nó thực sự là một chỉ mục trong cấu trúc u quy trình - nhưng điều đó không quan trọng). Do đó, nếu bạn muốn giao tiếp trực tiếp với các hạt nhân, sử dụng các cuộc gọi hệ thống để read()
, write()
, close()
vv các xử lý bạn sử dụng là một bộ mô tả tập tin.
Có một lớp trừu tượng được phủ lên trên các cuộc gọi hệ thống, đó là stdio
giao diện. Điều này cung cấp nhiều chức năng / tính năng hơn các cuộc gọi hệ thống cơ bản. Đối với giao diện này, tay cầm mờ bạn nhận được là một FILE*
, được trả về bởi fopen()
cuộc gọi. Có rất nhiều nhiều chức năng sử dụng các stdio
giao diện fprintf()
, fscanf()
, fclose()
, mà đang có để làm cho cuộc sống của bạn dễ dàng hơn. Trong C, stdin
, stdout
, và stderr
là FILE*
, mà trong UNIX tương ứng bản đồ để mô tả tập tin 0
, 1
và 2
.
Nghe nó từ Miệng Ngựa: APUE (Richard Stevens).
Đối với kernel, tất cả các tệp đang mở được tham chiếu bởi Trình mô tả tệp. Một mô tả tập tin là một số không âm.
Khi chúng ta mở một tệp hiện có hoặc tạo một tệp mới, kernel sẽ trả về một bộ mô tả tệp cho quy trình. Hạt nhân duy trì một bảng của tất cả các mô tả tập tin đang mở, đang được sử dụng. Việc phân bổ các bộ mô tả tệp nói chung là tuần tự và chúng được phân bổ cho tệp dưới dạng bộ mô tả tệp miễn phí tiếp theo từ nhóm bộ mô tả tệp miễn phí. Khi chúng tôi đóng tệp, bộ mô tả tệp sẽ được giải phóng và có sẵn để phân bổ thêm.
Xem hình ảnh này để biết thêm chi tiết:
Khi chúng tôi muốn đọc hoặc ghi một tệp, chúng tôi xác định tệp có bộ mô tả tệp được trả về bằng lệnh gọi hàm open () hoặc tạo () và sử dụng nó làm đối số để đọc () hoặc write () .
Theo quy ước, các hệ thống UNIX shell liên kết bộ mô tả tệp 0 với Đầu vào tiêu chuẩn của một quy trình, bộ mô tả tệp 1 với Đầu ra tiêu chuẩn và bộ mô tả tệp 2 với Lỗi tiêu chuẩn .
Bộ mô tả tệp nằm trong khoảng từ 0 đến OPEN_MAX. Giá trị tối đa mô tả tập tin có thể được lấy với ulimit -n
. Để biết thêm thông tin, hãy đi qua chương 3 của Sách APUE.
osqueryi <<< echo '.all process_open_files'
trong bash shell.
Câu trả lời khác thêm công cụ tuyệt vời. Tôi sẽ chỉ thêm 2 xu của tôi.
Theo Wikipedia chúng tôi biết chắc chắn: một mô tả tập tin là một số nguyên không âm. Điều quan trọng nhất tôi nghĩ là thiếu, sẽ là:
Mô tả tập tin được ràng buộc với một ID quá trình.
Chúng tôi biết hầu hết các mô tả tập tin nổi tiếng là 0, 1 và 2. 0 tương ứng với STDIN
, 1 đến STDOUT
và 2 đến STDERR
.
Nói, lấy các quy trình shell làm ví dụ và làm thế nào để áp dụng nó?
Kiểm tra mã này
#>sleep 1000 &
[12] 14726
Chúng tôi đã tạo một quy trình với id 14726 (PID). Sử dụng lsof -p 14726
chúng ta có thể có được những thứ như thế này:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sleep 14726 root cwd DIR 8,1 4096 1201140 /home/x
sleep 14726 root rtd DIR 8,1 4096 2 /
sleep 14726 root txt REG 8,1 35000 786587 /bin/sleep
sleep 14726 root mem REG 8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep 14726 root mem REG 8,1 2030544 137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep 14726 root mem REG 8,1 170960 137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep 14726 root 0u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 1u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 2u CHR 136,6 0t0 9 /dev/pts/6
Cột thứ 4 FD và cột TYPE tiếp theo tương ứng với loại Mô tả tệp và loại Mô tả tệp.
Một số giá trị cho FD có thể là:
cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device
Nhưng bộ mô tả tập tin thực sự nằm dưới:
NUMBER – Represent the actual file descriptor.
Ký tự sau số tức là "1u", biểu thị chế độ mở tệp. r để đọc, w để viết, u để đọc và viết.
TYPE chỉ định loại tệp. Một số giá trị của TYPE là:
REG – Regular File
DIR – Directory
FIFO – First In First Out
Nhưng tất cả các mô tả tệp là tệp đặc biệt CHR - Ký tự (hoặc tệp thiết bị ký tự)
Bây giờ, chúng ta có thể xác định các file descriptor cho STDIN
, STDOUT
và STDERR
dễ dàng với lsof -p PID
, hoặc chúng ta có thể xem cùng nếu chúng ta ls /proc/PID/fd
.
Cũng lưu ý rằng bảng mô tả tệp mà kernel theo dõi không giống như bảng tệp hoặc bảng inodes. Đây là riêng biệt, như một số câu trả lời khác giải thích.
Bạn có thể tự hỏi những mô tả tập tin này ở đâu và /dev/pts/6
ví dụ những gì được lưu trữ
sleep 14726 root 0u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 1u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 2u CHR 136,6 0t0 9 /dev/pts/6
Vâng, /dev/pts/6
sống hoàn toàn trong ký ức. Đây không phải là các tệp thông thường, nhưng được gọi là các tệp thiết bị ký tự . Bạn có thể kiểm tra điều này với: ls -l /dev/pts/6
và họ sẽ bắt đầu với c
, trong trường hợp của tôi crw--w----
.
Chỉ cần nhớ lại hầu hết Linux như HĐH xác định bảy loại tệp:
Thêm điểm về File Descriptor
:
File Descriptors
(FD) là các số nguyên không âm (0, 1, 2, ...)
được liên kết với các tệp được mở.
0, 1, 2
là tiêu chuẩn FD 's mà tương ứng với STDIN_FILENO
, STDOUT_FILENO
và STDERR_FILENO
(quy định tại unistd.h
) mở theo mặc định trên danh nghĩa của vỏ khi chương trình bắt đầu.
FD được phân bổ theo thứ tự tuần tự, có nghĩa là giá trị nguyên chưa được phân bổ thấp nhất có thể.
FD cho một quy trình cụ thể có thể được nhìn thấy /proc/$pid/fd
(trên các hệ thống dựa trên Unix).
Ngoài các câu trả lời khác, unix coi mọi thứ là một hệ thống tệp. Bàn phím của bạn là một tệp chỉ được đọc từ phối cảnh của kernel. Màn hình là một tập tin chỉ ghi. Tương tự, các thư mục, thiết bị đầu vào-đầu ra, vv cũng được coi là các tệp. Bất cứ khi nào một tệp được mở, hãy nói khi trình điều khiển thiết bị [cho các tệp thiết bị] yêu cầu mở () hoặc một quá trình mở tệp người dùng, hạt nhân cấp phát một bộ mô tả tệp, một số nguyên chỉ định quyền truy cập vào tệp đó để nó chỉ được đọc , chỉ viết, v.v. [để tham khảo: https://en.wikipedia.org/wiki/Everything_is_a_file ]
Mô tả tệp (FD):
$ ls mydir 2> lỗifile.txt
Bộ mô tả tệp cho lỗi tiêu chuẩn là 2.
Nếu không có bất kỳ thư mục nào có tên là mydir thì đầu ra của lệnh sẽ được lưu vào tệp errorfile.txt
Sử dụng "2>", chúng tôi chuyển hướng đầu ra lỗi sang tệp có tên "errorfile. txt "
Như vậy, đầu ra chương trình không bị lộn xộn với lỗi.
Tôi hy vọng bạn có câu trả lời của bạn.
Bất kỳ hệ điều hành nào cũng có các tiến trình (p's) đang chạy, giả sử p1, p2, p3 , v.v. Mỗi quá trình thường làm cho việc sử dụng tập tin liên tục.
Mỗi quy trình bao gồm một cây quy trình (hoặc một bảng quy trình, trong một cụm từ khác).
Thông thường, Hệ điều hành đại diện cho mỗi tệp trong mỗi quy trình bằng một số (có nghĩa là, trong mỗi cây / bảng quy trình).
Các tập tin đầu tiên được sử dụng trong quá trình này là file0 , thứ hai là file1 , thứ ba là file2 , và vân vân.
Bất kỳ số nào là một mô tả tập tin.
Mô tả tệp thường là số nguyên (0, 1, 2 chứ không phải 0,5, 1,5, 2,5).
Do chúng ta thường mô tả các quy trình là "bảng quy trình" và do các bảng có hàng (mục), chúng ta có thể nói rằng ô mô tả tệp trong mỗi mục, sử dụng để thể hiện toàn bộ mục.
Theo cách tương tự, khi bạn mở một ổ cắm mạng, nó có một bộ mô tả ổ cắm.
Trong một số hệ điều hành, bạn có thể dùng hết phần mô tả tệp, nhưng trường hợp như vậy là cực kỳ hiếm và người dùng máy tính trung bình không nên lo lắng về điều đó.
Các mô tả tệp có thể là toàn cục (quy trình A bắt đầu bằng 0 và kết thúc bằng 1; Quá trình B bắt đầu bằng 2 và kết thúc bằng 3), v.v., theo như tôi biết, thông thường trong các hệ điều hành hiện đại, tệp các mô tả không phải là toàn cục và thực sự là quy trình cụ thể (quy trình A bắt đầu bằng nói 0 và kết thúc bằng 5, trong khi quy trình B bắt đầu bằng 0 và kết thúc bằng 10).
Ngoài ra trên tất cả các câu trả lời đơn giản hóa.
Nếu bạn đang làm việc với các tệp trong tập lệnh bash, tốt hơn là sử dụng bộ mô tả tệp.
Ví dụ: -
Bạn muốn đọc và ghi từ / vào tệp "test.txt".
Sử dụng mô tả tập tin như hiển thị dưới đây
FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
echo "$LINE"
done <&5
# Writing to the file using descriptor
echo "Adding the date: `date`" >&5
exec 5<&- # Closing a file descriptor