Shell

/bin/sh:萬用字元擴展在腳本中不起作用

  • August 5, 2021

我正在使用dashas /bin/sh。在我的腳本中,我有以下行:

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

哪個應該匹配 file /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

為什麼模式擴展(萬用字元匹配)在我的腳本中不起作用?

文件名通配不會發生在諸如

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

在您的程式碼中似乎可以正常工作,您會得到預期的輸出,因為您沒有引用$SSH_AUTH_SOCK. 您的sh -c腳本正在做的是將文字字元串分配/tmp/ssh-????????????/agent.*SSH_AUTH_SOCK,然後當您使用不帶引號的變數時,shell 會應用萬用字元echo

當您在命令行上嘗試它時它的行為方式不同的原因(echo $SSH_AUTH_SOCK列印文字模式)可能是因為您可能正在使用zsh外殼程序(它以不同的方式做這些事情),或者您set -f在外殼程序中使用了轉關閉文件名萬用字元,或者根本沒有匹配的路徑名。

如果您想做類似您提議的事情,請使用

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

這首先將位置參數設置為與給定模式匹配的所有路徑名(按詞法順序)。然後它將這些路徑名中的第一個分配給變數SSH_AUTH_SOCK

如果沒有路徑名與模式匹配,則模式將保持未擴展狀態,然後按原樣分配給變數。

bashshell 中,您可以使用命名數組來代替位置參數:

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

引用自:https://unix.stackexchange.com/questions/663257