我需要使用 sh -c 执行带有转义参数的命令。我知道这个字符串看起来很丑,但简单的字符串不会造成问题。
传递给 sh -c 时的 echo 输出与单独运行时不同,我正在努力找出如何修复它。
背景:[1] 我正在转义 echo 命令的参数,因为这是传入的,并且我想确保没有插入额外的命令。 [2] 我使用 sh -c 因为我希望能够使用 shell 设施,例如 |或 nohup 等。 [3] 可能不相关,但这是通过与远程服务器的 ssh 连接运行的。
sh -c 命令的命令和输出是:
sh -c "echo \a\\\\\b\;\c"
;c
独立命令的命令和输出为:
echo \a\\\\\b\;\c
a\\b;c
任何帮助将非常感激!
答案1
\
用于转义一些字符(如其\
自身、"
, $
, `
)并删除双引号内的换行符,因此
sh -c "echo \a\\\\\b\;\c"
就好像
sh -c 'echo \a\\\b\;\c'
因为 sh,\
用于转义每个字符,所以它变得与
echo 'a\b;c'
符合 UNIX 规范的echo
s 展开\b
为退格字符 ( ^H
),当发送到终端时,该字符会将光标向左后移一个字符,因此 会;
覆盖a
,这就是您看到的原因;c
。
echo
是一个不可移植的命令,其行为因 shell 和系统而异。最好避免这种情况,特别是如果给定的参数可能包含反斜杠或可能以破折号开头。使用 printf 代替。
sh -c 'printf "%s\n" "a\\\\b;c"'
输出a\\b;c
.
(3 个反斜杠就足够了,但更安全的是要记住,在双引号内,您需要两个反斜杠才能得到一个)。
对于echo
像您这样扩展转义序列的实现,您必须将反斜杠的数量加倍。
sh -c 'echo "a\\\\\\\\b;c"'
如果您想避免使用双引号,则只需转义;
shell 唯一特殊的字符(除了\
您已经在双引号版本中转义的字符之外)。
sh -c 'echo a\\\\\\\\b\;c'
如果您想使用双引号而不是单引号,则必须再次将反斜杠的数量加倍。
sh -c "echo a\\\\\\\\\\\\\\\\b\\;c"
如果你想去掉引号,你需要转义空格并;
再次转义外壳。
sh -c echo\ a\\\\\\\\\\\\\\\\b\\\;c