我有以下脚本:
#!/bin/bash
if [ "$1" == "" ]
then
echo "To start monitor, please provide the server ip:"
read STRIP
else
STRIP=$1
fi
ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t | awk '{print $5 " " $1 " " $2}'"
所以如果我在终端上输入:
./my_script.sh 192.168.5.210
它应该通过 SSH 连接到我的门户 209,然后通过 SSH 连接到 210 并获取其硬盘信息。问题是它没有按预期工作,而是只输出 5 行,如下所示:
192.1680.50.21
192.1680.50.21
192.1680.50.21
192.1680.50.21
192.1680.50.21
我尝试手动将 IP 设置为脚本中的变量或回显参数的值,它工作正常吗?
例如这工作正常:
STRIP=192.168.5.210
ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t | awk '{print $5 " " $1 " " $2}'"
但是如果我传递一个参数而不使用它,我会得到 5 个空白行
答案1
引号不嵌套。您尝试将ssh
远程命令作为包含单引号参数的双引号字符串传递给awk
,并在该参数中包含多个双引号字符串。但是 shell 将每个双引号视为双引号字符串的开头或结尾,这会造成相当混乱。
具体来说,当您"df -khP | column -t | awk '{print $5 " " $1 " " $2}'"
在 的参数列表中使用时ssh
,它会被解析为几个单独的带引号的字符串。第一个是"df -khP | column -t | awk '{print $5 "
,并且由于$variable
替换是在双引号字符串内完成的,并且脚本没有获得 5 个参数,因此该$5
部分不会被任何内容替换,给出“df -khP | column -t | awk '{print ”。接下来是" $1 "
,它被扩展为“ 192.168.5.210 ”(因为这是脚本的第一个参数)。最后,它" $2}'"
扩展为“}'”,因为没有第二个参数。ssh
然后将它们粘贴在一起,并在它们之间留有空格,给出 `df -khP |列-t | awk '{print 192.168.5.210 }' 作为正在执行的命令。根本不是你想要的。
为了使其正常工作,您需要对单个长双引号字符串中的某些字符进行转义(使用反斜杠)。具体来说,所有双引号(以防止它们结束引号字符串)和美元符号(以防止它们被扩展为参数或其他)。如果有任何反引号或反斜杠,也需要进行转义。因此,这是您想要的命令:
ssh 192.168.5.209 ssh root@$STRIP "df -khP | column -t | awk '{print \$5 \" \" \$1 \" \" \$2}'"
顺便说一句,如果我理解正确的话,打印它的原因awk
是它将 192.168.5.210 解析为三个实数,192.168、.5 和 .210,并打印它们(在需要的地方添加前导零,并在需要时添加尾随零)不相关)如“192.168”、“0.5”和“0.21”。但它不会打印它们之间的空格,因此它显示为“192.1680.50.21”。