Có thể chuyển hướng đầu ra của một lệnh thành nhiều hơn một lệnh không?


21

Theo như tôi biết, tôi có thể sử dụng lệnh tee để phân chia đầu ra tiêu chuẩn lên màn hình và các tệp khác:

command -option1 -option2 argument | tee file1 file2 file3 

Có thể chuyển hướng đầu ra thành các lệnh thay vì các tệp bằng tee, để theo lý thuyết tôi có thể tạo ra một chuỗi các lệnh không?


3
Giải thích ý của bạn bằng "tín hiệu đầu ra" và mô tả ý của bạn bằng cách tạo ra một "mạng lệnh".
Janis

trong linux mỗi lệnh có một đầu vào và hai đầu ra. chúng được gắn nhãn 0 (cho đầu vào), 1 (cho đầu ra) và 2 (cho đầu ra lỗi). Tôi đã nghĩ đến 1 khi tôi nói "tín hiệu đầu ra" bởi vì tôi đọc rằng lệnh tee chỉ chia tách đầu ra có nhãn 1. Khi tôi nói "mạng lệnh" Tôi không rành lắm về kỹ thuật, tôi không chắc mạng được định nghĩa chính xác từ một quan điểm toán học, nhưng tôi chỉ đơn giản nghĩ về một cây lệnh nói theo kiểu chữ, để một số lệnh có thể là cha mẹ của nhiều lệnh con.
Abdul Al Hazred

Cảm ơn bạn đã làm rõ. Vui lòng không sử dụng tín hiệu từ vì nó có ý nghĩa cụ thể trong Unix và thuật ngữ này rất sai lệch trong ngữ cảnh này. Cảm ơn một lần nữa.
Janis

Tại dòng lệnh nhập tín hiệu man -k để tìm hiểu ý nghĩa đặc biệt của khái niệm khóa này trong UNIX và Linux. man kill sẽ là một trang tốt để bắt đầu.
Rob

Ngoài ra, nhiều người gọi stdin stdout và stderr là đầu vào hoặc đầu ra 'luồng'. Có những dòng dữ liệu nhỏ như một dòng chảy. Bạn đã đúng khi vật lộn với một từ để mô tả chúng một cách tập thể nhưng tín hiệu chỉ là từ sai.
Rob

Câu trả lời:


25

Bạn có thể sử dụng các ống có tên ( http://linux.die.net/man/1/mkfifo ) trên dòng lệnh của teevà có các lệnh đọc trên các ống được đặt tên.

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

Khi commandkết thúc, teesẽ đóng các đường ống được đặt tên, nó sẽ báo hiệu EOF (đọc 0 byte) trên mỗi đường ống /tmp/dataNthường kết thúc các cmdNtiến trình. Ví dụ thực tế:

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

Do các quá trình nền, shell trả về một dấu nhắc trước khi xuất chương trình. Tất cả ba trường hợp wcchấm dứt bình thường.


1
Trong bash , bạn có thể an toàn rất nhiều gõ qua /tmp/data/{0,1,2}. Sau đó, một lần nữa, trong bash, bạn có thể sử dụng thay thế quy trình và bỏ qua mkfifohoàn toàn
Tobias Kienzler 9/03/2015

2
Có thể muốn thay đổi / dev / data0 thành / tmp / data0. Ngoài ra, cảm ơn vì đã trả lời câu hỏi theo cách không rõ ràng. Điều đó hữu ích hơn là giả sử mọi người đang sử dụng bash.
abonet

15

Nếu tôi hiểu đúng, bạn đang tìm kiếm tương đương tee file1 file2 file3, nhưng thay vì ghi cùng một dữ liệu để ba tập tin file1, file2file3, bạn muốn ống cùng một dữ liệu vào ba lệnh cmd1, cmd2cmd3, tức là

… | ??? cmd1 cmd2 cmd3

nên tương đương với

… | cmd1 &
… | cmd2 &
… | cmd3 &

ngoại trừ điều đó sẽ chỉ được thực hiện một lần.

Có hai cách để làm điều đó.

Ksh93, bash và zsh hỗ trợ thay thế quá trình . Đây là một khái quát của các đường ống cho phép đối số của lệnh là một tệp mà khi được ghi vào sẽ truyền dữ liệu dưới dạng đầu vào cho lệnh (cũng có biến thể đầu vào, khi đọc từ đó, có được đầu ra dữ liệu bằng lệnh) . Đó là,

echo hello | tee >(cmd1)

in hellora đầu ra tiêu chuẩn và ngoài ra chạy cmd1với hellođầu vào.

Vì vậy, ví dụ, nếu bạn muốn sao chép đầu vào của somecommandvà chuyển nó cho cả hai cmd1cmd2, bạn có thể sử dụng

somecommand | tee >(cmd1) | cmd2

Nếu vỏ của bạn không hỗ trợ thay thế quá trình, bạn có thể sử dụng đường ống có tên thay thế. Xem câu trả lời của Arcege để biết cách thức hoạt động. Các ống được đặt tên ít thuận tiện hơn so với thay thế quy trình vì bạn phải tạo và xóa chúng, đồng thời bắt đầu và đồng bộ hóa các quy trình theo cách thủ công. Chúng có lợi thế là hoàn toàn di động, trong khi không phải tất cả các vỏ đều hỗ trợ quá trình thay thế. Chúng cũng có thể được sử dụng trong các tình huống khác với quy trình thay thế.

Dưới mui xe, trên một số hệ thống, quy trình thay thế sử dụng các ống được đặt tên trong nội bộ. Tuy nhiên, trên hầu hết các hệ thống, nó phụ thuộc vào các tệp được đặt tên đại diện cho các mô tả tệp .


5
Xem thêm peetừ moreutils.
Stéphane Chazelas

Lưu ý rằng quá trình thay thế đã được giới thiệu bởi ksh88.
Stéphane Chazelas

6

Ít nhất trong bạn có thể bỏ qua mkfifosử dụng thay thế quá trình:

command -option1 -option2 argument | tee >(cmd1) >(cmd2) >(cmd3)

hoặc chấp nhận ví dụ của Arcege

tee >(wc -l) >(wc -w) >(wc -c) < /etc/passwd >/dev/null

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.