ssh deploy@hera 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '{print $2}' | head -n 1`'
问题在于AWK标记化步骤需要使用单引号,而这与通过ssh执行远程命令时使用的单引号冲突。如何转义这些单引号?
ssh deploy@hera 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '{print $2}' | head -n 1`'
使用
ssh deploy@hera 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '"'"'{print $2}'"'"' | head -n 1`'
说明:
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) 带有命令开头的第一个字符串:'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '
2) 只有单引号的第二个字符串:"'"
3) 带有打印命令的第三个字符串:'{print $2}'
4) 另一个单引号的第四个字符串:"'"
5) 带有剩余命令的第五个字符串:' | head -n 1`'
这不是 ssh
或 awk
处理引号,而是 shell(它们必须保留以防止 shell 处理其他特殊字符,例如 $
)。嵌套引号不受支持(尽管其他结构,如 $()
,可以在包含引号的同时进行嵌套),因此您需要单独转义单引号。以下是几种方法:
$ 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!
在其他答案中没有提到的还有两个选项。为了演示目的,我保留了grep/grep/awk/head管道,尽管(如rici的答案中所暗示的那样),它可以缩减为类似以下内容:
awk -F ' ' '/MapReduceNod[e]/ { print $2; exit }'
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
.
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.
单引号不能出现在单引号字符串中。然而,这并不重要,因为一个参数可以有多个带引号的部分(只要没有未用引号括起来的空格或其他自限定字符)。
例如:
ssh deploy@hera 'kill -9 `ps -ef |
grep MapReduceNode |
grep -v "grep" |
awk -F " " '\''{print $2}'\'" |
head -n 1`"
pkill
实用程序,这将把所有内容简化为ssh deploy@hera 'pkill -SIGKILL MapReduceNode'
。awk
调用中执行所有字符串操作(未经测试,但我认为它会起作用):ssh deploy@hera 'ps -ef |
awk "/[M]apReduceNode/{system(\"kill -9 \"$2)}"'
与原始版本不同,这将杀死所有的MapReduceNode任务而不是任意的第一个任务。如果您确实只想在一个任务中执行,将; exit
添加到awk操作中即可。
ssh womanLptp "osascript -e 'tell app \"System Events\" to display dialog \"${1}\"'"