我在命令下运行时遇到问题:
当我运行:cmssh 12np时,我打算调用已定义的函数cmssh,最终我期待这样的shell命令行:
sshpass -p password ssh mydomain\\userxyz@host.com
,见以下来源:
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'
}
但是,最后一步始终将结果呈现为:
sshpass -p password 'ssh mydomain\\userxyz@host.com'
我尝试过多种方法尝试删除单引号,但不知道它是如何可能的。
请参阅调试信息:
~ 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
由于
答案 0 :(得分:1)
注意:此时不清楚OP使用的具体shell。这个答案提出了一般性观点,然后讨论了bash
和zsh
。
您的立即问题与引用无关:错误消息表明可执行文件sshpass
不在您的$PATH
中。
您的字符串($cmdstr
)实际上并不包含单引号 - 它们是运行bash
或zsh
并且set -x
生效的工件强>
但是,还有其他问题:
您在cmssh()
中解析别名定义的方式将您的别名定义中的\\
从(概念上的)引用的单个 \
转换为文字字符串{ {1}}(两个文字\\
字符。)
在这种情况下,一个简单的解决方法是通过让\
(不带参数)回显字符串来添加另一层评估:
xargs
请注意,我已经删除了基于cmdstr=$(alias $aliascmd | cut -d"'" -f2 | xargs)
的{{1}}命令,这是不需要的。
一般来说,解析别名定义这种方式很脆弱。
此时我希望您的代码可以在=
中使用,但尚未在cut
中(见下文)。
请注意,只需从函数定义的开头删除bash
,就可以使代码在zsh
(仅限POSIX功能的shell)中工作。
最终问题仅影响function
,而不影响sh
:
zsh
不会在bash
命令中对zsh
执行分词,因此$cmdstr
将作为SINGLE参数传递给sshpass -p "$cmpw" $cmdstr
要在评估'ssh mydomain\userxyz@host.com'
时启用分词,并将其标记作为单独的参数传递,请将其称为sshpass
:
$cmdstr
请注意,此功能是${=cmdstr}
特定的。
答案 1 :(得分:0)
试试这个
mydomain="'ssh mydomain\\userxyz@host.com'"
echo ${mydomain/#'/\\\'} \\ assign this variable
其他方法,使用sed
echo $mydomain | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)\$/\\3\\5/g"