在 zsh 中模擬 bash 破壞動態分配的文件描述符
如本文所述,我在腳本中使用動態分配的文件描述符:
zsh 和 POSIX 等效於 bash 的
{var}>&1
腳本本身可以在 bash 和 zsh 之間移植,因此
emulate -LR bash
如果腳本檢測到它正在 zsh 中執行,則會儘早執行。不幸的是,這是破壞性的
exec {fd}>&...
,它已經在 zsh 和 bash 中支持了相當長的一段時間。為了說明,這個腳本成功了(也適用於 bash):
#!/usr/bin/env zsh set -euo pipefail for i in {1..10}; do exec {fd}> >( tee /dev/stderr | logger ) echo "FD: ${fd}" >&"${fd}" done
但這不會:
#!/usr/bin/env zsh set -euo pipefail emulate -LR bash for i in {1..10}; do exec {fd}> >( tee /dev/stderr | logger ) echo "FD: ${fd}" >&"${fd}" done
command not found: {fd}
任何人都可以指出我
emulate -R bash
在引擎蓋下的功能的完整列表(也許我忽略了它,但我無法找到真正的手冊頁emulate
)。或者更好的是,如果有人知道哪個特定選項會導致此問題,那就太好了。提前感謝您的幫助。
zsh
沒有bash
仿真模式。如果您將bash
(或任何以s
orb
(對於Bourne)開頭的內容)傳遞給emulate
,它將使用sh
仿真模式:$ emulate bash -c emulate sh
zsh
的仿真模式是zsh
(預設)、sh
(最初主要是 SysV/Bournesh
,現在更多的是 POSIXsh
)csh
和ksh
.
bash
是一個主要與 POSIXsh
兼容的 shell,但擴展大部分來自 Korn shell,因此要zsh
解釋bash
使用非 POSIX 擴展的程式碼,最好的選擇是 ksh 仿真(您可能還希望啟用BASH_REMATCH
預期的選項為了bash
兼容性)。該
{fd}<
功能實際上來自zsh
. 它是在3 種 shell 的維護者之間的討論zsh
中ksh93
同時bash
根據一位 zsh 開發人員的建議在 3 中實現的。
echo {fd}< /dev/null
POSIX 要求輸出{fd}
(儘管這將在標準的未來版本中發生變化),因此在仿真zsh
中禁用它。sh
它不在ksh
仿真中,所以這就是您要在此處使用的。至於在哪個仿真中啟用了哪個選項(zsh、sh、ksh、csh),請參見手冊中每個選項說明旁邊的
<C>
、<K>
、<S>
、 ( )。<Z>``info zsh 'Description of Options'
影響該
{fd}>...
功能的選項在手冊 (info zsh 'file descriptors, use with parameters'
) 中對該功能的描述中指定:IGNORE_BRACES
其描述 (info zsh IGNORE_BRACES
)<S>
旁邊有一個表示它預設情況下sh
僅在仿真中啟用。雖然
zsh
附帶了手冊頁(其中一些),但手冊頁對於這麼大的手冊來說是相當不足的。我建議info
改用它是超文本並且具有可搜尋的索引和目錄。要了解zsh
’semulate
builtin,您可以執行info zsh emulate
,或從 inside ,info zsh
按索引,然後輸入(可以使用製表符完成)。在某些系統上,您可能需要安裝一個包或等效項,因為預設情況下並不總是安裝資訊文件。I``emulate``zsh-doc