脚本执行SSH命令报错,CLI手动执行正常的差异与解决
问题原因
当你在脚本里把命令存在字符串变量SSH_CMD后直接执行$SSH_CMD时,bash的处理逻辑和手动在CLI执行完全不同:
- 变量赋值阶段,
'echo foo'里的单引号只是字符串的普通字符,不会被bash当作语法符号解析。 - 执行
$SSH_CMD时,bash会把整个字符串按空格拆分成多个独立单词:ssh、-v、root@xxx、-t、'echo、foo'。此时ssh收到的远程命令是'echo,自然会提示找不到这个命令。 - 而手动复制输出内容到CLI执行时,CLI会正确识别单引号的语法作用,把
echo foo作为一个完整参数传给ssh,所以能正常运行。
解决办法
推荐用bash数组存储命令,数组能精准保留每个参数的边界,避免分词错误:
MACHINE=$(cat ~/mach) # 每个命令参数作为数组的一个元素 SSH_CMD=(ssh -v root@"$MACHINE" -t 'echo foo') # 打印完整命令 echo "${SSH_CMD[*]}" # 执行数组中的命令 "${SSH_CMD[@]}"
如果一定要用字符串变量的方式,可以用eval强制bash重新解析命令中的引号(不推荐,若MACHINE的值包含特殊字符会有安全风险):
MACHINE=$(cat ~/mach) SSH_CMD="ssh -v root@$MACHINE -t 'echo foo'" echo $SSH_CMD eval $SSH_CMD
内容的提问来源于stack exchange,提问作者p k
相关产品推荐
相关产品推荐

