如何在脚本化的ssh命令中使用单引号和双引号 [英] How to have simple and double quotes in a scripted ssh command

查看:377
本文介绍了如何在脚本化的ssh命令中使用单引号和双引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小的bash脚本,并希望通过ssh执行以下命令

I am writing a small bash script and want to execute the following command via ssh

sudo -i mysql -uroot -pPASSWORD --execute "select user, host, password_last_changed from mysql.user where password_last_changed <= '2016-9-00 11:00:00' order by password_last_changed ASC;"

不幸的是,此命令同时包含单引号和双引号,所以我不能这样做

Unfortunately this command contains both simple and double quotes so I can't do

ssh user@host "command";

解决此问题的推荐方法是什么?

What would be the recommended way to solve this issue ?

推荐答案

使用Heredoc

您只需在shell的stdin上传递您的确切代码即可:

Using a heredoc

You can just pass your exact code on the shell's stdin:

ssh user@host bash -s <<'EOF'
sudo -i mysql -uroot -pPASSWORD --execute "select user, host, password_last_changed from mysql.user where password_last_changed <= '2016-9-00 11:00:00' order by password_last_changed ASC;"
EOF

请注意,以上代码不会执行任何变量扩展-由于使用了<<'EOF'(vs <<EOF),因此会将代码精确地传递给远程系统 变量扩展("$foo")将仅使用远程外壳程序可用的变量在远程侧进行扩展.

Note that the above doesn't perform any variable expansions -- due to the use of <<'EOF' (vs <<EOF), it passes the code to the remote system exactly, so a variable expansion ("$foo") would be expanded on the remote side, using only variables available to the remote shell.

这还会消耗包含要运行脚本的Heredoc的标准输入-如果您需要标准输入可用于其他目的,则可能无法按预期工作.

This also consumes stdin for the heredoc containing the script to be run -- if you need stdin to be available for other purposes, that may not work as intended.

您还可以告诉shell自己为您报价.假设您的本地shell是bash或ksh:

You can also tell the shell itself to do the quoting for you. Assuming your local shell is bash or ksh:

#!/usr/bin/env bash
#              ^^^^ - NOT /bin/sh

# put your command into an array, honoring quoting and expansions
cmd=(
  sudo -i mysql -uroot -pPASSWORD
    --execute "select user, host, password_last_changed from mysql.user where password_last_changed <= '2016-9-00 11:00:00' order by password_last_changed ASC;"
)

# generate a string which evaluates to that array when parsed by the shell
printf -v cmd_str '%q ' "${cmd[@]}"

# pass that string to the remote host
ssh user@host "$cmd_str"

需要说明的是,如果您的字符串扩展为包含不可打印字符的值,则在printf '%q'的输出中可能会使用不可移植的$''引用形式.为了以一种可移植的方式解决该问题,您实际上最终使用了一个单独的解释器,例如Python:

The caveat there is that if your string expands to a value containing non-printable characters, the nonportable $'' quoting form may be used in the output of printf '%q'. To work around that in a portable manner, you actually end up using a separate interpreter such as Python:

#!/bin/sh
# This works with any POSIX-compliant shell, either locally or remotely
# ...it *does* require Python (either 2.x or 3.x) on the local end.

quote_args() { python -c '
import pipes, shlex, sys
quote = shlex.quote if hasattr(shlex, "quote") else pipes.quote
sys.stdout.write(" ".join(quote(x) for x in sys.argv[1:]) + "\n")
' "$@"; }

ssh user@host "$(quote_args sudo -i mysql -uroot -pPASSWORD sudo -i mysql -uroot -pPASSWORD)"

这篇关于如何在脚本化的ssh命令中使用单引号和双引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆