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]}