当我偶然发现一个我想阻止公司访问的恶意网站时,我在我的绑定(bind)服务器上编辑我的 named.conf 文件,然后更新我的代理服务器黑名单文件。我想用 bash 脚本自动执行此操作。假设我的脚本名为“evil-site-block.sh”并包含以下内容:
ssh root@192.168.0.1 'echo "#date added $(date +%m/%d/%Y)" >> /var/named/chroot/etc/named.conf; echo "zone \"$1\" { type master; file \"/etc/zone/dummy-block\"; };" >> /var/named/chroot/etc/named.conf'
然后运行为
$ evil-site-block.sh google.com
当我在远程机器上查看 named.conf 的内容时,我看到:
#date added 09/16/2014
zone "" { type master; file "/etc/zone/dummy-block"; };
我想不通的是如何将“google.com”作为 1 美元传递。
最佳答案
首先,您不希望这是两个单独重定向的 echo
语句——这样做既效率低下又意味着这些行最终可能不是下一个如果同时附加了其他东西,则彼此。
其次,更重要的是,您不希望运行的远程命令可以转义其引号并在您的服务器上运行任意命令(想想如果 $1
是 '$(rm -rf/)'.spammer.com
).
相反,请考虑:
#!/bin/bash
# ^ above is mandatory, since we use features not found in #!/bin/sh
printf -v new_contents \
'# date added %s\nzone "%s" { type master; file "/etc/zone/dummy-block"; };\n' \
"$(date +%m/%d/%Y)" \
"$1"
printf -v remote_command \
'echo %q >>/var/named/chroot/etc/named.conf' \
"$new_contents"
ssh root@192.168.0.1 bash <<<"$remote_command"
printf %q
转义数据,以便另一个 bash shell 中的评估传递将评估该内容返回到自身。因此,将保证远程 shell(只要它是 bash)正确解释内容,即使内容试图转义其周围的引号。
关于linux - 通过 ssh 传递外部 shell 脚本变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25877498/