我有一个连接到远程计算机以执行操作的 shell 脚本。其中一项操作是设置一个或多个 DNS 服务器。虽然大部分静态数据很容易捕获并通过 SSH 通过管道传送到远程计算机:
config_ntp()
{
ssh -T admin@server_ip <<-NTPSERVER
sysconf ntp addserver $NTPSERVER
NTPSERVER
}
创建动态大小的命令列表比我想象的要棘手。我有什么:
DNSSERVERS=(8.8.8.8 8.8.8.7)
config_dns()
{
cmd=""
for server in ${DNSSERVERS[@]}; do
cmd+="network dns add nameserver $server$'\n' "
done
cmd+="service dns restart$'\n'"
echo -e "cmd: $cmd"
ssh -T admin@server_ip $cmd
}
调用的结果:
$ sh setup.sh
cmd: network dns add nameserver 8.8.8.8$'
' network dns add nameserver 8.8.8.7$'
' service dns restart$'
'
Syntax Error: Invalid character detected: '\'.
Command Result : 22 (Invalid argument)
Exiting...
那是我的最新化身。我按照其他地方的建议使用 $'\n'
...以前,我只使用 \n
,这导致了同样的错误。
如何创建一个包含命令列表(可变长度,动态生成)的变量,以通过 ssh 通过管道传输到远程计算机?
最佳答案
您为什么想要或需要此处的文档?如果它不仅仅是一个带有一些用变量填充的占位符的静态模板,那么通过其他方式向流程提供标准输入几乎肯定会更容易。
ssh <<____HERE
commands
more commands "$variable"
____HERE
完全等同于
printf "commands\nmore commands \"%s\"\n" "$variable" | ssh
如果某些部分比仅仅打印某些内容更复杂,您可以使其任意复杂:
{ complex_function --with --options and arguments -o stdout
printf "echo 'anything we send to stdout goes into the pipe'\n"
if command; then
while another command; do
for arguments in $(something to drive a loop); do
complex stuff
done
done
fi
: and etc
} | ssh
在管道之前使用大括号(commands)
而不是大括号{commands}
在子shell中运行commands
。
您的具体问题是您无法将 $'\n'
放入常规双引号字符串内。 echo
已经产生了一个换行符,因此您似乎正在采取一种非常迂回的方式来构建事物。但试试这个:
# Does this really need to be in a separate variable?
DNSSERVERS=(8.8.8.8 8.8.8.7)
config_dns()
{
{
# To be completely correct, notice quoting around array
for server in "${DNSSERVERS[@]}"; do
echo "network dns add nameserver $server"
done
echo "service dns restart"
} |
# maybe add a tee /dev/stderr or something here to see what's going on
ssh -T admin@server_ip
}
为了美观,我可能会重构
config_dns()
{
{
printf 'network dns add nameserver %s\n' "${DNSSERVERS[@]}"
printf 'service dns restart\n'
} |
ssh -T admin@server_ip
}
关于bash - 如何在 bash 中编写动态生成的定界文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47805775/