/bin/sh:通配符扩展在脚本中不起作用

/bin/sh:通配符扩展在脚本中不起作用

我正在使用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

为什么模式扩展(通配符匹配)在我的脚本中不起作用?

答案1

文件名通配不会发生在像这样的分配中

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

在你的代码中出现要工作,您会得到预期的输出,因为您没有引用 的扩展$SSH_AUTH_SOCK。您的sh -c脚本所做的是将文字字符串分配/tmp/ssh-????????????/agent.*SSH_AUTH_SOCK,然后当您使用不带引号的该变量时,shell 会应用通配符echo

当您在命令行上尝试它(echo $SSH_AUTH_SOCK打印文字模式)时,它的行为方式不同的原因可能是因为您可能正在使用 shell (它以不同的方式执行这些操作),或者您在 shell 中zsh使用了set -f关闭文件名通配,或者根本没有匹配的路径名。

如果您想做类似您所提议的事情,那么使用

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

首先将位置参数设置为与给定模式(按词法顺序)匹配的所有路径名。然后它分配第一的这些路径名到变量SSH_AUTH_SOCK

如果没有路径名与模式匹配,则模式将保持未展开状态,稍后按原样分配给变量。

bashshell 中,您可以使用命名数组来代替位置参数:

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

相关内容