我正在构建一个用于远程启动、停止和检查进程状态的小脚本集。这个 stop 这些脚本中的一个应该寻找一个进程并杀死它。因此,我要:
stop
ssh deploy@hera 'kill -9 `ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '{print $2}' | head -n 1`'
这里的问题是awk标记化步骤需要单引号,这些引号与用于通过ssh执行远程命令的单引号冲突。这些单引号如何转义?
oogrdqng1#
还有两个选择我在其他答案中没有提到。出于演示目的,我将grep/grep/awk/head管道原封不动地保留了下来,尽管(正如rici的回答中所提到的)它可以简化为
awk -F ' ' '/MapReduceNod[e]/ {print $2; exit}'
对整个ssh命令使用双引号:
ssh deploy@hera "kill -9 \$(ps -ef | grep MapReduceNode | grep -v \"grep\" | awk -F ' ' '{print \$2}' | head -n 1)"
请注意,我现在可以在命令中使用单引号,但我必须避开其他我不想扩展的内容: \$() (我用它代替了反勾号),双引号 \" ,和 print \$2 .带引号分隔符的here文档:
\$()
\"
print \$2
ssh -T deploy@hera <<'EOF' kill -9 $(ps -ef | grep MapReduceNode | grep -v 'grep' | awk -F ' ' '{print $2}' | head -n 1) EOF
这个 -T 防止ssh抱怨没有分配伪终端。带引号分隔符的here doc非常好,因为它的内容根本不需要修改转义内容,并且可以包含单引号。
-T
u1ehiz5o2#
这不是 ssh 或者 awk 处理引号,就是shell(它们必须防止shell特别处理其他字符,如 $ ). 不支持嵌套它们(尽管其他结构,例如 $() 即使包含引号也可能嵌套),因此需要分别转义单引号。以下是几种方法:
ssh
awk
$
$()
$ 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!
brc7rcf03#
使用
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 -9ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '2) 第二个字符串只有一个'char:"'"3) 带print命令的第三个字符串:'{print $2}'4) 带另一个单引号的第四个字符串:"'"5) 带其余命令的第五个字符串:' | head -n 1'
'kill -9
2) 第二个字符串只有一个'char:
3) 带print命令的第三个字符串:
4) 带另一个单引号的第四个字符串:
5) 带其余命令的第五个字符串:
'
ma8fv8wu4#
不能在单引号字符串中包含单引号。但是,这并不重要,因为一个参数可以有多个带引号的段(只要没有不带引号的空格或其他自定界字符)例如:
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 调用(未经测试,但我认为它会起作用):
pkill
ssh deploy@hera 'pkill -SIGKILL MapReduceNode'
ssh deploy@hera 'ps -ef | awk "/[M]apReduceNode/{system(\"kill -9 \"$2)}"'
(与原来的不同,这将杀死所有mapreducenode任务,而不是任意的第一个任务。如果你真的只想做一件事,加上 ; exit 到awk动作。)
; exit
txu3uszq5#
另一个例子是处理单引号或双引号,因为我需要解释和变量替换。如果我想做一个函数来向我的女人的macos显示msg,我可以做以下操作:
ssh womanLptp "osascript -e 'tell app \"System Events\" to display dialog \"${1}\"'"
5条答案
按热度按时间oogrdqng1#
还有两个选择我在其他答案中没有提到。出于演示目的,我将grep/grep/awk/head管道原封不动地保留了下来,尽管(正如rici的回答中所提到的)它可以简化为
对整个ssh命令使用双引号:
请注意,我现在可以在命令中使用单引号,但我必须避开其他我不想扩展的内容:
\$()
(我用它代替了反勾号),双引号\"
,和print \$2
.带引号分隔符的here文档:
这个
-T
防止ssh抱怨没有分配伪终端。带引号分隔符的here doc非常好,因为它的内容根本不需要修改转义内容,并且可以包含单引号。
u1ehiz5o2#
这不是
ssh
或者awk
处理引号,就是shell(它们必须防止shell特别处理其他字符,如$
). 不支持嵌套它们(尽管其他结构,例如$()
即使包含引号也可能嵌套),因此需要分别转义单引号。以下是几种方法:brc7rcf03#
使用
说明:
1) 以命令开头的第一个字符串:
'kill -9
ps -ef | grep MapReduceNode | grep -v "grep" | awk -F " " '2) 第二个字符串只有一个'char:
"'"3) 带print命令的第三个字符串:
'{print $2}'4) 带另一个单引号的第四个字符串:
"'"5) 带其余命令的第五个字符串:
' | head -n 1'
ma8fv8wu4#
不能在单引号字符串中包含单引号。但是,这并不重要,因为一个参数可以有多个带引号的段(只要没有不带引号的空格或其他自定界字符)
例如:
但是,这个命令行非常笨拙。如果可能的话,你应该使用
pkill
实用程序,这将减少所有的ssh deploy@hera 'pkill -SIGKILL MapReduceNode'
.否则你可以在一个单独的时间内完成所有的字符串操作
awk
调用(未经测试,但我认为它会起作用):(与原来的不同,这将杀死所有mapreducenode任务,而不是任意的第一个任务。如果你真的只想做一件事,加上
; exit
到awk动作。)txu3uszq5#
另一个例子是处理单引号或双引号,因为我需要解释和变量替换。如果我想做一个函数来向我的女人的macos显示msg,我可以做以下操作: