zshで動的に割り当てられたファイル記述子のbash破壊をシミュレートします。

zshで動的に割り当てられたファイル記述子のbash破壊をシミュレートします。

この資料に記載されているように、スクリプトは動的に割り当てられたファイル記述子を使用します。

bashの `{var}>&1`に対応するzshとPOSIX

スクリプト自体は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)。または、特定のオプションがこの問題を引き起こすかどうかを知っている人がいる場合は、より良いでしょう。

助けてくれてありがとう。

答え1

zshbashエミュレーションモードがありません。bash(またはまたはsで始まるすべてのものb)(for))〜エミュレーションモードをemulate使用してください。sh

$ emulate bash -c emulate
sh

zshエミュレーションモードはzsh(デフォルト)、sh(元は主にSysV / Bourne sh、現在はPOSIX shcsh、およびですksh

bashは主にPOSIX互換シェルですが、shその拡張はほとんどKornシェルによって提供されるため、POSIX以外の拡張を使用するコードを解釈するzshための最良のオプションはkshエミュレーションです(互換性のために予想されるオプションをbash有効にすることもできます)。BASH_REMATCHbash

この{fd}<機能は実際に出てきました。でzsh同時に実装され、3つのシェルすべての管理者間の議論でzsh開発者の提案に基づいて実装されました。zshksh93bash

echo {fd}< /dev/nullPOSIXには出力が必要です{fd}(たとえこれは標準の将来のバージョンで変更される予定です。)ので、シミュレーションzshでは無効にしてくださいsh。シミュレーションにはないので、kshここで使用する必要があります。

<C>エミュレーション(zsh、sh、ksh、csh)でどのオプションが有効になっているかについては、マニュアルの各オプションの説明の横にある、、、()を参照してください<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何が組み込まれているかを調べるには、を実行するか、press内でemulate実行できます。info zsh emulateinfo zshI索引を押してからEnterを押しますemulate(タブ補完機能を使用できます)。一部のシステムでは、zsh-doc情報文書がデフォルトで常にインストールされるわけではないため、パッケージまたはそれに対応するパッケージをインストールする必要があります。

関連情報