サブシェルとプロセスの交換

サブシェルとプロセスの交換

これが基本的な質問であればお詫び申し上げます。私は、シェルスクリプトが直接(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')'

脱出を試みて<、さまざまな組み合わせで脱出を試みましたがどこにも出力が表示されません。私がここで何を見逃しているのでしょうか?()

私の実際の問題は、<()シェルスクリプト内のPythonスクリプトに入力引数としてaを渡すことです。名前だけを使用してシェルスクリプトを呼び出すと正常に動作しますが、sh私が使用するのと同じエラーが発生します。上に見せてくれました。

ありがとうございます!

答え1

プロセスの交換は、1980年代のKornシェルで始まった機能です(ksh86に最初に文書化されています)。当時は、/dev/fd/<n>ファイルをサポートするシステムでのみ機能しました。

後でこの機能が追加されましたzsh(1990年から)およびbash(1993年から)。zshこれを実装するために一時的な名前付きパイプが使用され、可能であればローカルおよび他の名前付きパイプがbash使用されます。/dev/fd/<n>1996年に利用可能な場所zshに移行しました。/dev/fd/<n>2.6-beta17

/dev/fd名前付きパイプによるシステムのプロセス交換サポートは、2012年にのみ追加されました。パブリックドメインレプリカはこれをサポートしません。kshksh93u+ksh

私が知る限り、他のBourneに似たシェルはそれをサポートしていません(rcBourneに似たシェルes以外のfishシェルはそれをサポートしていますが、構文は異なります)。構造yashがありますが、<(...)それはプロセスリダイレクト

非常に便利ですが、この機能はPOSIXで標準化されていません。shしたがって、 で見つけることが期待できないので、shスクリプトで使用しないでください。

POSIXでは動作は指定されていませんが<(...)(それを維持しても問題ではありません)、その環境でbashasまたはwithを呼び出すとその機能は無効になります。shPOSIXLY_CORRECT=1

したがって、それを使用するスクリプトがある場合、またはAT&Tなどの対応する機能をサポートする<(...)シェルを使用して解釈する必要があります(もちろん、スクリプトの残りの構文が次のようにそのシェルと互換性があることを確認する必要があります)。よく)。zshbashksh

いずれにせよ:

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 

関連情報