How to escape the single quote character in an ssh / remote bash command?

前端 未结 5 2132
春和景丽
春和景丽 2020-12-01 07:51

I\'m building a small set of scripts for remotely starting, stopping and checking the status of a process. The stop of these scripts should look for a process a

相关标签:
5条回答
  • 2020-12-01 08:25

    This is not ssh or awk handling the quotes, it is the shell (and they are necessary to keep the shell from handling other characters specially, like $). Nesting them is not supported (although other structures, such as $() may nest even while containing quotes), so you'll need to escape the single quotes separately. Here are a couple of methods:

    $ echo 'Don'"'"'t mess with this apostrophe!'
    Don't mess with this apostrophe!
    $ echo 'Don'\''t mess with this apostrophe!'
    Don't mess with this apostrophe!
    
    0 讨论(0)
  • 2020-12-01 08:40

    Use

    ssh deploy@hera 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '"'"'{print $2}'"'"' | head -n 1`'
    

    Explanation:

    ssh deploy@hera 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '"'"'{print $2}'"'"' | head -n 1`'
                    >                               1                                   <>2<>    3     <>4<>      5      <
    

    1) First string with beginning of command: 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '

    2) Second string with only a single ' char: "'"

    3) Third string with the print command: '{print $2}'

    4) Fourth string with another single quote: "'"

    5) Fifth string with rest of command: ' | head -n 1`'

    0 讨论(0)
  • 2020-12-01 08:42

    You can't include a single quote in a single-quoted string. However, that doesn't matter because a single argument can have more than one quoted segment (as long as there is no unquoted whitespace or other self-delimiting characters.)

    For example:

    ssh deploy@hera 'kill -9 `ps -ef |
                     grep MapReduceNode |
                     grep -v "grep" |
                     awk -F " " '\''{print $2}'\'" |
                     head -n 1`"
    

    However, that command line is very clunky. If possible, you should use the pkill utility, which would reduce all that to ssh deploy@hera 'pkill -SIGKILL MapReduceNode'.

    Otherwise you could do all the string manipulation in a single awk invocation (untested, but I think it will work):

    ssh deploy@hera 'ps -ef |
                     awk "/[M]apReduceNode/{system(\"kill -9 \"$2)}"'
    

    (unlike the original, this will kill all MapReduceNode tasks rather than some arbitrary first one. If you really want to just do in one task, add ; exit to the awk action.)

    0 讨论(0)
  • 2020-12-01 08:42

    Another example is to deal with simple or double quotes because for me for example I needed interpretation and variable replacements. If I want to make a function to display a msg to the macOS of my woman I can do followings:

    ssh womanLptp "osascript -e 'tell app \"System Events\" to display dialog \"${1}\"'"
    
    0 讨论(0)
  • 2020-12-01 08:44

    There are two more options I don't see mentioned in any of the other answers. I've left the grep/grep/awk/head pipeline intact for demonstration purposes, even though (as alluded to in rici's answer) it could be reduced to something like

    awk -F ' ' '/MapReduceNod[e]/ {print $2; exit}'
    
    1. Using double quotes for the whole ssh command:

      ssh deploy@hera "kill -9 \$(ps -ef |
      grep MapReduceNode | grep -v \"grep\" | awk -F ' ' '{print \$2}' | head -n 1)"
      

      Notice that I can use single quotes in the command now, but I have to escape other things I don't want expanded yet: \$() (which I've used instead of backticks), double quotes \", and print \$2.

    2. A here-doc with quoted delimiter:

      ssh -T deploy@hera <<'EOF'
      kill -9 $(ps -ef | grep MapReduceNode | grep -v 'grep' |
      awk -F ' ' '{print $2}' | head -n 1)
      EOF
      

      The -T prevents ssh from complaining about not allocating a pseudo-terminal.

      The here-doc with quoted delimiter is extra nice because its contents don't have to be modified at all with respect to escaping things, and it can contain single quotes.

    0 讨论(0)
提交回复
热议问题