我認爲對於你想要做什麼感到困惑。如果我理解正確,那麼這裏的最終目標是運行管道並將輸出捕獲到變量中,對嗎?有點像這樣:
var=$(cmd1 | cmd2)
除了我猜的想法在這裏是「$ VAR」的名字存儲在另一個變量:
varname=var
你可以做一個繞擊通常的最終運行通過使用流程替代來控制工作情況。因此,而不是這種正常的管道(這將在KSH或zsh的工作,而不是在bash,除非你設置lastpipe):
cmd1 | cmd2 | read "$varname"
你可以使用這個命令,這是從殼如何處理工作分開相當於:
read "$varname" < <(cmd1 | cmd2)
通過進程替換,「read $ varname」不在管道中運行,因此Bash不會運行它。 (你可以使用你的streamStdInTo()函數有作爲,當然)
據我瞭解,你想通過使用數字文件描述符來解決這個問題:
cmd1 | cmd2 >&$fd1 &
read "$varname" <&$fd2
創建這些文件描述符將管道後臺作業連接到「讀取」命令,您需要將其稱爲管道或FIFO。這些可以被創建而不需要接觸文件系統(shell一直在做!)但是shell並沒有直接公開這個功能,這就是爲什麼我們需要使用mkfifo來創建一個命名管道。命名管道是存在於文件系統上的一個特殊文件,但是您寫入的數據不會存入磁盤。這是存儲在內存中的數據隊列(管道)。它並不需要留在文件系統中你打開後,無論是,它幾乎可以立即刪除:
pipedir=$(mktemp -d /tmp/pipe_maker_XXXX)
mkfifo ${pipedir}/pipe
exec {temp_fd}<>${pipedir}/pipe # Open both ends of the pipe
exec {fd1}>${pipedir}/pipe
exec {fd2}<${pipedir}/pipe
exec {temp_fd}<&- # Close the read/write FD
rm -rf ${pipedir} # Don't need the named FIFO any more
一個在外殼使用命名管道工作的困難是,試圖打開他們只是爲了閱讀,或者僅僅爲了寫作而導致呼叫阻塞,直到打開管道的另一端。在嘗試打開另一端之前,可以通過在後臺作業中打開一端來解決該問題,或者像上述那樣一次打開兩端。
「{fd} < ...」語法將未使用的文件描述符編號動態分配給變量$ fd,並在該文件描述符上打開該文件。它的年齡(自1993年以來)一直在ksh左右,但在Bash中,我認爲它只能回到4.1(從2010年)。
嘿,那裏,謝謝你的回答,我在這裏遇到的問題似乎是雞和雞蛋/ bootstrap場景。即,如果文件描述符已經打開並且被映射到流,那麼按照你所說的那樣執行FD4的命令的方向是好的。儘管我想做的事情是將流水線的末端流式傳輸到變量中,但使用文件描述符來避免子外殼問題,但是,似乎我無法通過映射到未知問題來初始化問題的任何一端,分配的文件描述符。所以,說我映射fd 4到一個文件,那麼它會一切正常,我可以流入和流出罰款... – user4838443
我的問題是直接去,如何使用兩個事情之間映射一個未使用的文件描述符?如果我需要在一端打開它,然後才能在另一端打開,那麼我該怎麼做?我真的很感激任何人的想法! – user4838443
假設我有一個流水線,如下所示:'$ printf'\ n \ n123 \ n456 \ n524 \ n789 \ n \ n \ n'| grep 2',我想通過文件描述符將值傳遞給當前shell中的變量,以避免子shell問題。考慮到試圖在流水線結束時或者在等式的變量賦值一端分配給未使用的FD,我怎麼做這些,不要讓我使用先前未分配的文件描述符來做到這一點。 – user4838443