如何在 ssh / 远程 bash 命令中转义单引号字符?
Posted
技术标签:
【中文标题】如何在 ssh / 远程 bash 命令中转义单引号字符?【英文标题】:How to escape the single quote character in an ssh / remote bash command? 【发布时间】:2013-12-28 05:07:43 【问题描述】:我正在构建一小组用于远程启动、停止和检查进程状态的脚本。这些脚本的stop
应该寻找一个进程并杀死它。所以我这样做:
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 " " "'"打印 $2"'" |头 -n 1`' @RedX 这工作谢谢!用它作为答案,我会接受。 【参考方案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`'
【讨论】:
一个解释会比仅仅解决这个特定问题的一个班轮更好。【参考方案2】:这不是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!
【讨论】:
【参考方案3】:我在其他任何答案中都没有看到另外两个选项。出于演示目的,我已将 grep/grep/awk/head 管道完好无损,即使(如 rici's answer 中提到的那样)它可能会简化为类似
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-doc:
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 非常好,因为它的内容根本不需要修改关于转义的东西,并且它可以包含单引号。
【讨论】:
here-doc 示例非常有用,因为它提醒您引用 EOF 会影响以下文本是否由 bash 评估。【参考方案4】:您不能在单引号字符串中包含单引号。但是,这并不重要,因为单个参数可以有多个带引号的段(只要没有不带引号的空格或其他自定界字符。)
例如:
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 操作中。)
【讨论】:
【参考方案5】:另一个例子是处理单引号或双引号,因为例如我需要解释和变量替换。如果我想创建一个功能来向我的女人的 macOS 显示一条消息,我可以执行以下操作:
ssh womanLptp "osascript -e 'tell app \"System Events\" to display dialog \"$1\"'"
【讨论】:
以上是关于如何在 ssh / 远程 bash 命令中转义单引号字符?的主要内容,如果未能解决你的问题,请参考以下文章