我正在编写一个 bash 脚本(除了其他更有趣的事情之外)在远程主机上执行一系列命令,但是 ssh 命令失败并显示“名称或服务未知”。以下脚本重现了该行为:
#!/bin/bash
function apply {
local cmd_template cmd_arg logfile
cmd_template=$1
cmd_arg=$2
logfile=$3
local cmd
cmd=${cmd_template//'{}'/${cmd_arg}}
echo "cmd is ${cmd}"
${cmd} >${logfile} 2>&1
}
USER="symcbean"
HOST="ssh.example.com"
SCRIPT="sleep"
TEMPLATE="ssh \"${USER}@${HOST}\" \"${SCRIPT}\" {}"
apply "${TEMPLATE}" "1" "/tmp/test.$$"
输出:
cmd is ssh "[email protected]" "sleep" 1
ssh: Could not resolve hostname ssh.example.com": Name or service not known
但是 DNS 存在且有效。此外,如果我从输出中复制并粘贴 ssh 命令,它会按预期工作。
我在这里缺少什么?
(在有人建议我只使用 xargs 或并行之前 - 实际的实现需要这些中不存在的行为)。
答案1
事实上,线索就在错误消息中:
ssh: Could not resolve hostname ssh.example.com": Name or service not known
请注意不匹配的双引号。
ssh 将“username@host”拆分为"username
和host"
。解决方案是删除 TEMPLATE= 中对此的引用
这确实意味着如果用户名包含空格,脚本将无法工作 - 但这是一个可以接受的妥协(因为这种情况可能会产生很多其他影响)。
我怀疑我本可以创造性地eval
解决这里的问题,但由于这在我的实现中出现的方式,这会产生其他问题。