Hiểu cách các đầu vào được gửi đến các đường ống trong Bash


17

Tôi hoàn toàn không hiểu làm thế nào các đường ống làm việc trong bash.

Tôi biết rằng nó nhận một đầu ra từ một lệnh làm đầu vào trong một lệnh khác.

Tôi có thể nhận được kết quả đầu ra vì đó là những gì lệnh in ra màn hình.

Nhưng làm thế nào để tôi biết đầu vào của lệnh sẽ mất gì?

Đây là một ví dụ tôi nghĩ sẽ làm việc:

which gem | rm

Thật không may, nó đã không.

Đá quý nào in ra /usr/bin/gemsao cho phải là đầu ra phải không?

Tôi nghĩ rằng nó đã được trao cho rm vì vậy nó sẽ được rm /usr/bin/gemnhưng tôi đã sai.

Vì vậy, câu hỏi của tôi là, làm thế nào để tôi biết lệnh đầu vào mất gì?


2
Ngoài bất cứ điều gì khác, rm /usr/bin/gemlà một ý tưởng khủng khiếp . Để nó gem(và trình thông dịch Ruby đi cùng) và cài đặt trình thông dịch Ruby ưa thích của bạn (và gem) bằng cách sử dụng rvm: rvm.beginrescueend.com
Telemachus

Câu trả lời:


23

"Đầu vào" và "đối số dòng lệnh" là những thứ khác nhau.

rm loại bỏ các tập tin được cung cấp như là đối số.

Một đường ống chuyển hướng đầu ra của lệnh bên trái sang đầu vào của lệnh bên phải. Nó không ảnh hưởng đến các đối số dòng lệnh của chương trình bên phải.

Để thực hiện những gì bạn đang cố gắng thực hiện, hãy thử sử dụng xargsđể chuyển đổi đầu vào tiêu chuẩn thành đối số dòng lệnh để thực hiện chương trình. Đó là công việc của nó.

which gem | xargs rm, ví dụ, sẽ loại bỏ gemtrong PATH của bạn.


12

rmkhông lấy đầu vào, nó cần đối số. Đây là khác nhau. Đối số là các công tắc và tên tệp và do đó bạn cung cấp cho một chương trình trên dòng lệnh để ảnh hưởng đến hành vi của nó. Đầu vào là dữ liệu mà chương trình hoạt động. Ví dụ: greplấy cả đầu vào và đối số:

grep "foo" file.txt

Có hai đối số ở đó "foo"file.txt. Đầu vàonội dung của file.txt, không phải file.txtchính chuỗi . Vì grep lấy đầu vào, bạn có thể sử dụng nó với các đường ống:

cat file.txt | grep "foo"

sản xuất đầu ra tương tự, kể từ khi con mèo đang file.txtlà một cuộc tranh cãi, và sản xuất các nội dung của file.txtnhư đầu ra. Đầu ra đó sau đó được dẫn vào grep, mang lại hiệu quả tương tự như việc grep mở tệp chính nó, như trong ví dụ đầu tiên.

Nếu bạn muốn sử dụng đầu ra của một chương trình làm đối số cho chương trình khác, bạn sử dụng backticks:

rm `which gem`

hoặc cú pháp thay thế (bash-cụ thể) này:

rm $(which gem)

Chỉnh sửa: hoặc xargsnhư một người trả lời khác chỉ ra. Nhiều cách để lột da một con mèo bằng một dòng lệnh.


Điều đáng chú ý là cat file.txt | grep "foo"có thể chậm hơn hàng trăm lần grep "foo" file.txt.
Borealid

1
đây là phần tôi không nhận được Làm thế nào để tôi biết thế nào là một đối số và đầu vào tiêu chuẩn là gì?
ajsie

8
@ajsie: Nếu bạn nhập nó sau tên chương trình và trước khi nhấn enter, đó là một đối số. Nếu bạn nhập nó vào chương trình sau khi nó bắt đầu chạy, thì đó là đầu vào tiêu chuẩn.
Borealid

1
Hiểu rồi! Điều này giải thích mọi thứ. Bây giờ tôi biết tôi có thể sử dụng lệnh trực tiếp và xem liệu nó có nhắc tôi (grep) không và tôi cũng có thể đọc hướng dẫn (man grep) để xem liệu nó có sử dụng đầu vào std không.
ajsie

@ajsie: Nếu bạn không muốn đi sâu vào trang này, cũng có grep --helpmột cái nhìn tổng quan nhanh về các đối số được chấp nhận.
Borealid

3

Kiểm tra các mantrang của lệnh bạn quan tâm. Các chương trình này sẽ cho biết họ đã đọc từ stdin(thử man grepmột lệnh phổ biến đọc stdin).


Tôi đã thử man grep | grep 'standard input'và có được If no file arguments are specified, the standard input is used.như trận đấu cuối cùng. Tôi đã phải cho grepmột chút hương vị của thuốc của nó. 😎
ma11hew28

2

Tất cả đều nguy hiểm khi chạy nếu bạn có một thư mục trong PATH chứa khoảng trắng hoặc nếu tên lệnh chứa khoảng trắng:

rm `which gem`       # Dangerous
rm $(which gem)      # Dangerous
which gem | xargs rm # Dangerous

GNU Parallel http: // www.gnu.org/software/pool/ không có vấn đề đó, vì vậy điều này sẽ hoạt động ngay cả khi bạn có một thư mục trong PATH chứa khoảng trắng hoặc nếu tên lệnh chứa khoảng trắng:

which gem | parallel rm
parallel -a <(which bass) rm

Xem video giới thiệu về GNU Parallel: http://www.youtube.com/watch?v=OpaiGYxkSuQ

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.