Process-Substitution

子外殼和程序替換

  • May 10, 2017

如果這是一個基本問題,我深表歉意——我一直試圖解決一個更大的問題,這歸結為如何呼叫 shell 腳本——直接(shellScript.sh)或使用sh shellScript.sh.

這是解決問題的模型:

當我在 bash 上執行時:

cat <(echo 'Hello')

我看到了輸出

Hello

但是當我使用:

sh -c "cat <(echo 'Hello')"

我看到錯誤:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `cat <(echo 'Hello')'

我嘗試以各種組合轉義<,(),但在任何地方都看不到輸出。我在這裡想念什麼?

我的實際問題是我將 a<()作為輸入參數傳遞給 shell 腳本中的 python 腳本,雖然當我只使用名稱呼叫 shell 腳本時它工作正常,但如果我sh用來呼叫它,我會得到類似的錯誤到我上面展示的內容。

謝謝!

程序替換是一個起源於 80 年代 Korn shell(在 ksh86 中)的特性。當時,它僅在支持/dev/fd/<n>文件的系統上可用。

後來,該功能被添加到zsh(從開始:1990 年)和bash(1993 年)。zsh正在使用臨時命名管道來實現它,而在可用的地方使用命名管道,否則bash使用命名管道。1996 年改用可用的地方。/dev/fd/<n>``zsh``/dev/fd/<n>``2.6-beta17

僅在2012/dev/fd年才在系統上通過命名管道來支持程序替換,但不支持它的公共域複製。ksh``ksh93u+``ksh

據我所知,沒有其他類似 Bourne 的 shell 支持它(rc, es, fish, 非類 Bourne 的 shell 支持它,但語法不同)。yash有一個<(...)構造,但那是用於程序重定向的。

雖然非常有用,但該功能從未被 POSIX 標準化。所以,不能指望在 中找到它sh,所以不應該在sh腳本中使用它。

儘管<(...)在 POSIX 中未指定 for 的行為(因此保留它不會有任何害處),但在呼叫 as或在其環境中呼叫 withbash時會禁用該功能。sh``POSIXLY_CORRECT=1

因此,如果您有一個使用 的腳本<(...),您應該使用支持該功能的 shell 來解釋它,如zshbashAT&T ksh(當然,您需要確保腳本的其餘語法也與該 shell 兼容)。

任何狀況之下:

cat <(cmd)

可以寫成:

cmd | cat

要不就

cmd

對於除cat(需要通過作為參數給出的文件傳遞數據)以外的命令,在具有 的系統上/dev/fd/x,您始終可以執行以下操作:

something | that-cmd /dev/stdin

或者,如果您需要that-cmd保留 的標準輸入:

{ something 3<&- | that-cmd /dev/fd/4 4<&0 <&3 3<&-; } 3<&0 

引用自:https://unix.stackexchange.com/questions/364002