子外殼和程序替換
如果這是一個基本問題,我深表歉意——我一直試圖解決一個更大的問題,這歸結為如何呼叫 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 來解釋它,如zsh
或bash
AT&Tksh
(當然,您需要確保腳本的其餘語法也與該 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