How to have simple and double quotes in a scripted ssh command

前端 未结 1 1333
独厮守ぢ
独厮守ぢ 2020-12-04 03:09

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_la         


        
相关标签:
1条回答
  • 2020-12-04 03:52

    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
    

    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.

    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.


    Generating an eval-safe command dynamically

    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"
    

    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)"
    
    0 讨论(0)
提交回复
热议问题