Bash

在 zsh 中模擬 bash 破壞動態分配的文件描述符

  • September 18, 2020

如本文所述,我在腳本中使用動態分配的文件描述符:

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(或任何以sor b(對於Bourne)開頭的內容)傳遞給emulate,它將使用sh仿真模式:

$ emulate bash -c emulate
sh

zsh的仿真模式是zsh(預設)、sh(最初主要是 SysV/Bourne sh,現在更多的是 POSIX shcshksh.

bash是一個主要與 POSIXsh兼容的 shell,但擴展大部分來自 Korn shell,因此要zsh解釋bash使用非 POSIX 擴展的程式碼,最好的選擇是 ksh 仿真(您可能還希望啟用BASH_REMATCH預期的選項為了bash兼容性)。

{fd}<功能實際上來自zsh. 它是在3 種 shell 的維護者之間的討論zshksh93同時bash根據一位 zsh 開發人員的建議在 3 中實現的。

echo {fd}< /dev/nullPOSIX 要求輸出{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’s emulatebuiltin,您可以執行info zsh emulate,或從 inside ,info zsh索引,然後輸入(可以使用製表符完成)。在某些系統上,您可能需要安裝一個包或等效項,因為預設情況下並不總是安裝資訊文件。I``emulate``zsh-doc

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