Chương trình chuyển hướng đầu ra


11

Khi cố gắng chuyển hướng đầu ra chương trình với cú pháp "một số lớn hơn" (ví dụ foo 2> myfile), các số có thể có ở đây là gì và chúng đại diện cho cái gì?

Tôi tin 1 là /dev/stdout, 2 là /dev/stderr. Còn 5 & 6 thì sao? Có 3, 4 hoặc một số số lớn hơn 6?


Câu trả lời:


11

Chương trình giả định này sẽ ghi vào số mô tả tập tin bạn đã chỉ định. xem xét chương trình hello world sau đây:

#include <stdio.h>

main()
{
   ssize_t i = 0 ;
   printf ("hello world\n") ;
   i = write( 5 , "Bonjour Monde\n", 14 ) ;
   printf ("%d octet dans 5\n", (int) i) ;
}

biên dịch nó

me@mybox:~/tmp7$ make hw
cc     hw.c   -o hw

bây giờ chạy đơn giản

me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5

không có tập tin nào cho 5, vì vậy không có byte nào được viết

thử tiếp theo:

me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde

Tôi quản lý để có được một đầu ra trong khi chỉ định một tệp và một mô tả tệp (ví dụ 5>u).

Trong thực tế, trừ khi bạn đã viết chương trình hài hước như trên, bạn không có khả năng thu thập dữ liệu bằng cách sử dụng 5>foo.

trong shell script, cấu trúc sử dụng <() hữu ích hơn:

 diff <( cmd -par 1 ) <(cmd -par 2)

write()Trả lại ssize_t, không int.
Andrew Henle

Đó không phải là điểm chính của câu hỏi, cũng có một sự trở lại cho chức năng printf.
Archemar

Không sử dụng một giá trị trả về là rất nhiều khác với việc sử dụng sai loại .
Andrew Henle

chỉnh sửa Tôi thấy không có thay đổi trong đầu ra tho ...
Archemar

10

Các số đại diện cho mô tả tệp (xử lý các tệp đã được mở).

Shell thường có 3 bộ tự động,

0 - stdin 1 - stdout 2 - stderr

Nhưng các tập tin tiếp theo có thể được mở ra và số lượng tăng lên.


7

Những con số này là mô tả tập tin . Như bạn đã lưu ý, có một số được tạo tự động. Khi các tệp khác hoặc những thứ giống như tệp được mở, chúng sẽ nhận được các số khác.

Các số được sử dụng trong bất kỳ chương trình cụ thể nào phụ thuộc vào các tệp đã được mở bởi chương trình đó hoặc được sử dụng theo cách khác. Ví dụ: nếu bạn muốn "lưu" stdin hiện tại và tạm thời chuyển hướng stdin từ nơi khác sau đó khôi phục nó sau, bạn có thể làm một cái gì đó như:

exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate

Vì vậy, tập lệnh này sẽ có một bộ 4mô tả tập tin có sẵn ít nhất một thời gian. 4 cái đó có thể là bất cứ thứ gì không được sử dụng mặc dù (vâng, có giới hạn về số lượng tệp mà một quá trình có thể mở, nhưng bất cứ thứ gì trong giới hạn đó).

Bạn có thể xem những gì mô tả tập tin mà một quá trình đã mở và nơi chúng được mở bằng cách nhìn vào /proc/<pid>/fd. Điều đó cho thấy tất cả các mô tả tệp mở cho quá trình đó <pid>và những tệp nào được liên kết với.


0

Bất kỳ quá trình nào cũng nhận được số nguyên dưới dạng mô tả tệp, trong đó có ba số được dành riêng trong POSIX: 0 là stdin, 1 là stdout và 2 là stderr. Bất kỳ tập tin tiếp theo sẽ được chỉ định số lượng thêm. Bạn có thể kiểm tra nó dễ dàng với chương trình này, lưu nó dưới dạng fdtest.c , để nó mở mã chương trình của chính nó trong thời gian chạy:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = open("fdtest.c", O_RDONLY);
    printf("%d\n", fd);
    close(fd);
    return 0;
}

Biên dịch nó:

gcc fdtest.c -o fdtest

Chạy nó:

./fdtest

Đầu ra bạn sẽ nhận được là một cái gì đó như thế này:

3

... Đó là số lượng mô tả tệp của tệp được tham chiếu bởi biến fd.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.