Tôi khá bối rối với mục đích của ba tập tin này. Nếu sự hiểu biết của tôi là chính xác, thì stdin là tệp mà chương trình ghi vào các yêu cầu của nó để chạy một tác vụ trong quy trình, stdout là tệp mà hạt nhân ghi đầu ra của nó và quá trình yêu cầu nó truy cập thông tin từ đó, và stderr là các tập tin mà tất cả các ngoại lệ được nhập vào. Khi mở các tệp này để kiểm tra xem những điều này có thực sự xảy ra hay không, tôi thấy dường như không có gì gợi ý như vậy!
Những gì tôi muốn biết là chính xác mục đích của các tệp này là gì, hoàn toàn không có câu trả lời với rất ít thuật ngữ công nghệ!
linuxstdoutstdinstderr
178
2 thg 8, 2010Shouvik
Đầu vào tiêu chuẩn – đây là tệp xử lý tệp mà quy trình của bạn đọc để lấy thông tin từ bạn.
Đang xem: Có nghĩa là gì khi kết nối stdout là gì khi kết nối stdout và stdin?
Đầu ra tiêu chuẩn – quy trình của bạn ghi thông tin bình thường vào tệp xử lý này.
Lỗi tiêu chuẩn – quy trình của bạn ghi thông tin lỗi vào tệp xử lý này.
Đó là về sự ngu ngốc như tôi có thể làm cho nó 🙂
Tất nhiên, đó chủ yếu là theo quy ước. Không có gì ngăn bạn viết thông tin lỗi của bạn vào đầu ra tiêu chuẩn nếu bạn muốn. Bạn thậm chí có thể đóng hoàn toàn ba tay cầm tệp và mở tệp của riêng bạn cho I/O.
Khi quy trình của bạn bắt đầu, nó sẽ có các tay cầm này mở và nó chỉ có thể đọc từ và/hoặc viết cho chúng.
Theo mặc định, chúng có thể được kết nối với thiết bị đầu cuối của bạn (ví dụ: /dev/tty) nhưng shell sẽ cho phép bạn thiết lập kết nối giữa các tay cầm này và các tệp và/hoặc thiết bị cụ thể (hoặc thậm chí là đường ống đến các quy trình khác) trước khi quá trình của bạn bắt đầu (một số của các thao tác có thể là khá thông minh).
Một ví dụ là:
my_prog errorfile | grep XYZcái nào sẽ:
tạo một quy trình cho my_prog.mở inputfile làm đầu vào tiêu chuẩn của bạn (xử lý tệp 0).mở errorfile là lỗi tiêu chuẩn của bạn (xử lý tệp 2).tạo quy trình khác cho grep.đính kèm đầu ra tiêu chuẩn của my_prog với đầu vào tiêu chuẩn của grep.
Nhận xét của bạn:
Khi tôi mở các tệp này trong thư mục/dev, tại sao tôi không bao giờ thấy đầu ra của một tiến trình đang chạy?
Đó là bởi vì chúng không phải là các tập tin bình thường. Trong khi UNIX trình bày mọi thứ dưới dạng tệp trong một hệ thống tệp ở đâu đó, điều đó không làm cho nó ở mức thấp nhất. Hầu hết các tệp trong hệ thống phân cấp /dev là ký tự hoặc khối thiết bị, thực sự là trình điều khiển thiết bị. Chúng không có kích thước nhưng chúng có số thiết bị chính và phụ.
Khi bạn mở chúng, bạn đã kết nối với trình điều khiển thiết bị chứ không phải tệp vật lý và trình điều khiển thiết bị đủ thông minh để biết rằng các quy trình riêng biệt nên được xử lý riêng.
Điều này cũng đúng với hệ thống tập tin Linux /proc. Đó không phải là các tập tin thực, chỉ là các cổng kiểm soát chặt chẽ thông tin kernel.
Sẽ đúng hơn khi nói rằng stdin, stdout và stderr là “luồng I/O” chứ không phải là tệp. Như bạn đã nhận thấy, những thực thể này không sống trong hệ thống tập tin. Nhưng triết lý Unix, theo như I/O có liên quan, là “mọi thứ đều là một tập tin”. Trong thực tế, điều đó thực sự có nghĩa là bạn có thể sử dụng cùng các chức năng và giao diện thư viện (printf, scanf, read, write, select, v.v.) mà không cần lo lắng về việc liệu luồng I/O có được kết nối với một tệp, bàn phím ổ cắm, đường ống hoặc một số trừu tượng I/O khác.
Xem thêm: Thermoplastic Là Gì – Tìm Hiểu Nhựa Tpe Là Gì
Hầu hết các chương trình cần đọc đầu vào, ghi đầu ra và ghi nhật ký lỗi, vì vậy stdin, stdout và stderr được xác định trước cho bạn, như một sự thuận tiện cho lập trình. Đây chỉ là một quy ước và không được hệ điều hành thi hành.
Để bổ sung cho các câu trả lời ở trên, đây là tổng hợp về Chuyển hướng:
EDIT: Đồ họa này không hoàn toàn chính xác nhưng tôi không chắc tại sao …
Đồ họa cho biết 2> & 1 có tác dụng tương tự như &> tuy nhiên
ls Documents ABC > dirlist 2>&1#does not give the same output as ls Documents ABC > dirlist &>
Tôi sợ sự hiểu biết của bạn là hoàn toàn lạc hậu. 🙂
Hãy nghĩ về “tiêu chuẩn trong”, “tiêu chuẩn ra” và “lỗi tiêu chuẩn” từ phối cảnh chương trình, không phải từ quan điểm của hạt nhân.
Khi một chương trình cần in đầu ra, nó thường in thành “tiêu chuẩn ra”. Một chương trình thường in đầu ra thành tiêu chuẩn với printf, in CHỈ ra tiêu chuẩn.
Khi một chương trình cần in thông tin lỗi (không nhất thiết là ngoại lệ, đó là cấu trúc ngôn ngữ lập trình, được áp đặt ở mức cao hơn nhiều), nó thường in thành “lỗi tiêu chuẩn”. Nó thường làm như vậy với fprintf, chấp nhận luồng tệp để sử dụng khi in. Luồng tệp có thể là bất kỳ tệp nào được mở để ghi: lỗi tiêu chuẩn, lỗi tiêu chuẩn hoặc bất kỳ tệp nào khác đã được mở bằng fopen hoặc fdopen.
“Standard in” được sử dụng khi tệp cần đọc đầu vào, sử dụng fread hoặc fgets hoặc getchar.
Bất kỳ tệp nào trong số này cũng có thể dễ dàng chuyển hướng từ Shell, như thế này:
cat /etc/passwd > /tmp/out # redirect cat”s standard out to /tmp/foocat /nonexistant 2> /tmp/err # redirect cat”s standard error to /tmp/errorcat Hoặc, toàn bộ enchilada:
cat /tmp/out 2> /tmp/errCó hai cảnh báo quan trọng: Thứ nhất, “tiêu chuẩn trong”, “tiêu chuẩn ra” và “lỗi tiêu chuẩn” chỉ là một quy ước. Chúng là một quy ước rất mạnh, nhưng tất cả chỉ là một thỏa thuận rằng thật tuyệt khi có thể chạy các chương trình như thế này: grep echo /etc/services | awk “{print $2;}” | sort và có đầu ra tiêu chuẩn của mỗi chương trình được nối vào đầu vào tiêu chuẩn của chương trình tiếp theo trong đường ống.
Thứ hai, tôi đã cung cấp các hàm ISO C tiêu chuẩn để làm việc với các luồng tệp (các đối tượng FILE *) – ở cấp độ nhân, tất cả đều là các mô tả tệp (tham chiếu int vào bảng tệp) và các hoạt động ở cấp độ thấp hơn nhiều như read và write , không thực hiện bộ đệm hạnh phúc của các chức năng ISO C. Tôi nghĩ rằng để giữ cho nó đơn giản và sử dụng các chức năng dễ dàng hơn, nhưng tôi nghĩ tất cả giống như bạn nên biết các lựa chọn thay thế. 🙂
stdin
Đọc đầu vào thông qua bảng điều khiển (ví dụ: Nhập bàn phím). Được sử dụng trong C với scanf
scanf(, …);
xuất sắc
Tạo đầu ra cho giao diện điều khiển. Được sử dụng trong C với printf
printf(, …);
stderr
Tạo đầu ra “lỗi” cho bàn điều khiển. Được sử dụng trong C với fprintf
fprintf(stderr, , …);
Chuyển hướng
Nguồn cho stdin có thể được chuyển hướng. Ví dụ: thay vì đến từ đầu vào bàn phím, nó có thể đến từ một tệp (echo ) hoặc chương trình khác (ps | grep ).
Các điểm đến cho thiết bị xuất chuẩn, thiết bị xuất chuẩn cũng có thể được chuyển hướng. Ví dụ, thiết bị xuất chuẩn có thể được chuyển hướng đến một tệp: ls . > ls-output.txt, trong trường hợp này, đầu ra được ghi vào tệp ls-output.txt. Stderr có thể được chuyển hướng với 2>.
Tôi nghĩ rằng mọi người nói stderr chỉ nên được sử dụng cho các thông báo lỗi là sai lệch.
Xem thêm: Tái Hôn Là Gì ? Các Quy Định Của Pháp Luật Về Kết Hôn
Nó cũng nên được sử dụng cho các thông báo có ý nghĩa đối với người dùng đang chạy lệnh và không dành cho bất kỳ người tiêu dùng dữ liệu tiềm năng nào (ví dụ: nếu bạn chạy một ống Shell có một số lệnh bạn không muốn có thông báo như “nhận mục 30 42424 “xuất hiện trên stdout vì họ sẽ gây nhầm lẫn cho người tiêu dùng, nhưng bạn vẫn có thể muốn người dùng nhìn thấy họ.
Xem này để biết lý do lịch sử:
“Tất cả các chương trình đặt chẩn đoán trên đầu ra tiêu chuẩn. Điều này luôn gây ra sự cố khi đầu ra được chuyển hướng thành một, nhưng trở nên không thể chịu đựng được khi đầu ra được gửi đến một quy trình không nghi ngờ. Tuy nhiên, không muốn vi phạm tính đơn giản của đầu vào tiêu chuẩn- Mô hình đầu ra tiêu chuẩn, mọi người chấp nhận tình trạng này qua v6. Ngay sau đó Dennis Ritchie đã cắt nút Gordian bằng cách đưa ra lỗi tiêu chuẩn. Điều đó là không đủ. Với chẩn đoán đường ống có thể đến từ bất kỳ chương trình nào chạy cùng lúc. để nhận diện chính họ. “