如何在ssh/remote bash命令中转义单引号字符?

pwuypxnk  于 2021-06-18  发布在  Mysql
关注(0)|答案(5)|浏览(567)

我正在构建一个用于远程启动、停止和检查进程状态的小脚本集。这个 stop 这些脚本中的一个应该寻找一个进程并杀死它。因此,我要:

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

这里的问题是awk标记化步骤需要单引号,这些引号与用于通过ssh执行远程命令的单引号冲突。这些单引号如何转义?

oogrdqng

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文档:

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非常好,因为它的内容根本不需要修改转义内容,并且可以包含单引号。

u1ehiz5o

u1ehiz5o2#

这不是 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!
brc7rcf0

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'

ma8fv8wu

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 调用(未经测试,但我认为它会起作用):

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

(与原来的不同,这将杀死所有mapreducenode任务,而不是任意的第一个任务。如果你真的只想做一件事,加上 ; exit 到awk动作。)

txu3uszq

txu3uszq5#

另一个例子是处理单引号或双引号,因为我需要解释和变量替换。如果我想做一个函数来向我的女人的macos显示msg,我可以做以下操作:

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

相关问题