2013-12-10 70 views
13

我正在构建一组用于远程启动,停止和检查进程状态的脚本。这些脚本的stop应寻找一个进程并杀死它。因此,我做:如何在ssh/remote bash命令中转义单引号字符?

ssh [email protected] 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '{print $2}' | head -n 1`' 

的这里的问题是,AWK标记化步骤需要单引号和这些冲突有用于通过ssh执行远程命令中使用的单引号。这些单引号如何逃脱?

+0

Try> ssh deploy @ hera'kill -9 \'ps -ef | grep MapReduceNode | grep -v“grep”| awk -F“”“'”{print $ 2}“'”| head -n 1'' – RedX

+0

@RedX这个谢谢你!用它作为答案,我会接受。 –

回答

18

使用

ssh [email protected] 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '"'"'{print $2}'"'"' | head -n 1`' 
8

这不是sshawk处理的报价,它是壳(和他们是需要保持外壳由特殊处理的其他字符,如$)。不支持嵌套它们(尽管其他结构,如$()甚至可以在包含引号时嵌套),因此您需要单独转义单引号。以下是几种方法:

$ 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! 
7

您不能在单引号字符串中包含单引号。然而,这并不重要,因为一个参数可以有不止一个报价段

例如(只要没有加引号的空格或其他自定界字符):

ssh [email protected] 'kill -9 `ps -ef | 
       grep MapReduceNode | 
       grep -v "grep" | 
       awk -F " " '\''{print $2}'\'" | 
       head -n 1`" 

然而,该命令行是非常笨重。如果可能的话,您应该使用pkill实用程序,该实用程序会将所有这些减少到ssh [email protected] 'pkill -SIGKILL MapReduceNode'

否则,你可以做所有的字符串操作在一个单一的awk调用(未经测试,但我认为这将工作):

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

(不像原来,这将杀死所有MapReduceNode任务,而不是一些武断第一个,如果你真的想在一个任务中完成,在awk动作中加上; exit

1

还有两个选项我没有在其他答案中看到。我已经离开了的grep/grep的/ AWK /头管道完好出于演示的目的,即使(在rici's answer提到),它可以减少到像

awk -F ' ' '/MapReduceNod[e]/ {print $2; exit}' 
  1. 使用双引号为全SSH命令:

    ssh [email protected] "kill -9 \$(ps -ef | 
    grep MapReduceNode | grep -v \"grep\" | awk -F ' ' '{print \$2}' | head -n 1)" 
    

    请注意,我可以在命令中使用单引号了,但我有逃避其他的事情我不想尚未展开:\$()(我已经使用的,而不是反引号),双报价\"print \$2

  2. 甲这里-DOC与引述定界符:

    ssh -T [email protected] <<'EOF' 
    kill -9 $(ps -ef | grep MapReduceNode | grep -v 'grep' | 
    awk -F ' ' '{print $2}' | head -n 1) 
    EOF 
    

    -T防止SSH抱怨不分配一个伪终端。

    带引号分隔符的here-doc非常好看,因为它的内容不必根据转义事物进行修改,它可以包含单引号。

0

另一个例子是处理简单或双引号,因为对于我来说,例如我需要解释和变量替换。如果我想做一个函数来显示我的女人macOS的味精我可以做以下事情:

ssh womanLptp "osascript -e 'tell app \"System Events\" to display dialog \"${1}\"'"