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

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

{var}>&1inに該当するものはありますかzsh

これbash手動説明する:

各リダイレクトの前にファイルディスクリプタ番号を付けることができますが、次の形式の単語を前に付けることもできます{varname}。この場合>&-とを除くすべてのリダイレクト演算子に対して、<&-シェルは10より大きいファイル記述子を割り当ててそれに割り当てます{varname}>&-または、<&-前に来る場合、{varname}varname 値は閉じるファイル記述子を定義します。

使用法の例は、STDERR次のコマンドでキャプチャされます。

{ error=$( { { ls -ld /XXXX /bin | tr o Z ; } 1>&$tmp ; } 2>&1); } {tmp}>&1

zshPOSIXの世界で同じことをする方法は?

一般的な解決策を探しています。どうすればいいですか?

  • 未使用のファイル記述子の検索
  • シミュレーション{var}>&1構文

ベストアンサー1

開発者の提案に従って{var}>...サポートも追加されましたksh93。この演算子は複合コマンドで動作しますが、動作しません。bashzshzsh{var}>...zsh

以下も参考にしてください。

cmd 3>&1

fd 3 はcmd次にのみ開いています。

cmd {var}>&1

動的に割り当てられた fd ( に保存されている) は、$varに返された後も開いたままです。この演算子は基本的に一緒に使用するように設計されています(簡単なシステムコールインターフェイスも参照)。cmdzshbashexecsysopenzshopen()

したがって、上記のコードexec {tmp}>&-ではbash

だからここで行うことができます:

if exec {tmp}>&1; then
   errors=$(exec 2>&1 >&"$tmp" {tmp}>&- && ls -ld /x /bin | tr o Z)
   exec {tmp}>&-
fi

これはで動作し、fdbashをリークしません。 (引用符は、対応するオプションが有効になっていない場合にのみ必要です)。 POSIXモードでまたは途中で失敗すると、シェルは終了します(ここで、失敗はstdoutが閉じられたファイル、開かれたファイル数の制限に達した、または終了しようとする他の病理学的条件によって引き起こされる可能性があります)。zshksh93$tmpbashposixksh93zshbashexecdup()

ただし、ここでは動的に割り当てられたfdを必要とせず、そのコードで使用されていないfd 3を使用するだけです。

{ errors=$(exec 2>&1 >&3 3>&-; ls -ld /x /bin | tr o Z); } 3>&1

これはBourneのようなシェルで動作します。

上記の動的fdメソッドと同様に、明確ではない場合でもdup2()(in)失敗すると割り当て3>&1は実行されないため、以前に初期化されていることをerrors確認することをお勧めします(例unset -v errors:)。

fd 3が別の方法で開かれるか、スクリプトの残りの部分で使用されるかは重要ではありません(開くと、元のfdはそのまま残り、最後に復元されます)。重要なのは、埋め込みコードが内部的に$(...)fd 3を期待しているかどうかです。開いている。

fd 0、1、2のみがアプリケーションで開かれると予想され、他のfdは開かれません。lsそしてtrfd3には何も期待しないでください。他のfdを使用する必要がある状況は次のとおりです。明らかにfdを使用してifのように事前に開いていると予想する代わりに、fd 3がスクリプトでより早く開かれたと予想されるリソースがlsあります。cat /dev/fd/3

POSIXシェルで最初の無料fdを割り当てる方法に関する質問に答えるには、POSIXシェルとユーティリティAPIには方法がないと思います。これも言えないかもしれません。シェルは、独自のAPIを妨げない限り、内部的にすべてのfdを使用して必要な操作を実行できます。たとえば、fd 11 は今は無料ですが、後で内部操作のためにシェルで使用でき、fd 11 に書き込むと動作に影響を与える可能性があります。また、POSIX shではfds 0から9までしか操作できません。

おすすめ記事