如何將標準輸出發送到多個命令?
有一些命令過濾或作用於輸入,然後將其作為輸出傳遞,我認為通常是這樣
stdout
- 但有些命令只會接受stdin
並做任何他們用它做的事情,並且什麼也不輸出。我對 OS X 最熟悉,因此立即想到兩個是
pbcopy
和pbpaste
- 是訪問系統剪貼板的方法。無論如何,我知道如果我想獲取標準輸出並將輸出吐到兩者
stdout
和一個文件中,那麼我可以使用該tee
命令。而且我知道一點點xargs
,但我不認為那是我正在尋找的。我想知道如何拆分
stdout
以在兩個(或更多)命令之間進行。例如:cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors
可能有一個比那個更好的例子,但我真的很想知道如何將標準輸出發送到一個不中繼它的命令,同時避免
stdout
被“靜音”——我不是在問如何cat
文件和grep
它的一部分並將其複製到剪貼板 - 具體的命令並不重要。另外-我不是在問如何將其發送到文件,而且
stdout
-這可能是一個“重複”的問題(對不起),但我做了一些查找,只能找到類似的詢問如何在標準輸出和文件之間拆分的問題- 這些問題的答案似乎是tee
,我認為這對我不起作用。最後,您可能會問“為什麼不把 pbcopy 放在管道鏈中的最後一件事呢?” 我的回答是 1)如果我想使用它並且仍然在控制台中看到輸出怎麼辦?2)如果我想使用兩個
stdout
在處理輸入後不輸出的命令怎麼辦?哦,還有一件事——我意識到我可以使用
tee
命名管道(mkfifo
),但我希望有一種方法可以簡潔地內聯完成,而無需事先設置:)
您可以
tee
為此使用和處理替換:cat file.txt | tee >(pbcopy) | grep errors
這將發送
cat file.txt
to的所有輸出pbcopy
,並且您只能grep
在控制台上獲得結果。您可以在零件中放置多個程序
tee
:cat file.txt | tee >(pbcopy) >(do_stuff) >(do_more_stuff) | grep errors
您可以為 指定多個文件名
tee
,此外,標準輸出可以通過管道傳輸到一個命令中。要將輸出分派給多個命令,您需要創建多個管道並將每個管道指定為tee
. 有幾種方法可以做到這一點。流程替代
如果你的 shell 是 ksh93、bash 或 zsh,你可以使用程序替換。這是一種將管道傳遞給需要文件名的命令的方法。shell 創建管道並將文件名傳遞
/dev/fd/3
給命令。該數字是管道連接到的文件描述符。一些 unix 變體不支持/dev/fd
; 在這些上,改用命名管道(見下文)。tee >(command1) >(command2) | command3
文件描述符
在任何 POSIX shell 中,您都可以顯式使用多個文件描述符。這需要一個支持 的 unix 變體
/dev/fd
,因為除一個輸出之外的所有輸出都tee
必須按名稱指定。{ { { tee /dev/fd/3 /dev/fd/4 | command1 >&9; } 3>&1 | command2 >&9; } 4>&1 | command3 >&9; } 9>&1
命名管道
最基本和可移植的方法是使用命名管道。缺點是你需要找到一個可寫的目錄,創建管道,然後清理。
tmp_dir=$(mktemp -d) mkfifo "$tmp_dir/f1" "$tmp_dir/f2" command1 <"$tmp_dir/f1" & pid1=$! command2 <"$tmp_dir/f2" & pid2=$! tee "$tmp_dir/f1" "$tmp_dir/f2" | command3 rm -rf "$tmp_dir" wait $pid1 $pid2