我在命令下运行时遇到问题:
当我运行:cmssh 12np时,我打算调用已定义的函数cmssh,最终我期待一个像这样的shell命令行:
sshpass -p password ssh mydomain\\userxyz@host.com
Run Code Online (Sandbox Code Playgroud)
,见以下来源:
alias 12np='ssh mydomain\\stephencheng@userxyz@host.com'
function cmssh () {
set -x
local aliascmd=$1
cmdstr=$(alias $aliascmd | cut -d'=' -f2 | cut -d"'" -f2)
echo $cmdstr
sshpass -p "$cmpw" $cmdstr
#debug cmdstr : sshpass -p password 'ssh mydomain\\userxyz@host.com'
}
Run Code Online (Sandbox Code Playgroud)
但是,最后一步总是将结果呈现为:
sshpass -p password 'ssh mydomain\\userxyz@host.com'
Run Code Online (Sandbox Code Playgroud)
我试过很多方法试图删除单引号,但不知道它是如何可能的.
请参阅调试信息:
~ cmssh 12np
+cmssh:2> local 'aliascmd=12np'
+cmssh:4> cmdstr=+cmssh:4> alias 12np
+cmssh:4> cmdstr=+cmssh:4> cmdstr=+cmssh:4> cut '-d=' -f2
+cmssh:4> cut '-d'\' -f2
+cmssh:4> cmdstr='ssh mydomain\\userxyz@host.com'
+cmssh:7> echo 'ssh mydomain\\userxyz@host.com'
ssh mydomain\\userxyz@host.com
+cmssh:8> sshpass -p password 'ssh mydomain\\userxyz@host.com'
sshpass: Failed to run command: No such file or directory
Run Code Online (Sandbox Code Playgroud)
谢谢
注意:目前尚不清楚 OP 使用什么特定的 shell。这个答案提出了一般观点,然后讨论bash和zsh。
您眼前的问题与引用无关:错误消息表明可执行文件sshpass不在您的$PATH.
您的字符串 ( $cmdstr) 实际上并不包含单引号 - 它们是runningbash或zshwith set -xin effective的产物。
但是,还有其他问题:
\n\n解析别名定义的方式会将别名定义中的(概念上)cmssh()带引号的单数转换为文字字符串(两个文字字符)。\\\\ \\\\\\\\
在这种情况下,一个简单的修复方法是通过xargs(不带参数)回显字符串来添加另一层评估:
cmdstr=$(alias $aliascmd | cut -d"\'" -f2 | xargs)\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,我已经删除了不需要的=基于 - 的命令。cut
但一般来说,以这种方式解析别名定义是脆弱的。
\n\n那时,我希望您的代码可以在 中工作bash,尽管还不能在(见下文)中工作。\n请注意,只需从函数定义的开头zsh删除即可使您的代码也可以在(仅限 POSIX 功能的 shell)中工作。function\xc2\xa0sh
最后的问题仅影响zsh,而不影响bash:
zsh默认情况下,不会$cmdstr在sshpass -p "$cmpw" $cmdstr命令中执行分词,因此它\'ssh mydomain\\userxyz@host.com\'作为 SINGLE 参数传递给sshpass.
要在求值时打开分词$cmdstr,从而将其标记作为单独的参数传递,请将其称为${=cmdstr}:
sshpass -p "$cmpw" ${=cmdstr}\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,此功能是zsh特定的。