Sử dụng dấu gạch ngang (-) thay cho tên tệp


110

Đối với một lệnh, nếu sử dụng -làm đối số thay cho tên tệp sẽ có nghĩa là STDIN hoặc STDOUT.

  1. Nhưng trong ví dụ này, nó tạo ra một tệp có tên -:

    echo hello > -

    Làm thế nào tôi có thể thực hiện -trong ví dụ này có nghĩa là STDOUT?

  2. Ngược lại, làm thế nào tôi có thể làm cho -một tệp có tên -trong các ví dụ như:

    cat -

3
Vì rõ ràng tôi phải có 50 danh tiếng để bình luận trực tiếp ... Trên bình luận / dev / stdin / dev / stdout, AIX, một dẫn xuất UNIX hợp pháp không có các giả thuyết này. Và, như một nhận xét thêm, LINUX không phải là một dẫn xuất UNIX trong mọi trường hợp. Nó là một máy tính tương thích POSIX và là hệ điều hành UNIX-ish phổ biến nhất tại thời điểm này, nhưng không có lỗi, đây không phải là UNIX. Nhưng, ý chính của các câu trả lời ở đây là chính xác. Ký hiệu "-" không được hiểu là đặc biệt bởi shell và do đó được truyền trực tiếp đến từng ứng dụng riêng lẻ dưới dạng ARG. Nếu ứng dụng không nhận dạng

Ngoài ra còn có 2>&-xây dựng, có nghĩa là "mô tả gần 2".
dùng3132194

@ user95873, điều tôi cho rằng bạn muốn nói là: trong khi Linux giống Unix, không phải mọi Unix giống (hoặc UNIX thực) đều là Linux . Vấn đề liệu Linux có đúng hay không UNIX (nghĩa là tuân thủ Đặc tả UNIX đơn) không liên quan đến vấn đề / dev / std {in, out, err}. As / dev / std {in, out, err} được thêm tính năng, không thiếu .
sasha

Câu trả lời:


156

Sử dụng -làm tên tệp để có nghĩa là stdin / stdout là một quy ước mà rất nhiều chương trình sử dụng. Nó không phải là một tài sản đặc biệt của tên tệp. Hạt nhân không nhận ra -là đặc biệt nên bất kỳ cuộc gọi hệ thống nào đề cập đến -như một tên tệp sẽ sử dụng theo -nghĩa đen là tên tệp.

Với chuyển hướng bash, -không được nhận dạng là một tên tệp đặc biệt, vì vậy bash sẽ sử dụng đó làm tên tệp theo nghĩa đen.

Khi catthấy chuỗi -là một tên tệp, nó coi nó như một từ đồng nghĩa với stdin. Để giải quyết vấn đề này, bạn cần thay đổi chuỗi catnhìn theo cách mà nó vẫn đề cập đến một tệp được gọi -. Cách thông thường để làm điều này là tiền tố tên tệp với một đường dẫn - ./-hoặc /home/Tim/-. Kỹ thuật này cũng được sử dụng để khắc phục các vấn đề tương tự trong đó các tùy chọn dòng lệnh đụng độ với tên tệp, do đó, một tệp được gọi là ./-ekhông xuất hiện dưới dạng -etùy chọn dòng lệnh cho một chương trình, ví dụ.


37
Thật đáng để thêm vào đó /dev/stdin/dev/stdoutcó sẵn trên toàn cầu và có thể được sử dụng thay cho -quy ước.
jmtd

Cũng trong cattrường hợp, sử dụng chuyển hướng thay vì liệt kê đối số có thể giúp : cat <-; tuy nhiên, thật khó để trộn và kết hợp nó với việc ghép nhiều hơn một tệp cùng một lúc.
jmtd

10
@jmtd: / dev / std {in, out} không có sẵn trên toàn cầu. Không phải tất cả các unixes có nó.
camh

2
Thật thú vị, tôi cho rằng chúng là một phần của POSIX (nhưng không thể xác nhận). Họ hiện diện ít nhất trên Linux, BSD và Solaris. Bạn có thể đưa ra một ví dụ về một UNIX hiện đại thiếu chúng?
jmtd

1
@camh Không chắc bạn có nhận được thông báo hay không, và đây là một chủ đề rất cũ; Tôi không chắc là bạn có thể không, nhưng tôi rất tò mò nếu bạn biết câu trả lời cho jmtdcâu hỏi của mình? :)
Xoay

18
  1. Thay vì echo hello > -, bạn có thể sử dụng echo hello > /dev/stdout.

    Trong khi '-' là một quy ước mà đã được thực hiện bởi mỗi chương trình mong muốn hỗ trợ nó, /dev/stdin, /dev/stdout/dev/stderrlà, khi được hỗ trợ bởi hệ điều hành (ít nhất là Solaris, Linux và BSDs làm), không phụ thuộc vào ứng dụng và sau đó sẽ làm việc như bạn có ý định


9

Như camh đã đề cập , -chỉ là một quy ước đặt tên được sử dụng bởi một số chương trình. Nếu bạn muốn tham chiếu các luồng này với một bộ mô tả tệp, trình bao sẽ nhận ra, jiliagre đã đúng khi bạn sử dụng tên /dev/stdinhoặc /dev/stdoutthay vào đó. Những tên tệp đó sẽ hoạt động ở bất kỳ nơi nào mà một tên tệp bình thường sẽ hoạt động.

  1. Điều đó đang được nói, ví dụ đầu tiên của bạn là loại ngớ ngẩn. Bất kỳ đầu ra nào được toán tử chuyển hướng bắt để ghi vào một tệp đã BẬT đầu ra tiêu chuẩn, do đó, chuyển hướng nó và ghi lại nó đến nơi nó đến là vô ích. Hành vi bạn sử dụng là đường ống, không phải là chuyển hướng:

    echo hello |
  2. Trong ví dụ thứ hai của bạn, bạn chỉ cần đưa ra một số dấu hiệu cho thấy bạn muốn có một tệp rác của tên đó, chứ không phải bí danh nội bộ mà nó có. Bạn có thể làm điều này dễ nhất bằng cách chỉ định đường dẫn đến tệp như thế này:

    cat ./-

6

Đối với 1, chương trình phải hỗ trợ nó. Bạn không thể tự ý sử dụng nó. Đối với 2, chuyển hướng đầu vào từ (ví dụ, cat < -).


1

Cách tiếp cận '-' có rất nhiều vấn đề. Trước hết, nó đòi hỏi một sự giải thích về nhân vật '-' và nhiều chương trình không thực hiện việc giải thích như vậy. Và hơn nữa, có một số chương trình diễn giải một dấu gạch nối là dấu phân cách đánh dấu sự kết thúc của các tùy chọn dòng lệnh. Các chương trình được viết để hoạt động với các đối số tên tệp, cách tiếp cận '-' là một hack, đẹp nhưng yếu.

Cách tốt nhất là:

$ echo hello > /dev/fd/1

/dev/stdout là một liên kết tượng trưng của /dev/fd/1


Chuyển hướng được giải thích bởi shell chứ không phải chương trình được gọi.
sherrellbc
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.