在 stringstream 的 ssh 命令中转义来自 bash 脚本的引号
escaping quotes from bash script in an ssh command for a stringstream
我有一个 bash 脚本,我想使用 ssh 远程执行它。
这是脚本:
(
vmnames="$(/usr/bin/VBoxManage list vms | grep -o -w -P -e '\"([a-zA-Z0-9_]+)\"' | sed s/\"//g)"
for vm in $vmnames
do
ip="$(/usr/bin/VBoxManage guestproperty enumerate ${vm} | grep 'V4/IP' | grep -o -w -P -e '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | sed s/\"//g)"
echo "${vm} ${ip}"
done
)
由于我想使用 ssh 远程执行此操作,因此我需要引用整个脚本:
stringstream ssCmd;
ssCmd << "sshpass -p '" << sPass << "' ssh -o StrictHostKeyChecking=no "
<< sUser << "@" << sHost << " "
<< "\""
<< my_script_should_go_here
<< "\"";
我似乎无法弄清楚如何正确引用脚本以便正确解释它。
是否有我可以用来正确转义脚本的自动化工具,或者有人可以建议如何正确转义脚本?
nb - 出于好奇 - 该脚本需要在每个 VM 上安装来宾添加,以便它 return 每个 VM 的 IP 地址信息。
更新
我最终完成了以下操作:
// base64 encode the script for decode on remote system
static const std::string k_sGetHostIpScript = "KAp2bW5hbWVzPSIkKC91c3IvYmluL1ZCb3hNYW5hZ2UgbGlzdCB2bXMgfCBncmVwIC1vIC13IC1QIC1lICdcIihbYS16QS1aMC05X10rKVwiJyB8IHNlZCBzL1wiLy9nKSIKZm9yIHZtIGluICR2bW5hbWVzCmRvCmlwPSIkKC91c3IvYmluL1ZCb3hNYW5hZ2UgZ3Vlc3Rwcm9wZXJ0eSBlbnVtZXJhdGUgJHt2bX0gfCBncmVwICdWNC9JUCcgfCBncmVwIC1vIC13IC1QIC1lICdcZHsxLDN9XC5cZHsxLDN9XC5cZHsxLDN9XC5cZHsxLDN9JyB8IHNlZCBzL1wiLy9nKSIKZWNobyAiJHt2bX0gJHtpcH0iCmRvbmUKKQ==";
stringstream ssCmd;
ssCmd << "sshpass -p '" << sPass << "' ssh -o StrictHostKeyChecking=no "
<< sUser << "@" << sHost << " "
<< "\"eval 'echo " << k_sGetHostIpScript << " | base64 --decode | bash'\"";
您的 bash 脚本中似乎已经转义了字符串,因此您必须对转义的字符串进行转义。
例如,假设您在 bash 脚本中有以下行:
foo=$(printf "1st line\n2nd line\n3rd line\n" | grep -a "[0-2].*")
将上面的代码片段附加到例如std::stringstream
,你必须转义所有转义字符(\
)和所有引号,如下所示:
std::stringstream ss;
ss << "foo=$(printf \"1st line\n2nd line\n3rd line\n\" | grep -a \"[0-2].*\")"
为了让您的生活更轻松,您可以使用例如this tool 将您的脚本转换为 C++ 转义字符串。
我有一个 bash 脚本,我想使用 ssh 远程执行它。
这是脚本:
(
vmnames="$(/usr/bin/VBoxManage list vms | grep -o -w -P -e '\"([a-zA-Z0-9_]+)\"' | sed s/\"//g)"
for vm in $vmnames
do
ip="$(/usr/bin/VBoxManage guestproperty enumerate ${vm} | grep 'V4/IP' | grep -o -w -P -e '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | sed s/\"//g)"
echo "${vm} ${ip}"
done
)
由于我想使用 ssh 远程执行此操作,因此我需要引用整个脚本:
stringstream ssCmd;
ssCmd << "sshpass -p '" << sPass << "' ssh -o StrictHostKeyChecking=no "
<< sUser << "@" << sHost << " "
<< "\""
<< my_script_should_go_here
<< "\"";
我似乎无法弄清楚如何正确引用脚本以便正确解释它。
是否有我可以用来正确转义脚本的自动化工具,或者有人可以建议如何正确转义脚本?
nb - 出于好奇 - 该脚本需要在每个 VM 上安装来宾添加,以便它 return 每个 VM 的 IP 地址信息。
更新
我最终完成了以下操作:
// base64 encode the script for decode on remote system
static const std::string k_sGetHostIpScript = "KAp2bW5hbWVzPSIkKC91c3IvYmluL1ZCb3hNYW5hZ2UgbGlzdCB2bXMgfCBncmVwIC1vIC13IC1QIC1lICdcIihbYS16QS1aMC05X10rKVwiJyB8IHNlZCBzL1wiLy9nKSIKZm9yIHZtIGluICR2bW5hbWVzCmRvCmlwPSIkKC91c3IvYmluL1ZCb3hNYW5hZ2UgZ3Vlc3Rwcm9wZXJ0eSBlbnVtZXJhdGUgJHt2bX0gfCBncmVwICdWNC9JUCcgfCBncmVwIC1vIC13IC1QIC1lICdcZHsxLDN9XC5cZHsxLDN9XC5cZHsxLDN9XC5cZHsxLDN9JyB8IHNlZCBzL1wiLy9nKSIKZWNobyAiJHt2bX0gJHtpcH0iCmRvbmUKKQ==";
stringstream ssCmd;
ssCmd << "sshpass -p '" << sPass << "' ssh -o StrictHostKeyChecking=no "
<< sUser << "@" << sHost << " "
<< "\"eval 'echo " << k_sGetHostIpScript << " | base64 --decode | bash'\"";
您的 bash 脚本中似乎已经转义了字符串,因此您必须对转义的字符串进行转义。
例如,假设您在 bash 脚本中有以下行:
foo=$(printf "1st line\n2nd line\n3rd line\n" | grep -a "[0-2].*")
将上面的代码片段附加到例如std::stringstream
,你必须转义所有转义字符(\
)和所有引号,如下所示:
std::stringstream ss;
ss << "foo=$(printf \"1st line\n2nd line\n3rd line\n\" | grep -a \"[0-2].*\")"
为了让您的生活更轻松,您可以使用例如this tool 将您的脚本转换为 C++ 转义字符串。