/bin/sh: ワイルドカード拡張がスクリプトでは機能しません。

/bin/sh: ワイルドカード拡張がスクリプトでは機能しません。

dashで使用しています/bin/sh。私のスクリプトには次の行があります。

SSH_AUTH_SOCK=/tmp/ssh-????????????/agent.*

これはファイルと一致する必要があります/tmp/ssh-abcdefghijkl/agent.1234。ファイルが存在しても、スクリプトはパターンを拡張せず、代わりに変数にリテラルパターンを含めます。

echo $SSH_AUTH_SOCK
/tmp/ssh-????????????/agent.*

ただし、コマンドラインで同じ操作を実行するとパターンが拡張されます。

sh -c 'SSH_AUTH_SOCK=/tmp/ssh-????????????/agent.* ; echo $SSH_AUTH_SOCK'
/tmp/ssh-abcdefghijkl/agent.1234

私のスクリプトでパターン拡張(ワイルドカードマッチング)が機能しないのはなぜですか?

答え1

このような割り当てでは、ファイル名のグロービングは発生しません。

SSH_AUTH_SOCK=/tmp/ssh-????????????/agent.*

あなたのコードから現れる作業するには、引用符付きの拡張子がないため、予想される出力を取得します$SSH_AUTH_SOCK。スクリプトsh -cが実行する作業は、リテラル文字列を割り当ててから変数を引用/tmp/ssh-????????????/agent.*SSH_AUTH_SOCKなしで使用すると、シェルがワイルドカードを適用することですecho

コマンドライン(echo $SSH_AUTH_SOCK印刷リテラルモード)で試しても動作が異なるのは、おそらくシェルを使用しているか(これは別の方法で実行されます)、シェルで閉じるファイルをzsh使用しているためです。名前は次のとおりです。set -fワイルドカードで指定されたパスまたは一致するパス名がまったくありません。

あなたが提案したものと似たようなことをしたい場合は、以下を使用してください。

set -- /tmp/ssh-????????????/agent.*
SSH_AUTH_SOCK=$1

位置引数は、最初に指定されたパターン(語彙順)に一致するすべてのパス名に設定されます。その後、割り当てます最初変数のパス名SSH_AUTH_SOCK

パターンと一致するパス名がない場合、パターンは拡張されていないままになり、後で変数にそのまま割り当てられます。

シェルでは、bash位置引数の代わりに名前付き配列を使用できます。

names=( /tmp/ssh-????????????/agent.* )
SSH_AUTH_SOCK=${names[0]}

関連情報