我正在使用dash
as /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
。
如果没有路径名与模式匹配,则模式将保持未展开状态,稍后按原样分配给变量。
在bash
shell 中,您可以使用命名数组来代替位置参数:
names=( /tmp/ssh-????????????/agent.* )
SSH_AUTH_SOCK=${names[0]}