我有一个服务器,我必须使用许多命令进行 ssh 访问,这些命令的特点是使用变量赋值,因此需要使用大量引号。如果我们考虑脚本:
ssh user@host "kinit -k -t /path/to/dir/`whoami`.`hostname -s`.keytab `whoami`/`hostname -f`@host ;
set -x
touch health_check.log ;
echo \"Starting HDFS health check\" > health_check.log ;
echo \"/path/to\" >> health_check.log ;
hdfs dfs -du -h /path/to &>> health_check.log ;
echo \"**************************************************************************
/path/to/dir\" >> health_check.log ;
hdfs dfs -du -h /path/to/dir &>> health_check.log ;
subject=\"HDFS Health Check\" ;
from=\"[email protected]\" ;
recipients=\"[email protected]\" ;
mail=\"subject:$subject\nfrom:$from\nContent-Type: text/html\nMIME-Version: 1.0\n\n$(cat health_check.log)\" ;
echo -e $mail | sendmail \"$recipients\" ;
set +x
rm health_check.log
"
当我运行脚本时,我得到以下调试输出:
++ subject='HDFS Health Check'
++ [email protected]
++ [email protected]
++ mail='subject:\nfrom:\nContent-Type: text/html\nMIME-Version: 1.0\n\nStarting HDFS health check /data/gftocon'
++ echo -e
++ sendmail ''
注意我的变量应该在的空字符串。为什么转义引号不起作用?
答案1
这是因为脚本是双引号的:你的外壳正在替换变量前启动 ssh 命令。您可以添加一些额外的反斜杠,或者使用引用的heredoc像这样:
ssh user@host <<'END_COMMANDS'
# ...............^............^ these quotes make the whole document single-quoted
kinit -k -t /path/to/dir/`whoami`.`hostname -s`.keytab `whoami`/`hostname -f`@host
set -x
echo "Starting HDFS health check" > health_check.log
echo "/path/to" >> health_check.log
hdfs dfs -du -h /path/to &>> health_check.log
echo "**************************************************************************
/path/to/dir" >> health_check.log
hdfs dfs -du -h /path/to/dir &>> health_check.log
subject="HDFS Health Check"
from="[email protected]"
recipients="[email protected]"
headers="subject:$subject
from:$from
Content-Type: text/html
MIME-Version: 1.0"
{ echo "$headers"; echo; cat health_check.log; } | sendmail "$recipients"
set +x
rm health_check.log
END_COMMANDS
我认为这样更容易维护。
答案2
我认为你应该$
从你的"
"
街区内逃脱这些角色。
您的邮件命令将变为:
mail=\"subject:\$subject\nfrom:\$from\nContent-Type: text/html\nMIME-Version: 1.0\n\n\$(cat health_check.log)\"
注意:虽然看起来可行$(cat)
。不知道为什么。