shell如何在语句里面让单引号是配对?

各位好!我想获取当前机器的外网IP,然后远程到192.168.1.32这台机器上去生成一个mysql的语句文件,我写了一个shell脚本如下:

#!/bin/bash
ip=$(ifconfig eth1 | grep "inet addr" | awk '{ print $2}' | awk -F: '{print $2}')
sshpass -f /root/alarm.passwd ssh -o "StrictHostKeyChecking no" root@192.168.1.32 'echo "insert into third_service(host, port, create_time, weight) values(\'$ip\', 8800, now(), 100);" > /root/p2pserver.sql'

但是执行之后,在192.168.1.32这个机器上生成的内容是:

[root@ecs-alarm-manager ~]# cat p2pserver.sql 
insert into third_service(host, port, create_time, weight) values(\, 8800, now(), 100);

请问,这个变量ip如何转义才是正确的呢?

阅读 3.3k
1 个回答

这种直接将命令行写入ssh参数的做法很容易造成引号嵌套地狱,我的做法通常是在本地产生脚本,在远程执行本地脚本。因此你的脚本可以改成类似于下面这样的来避免引号嵌套带来的各种陷阱:

#!/bin/bash
ip=$(ifconfig eth1 | grep "inet addr" | awk '{ print $2}' | awk -F: '{print $2}')
cat <<EOF > p2pserver.sql
insert into third_service(host, port, create_time, weight) values(\'$ip\', 8800, now(), 100);
EOF

sshpass -f /root/alarm.passwd ssh -o "StrictHostKeyChecking no" root@192.168.1.32 'MYSQL_PWD=you_password mysql -uroot -p your_db' < p2pserver.sql

对于你的需求,直接把在本地产生的sql文件scp到远程主机就行了,没必要非得在远程主机上去生成sql。

EDIT: 你的问题有人回答过了,因为你用了单引号,等于${ip}实际在远程主机执行的,因此没这个环境变量,修改为

"echo 'insert into third_service(host, port, create_time, weight) values(\'$ip\', 8800, now(), 100);' > /root/p2pserver.sql"

让这个${ip}从本地环境变量拼接好传递给远程服务器执行即可。