2013-06-24 38 views
8

Đây chỉ là câu hỏi giả định - không giải quyết bất kỳ vấn đề thực sự nào - chỉ học bash.Dán kết quả của lệnh tee

Với lệnh tee có thể chia đầu ra để dòng khác nhau hơn, như:

command1 | tee >(commandA1 | commandA2 >file1) >(commandB1 | commandB2 >file2) >file0 

nên đồ họa được thực hiện tiếp theo

    ---commandA1---commandA2--> file1 
       /
command1---tee-------> file0 
       \ 
        ---commandB1---commandB2--> file2 

Bây giờ, với lệnh paste có thể ví dụ

paste file1 file2 | command3 

nhưng một lần nữa tôi có thể chuyển hướng đến dán đầu ra từ một chương trình khác nhau, như:

paste <(ls) <(ls) | command3 

Câu hỏi đặt ra là: có thể phần nào tham gia vào hai luồng lại thành một, một cái gì đó giống như

    ---commandA1---commandA2--- 
       /       \ 
command1---tee-------> file0     --- paste---command3 
       \       /
        ---commandB1---commandB2--- 

Ps: có nghĩa là không có tệp trung gian ...

+5

Không phải không có một file trung gian hoặc tên ống. Xem 'mkfifo' – SheetJS

+3

Đây là một loại câu hỏi mà tôi thích nhìn thấy - phần nào, cái gì không tầm thường. Thật không may, tôi không biết bash đủ sâu để cho thấy làm thế nào để đạt được điều này với "tên ống" như @Nirk đề nghị ... +1 – kobame

Trả lời

3

Đây là cách thực hiện với tên p ipes:

trap "rm -f /tmp/file1 /tmp/file2; exit 1" 0 1 2 3 13 15 
mkfifo /tmp/file1 
mkfifo /tmp/file2 
command1 | tee >(commandA1 | commandA2 >/tmp/file1) >(commandB1 | commandB2 >/tmp/file2) >file0 
paste /tmp/file1 /tmp/file2 | command3 
rm -f /tmp/file1 /tmp/file2 
trap 0 

dụ làm việc:

$ cd -- "$(mktemp -d)" 
$ trap "rm -f pipe1 pipe2; exit 1" 0 1 2 3 13 15 
$ mkfifo pipe1 pipe2 
$ printf '%s\n' 'line 1' 'line 2' 'line 3' 'line 4' | tee \ 
>(sed 's/line /l/' | head -n 2 > pipe1) \ 
>(sed 's/line /Line #/' | tail -n 2 > pipe2) \ 
> original.txt 
$ paste pipe1 pipe2 | sed 's/\t/ --- /' 
l1 --- Line #3 
l2 --- Line #4 
$ rm pipe1 pipe2 
$ trap 0 
+0

Tôi đã không viết nó, @ Jonathanathanffler thêm rằng (trước khi bạn thêm ví dụ làm việc) . – Barmar

+0

@ l0b0: 'thoát 1' trong bẫy để cho biết rằng quá trình không thành công; 'exit 0' sẽ tạo ra ấn tượng gây hiểu lầm rằng quá trình đã thành công. Và không thêm 'exit' có nghĩa là 'thoát với trạng thái của lệnh cuối cùng, sẽ là' rm -f', thành công, vì vậy trạng thái thoát sẽ là 0. 'trap' đảm bảo rằng các FIFO tạm thời được loại bỏ khi trình bao có thể xóa chúng. Nếu bạn giết quá trình bằng 'kill -9', không có gì có thể làm để dọn dẹp. Nhưng nếu bạn sử dụng HUP, INT, QUIT, PIPE hoặc TERM (1, 2, 3, 13, 15), thì trình bao sẽ dọn dẹp phía sau chính nó trước khi thoát. –

+0

@JonathanLeffler Điều khó hiểu là bạn bao gồm '0' trong danh sách các tín hiệu mà bạn bẫy, có nghĩa là nó sẽ chạy trong khi thoát bình thường và biến nó thành lối ra không thành công. Nhưng điều đó thực sự sẽ không xảy ra vì bạn vô hiệu hóa bẫy khi thoát với 'trap 0' ở cuối, vì vậy không có điểm nào trong lệnh bẫy gốc này. – Barmar

Các vấn đề liên quan