避免双引号转义

避免双引号转义

我想在 bash 脚本中执行一些命令。
现在,当我们使用单引号时,变量将被视为文字而不是值。
因此,执行 egls "$SOME_DIR"ls '$SOME_DIR'
我们如何处理引号和双引号的混合不同,而不是所有内容都因转义双引号而变得混乱?
例如如何验证类似的内容:

ssh server.com "mkdir \"/foo/bar/"$final"\""  

由于命令越长,它变得不可读并且很容易被破坏,我怎样才能避免所有这些转义?

答案1

经过多次使用heredocsherestrings,似乎最简单的解决方案是这样的:

ssh server.com "mkdir '/foo/bar/$final'"

是的,尽管有单引号bash,仍将进行变量替换$final,就像在echo "test'$final'".

$final注意:正如@muru 所指出的,如果包含单引号,这将不起作用。

答案2

相反的引用,(IE双引号中的单引号,以及反之亦然),可以代替转义。不使用转义符或这里的文件,考虑如何使用echo来显示此文本:

他头也不回,说道:“没办法。”

用双引号或单引号将其引起来是行不通的。交替使用相反的引号确实有效:

echo "He didn't look back, and said "'"It can'"'t be helped."'"'

输出:

He didn't look back, and said "It can't be helped."

不幸的是,上面的echo内容和转义一样难以阅读。

快乐的媒介是使用相反的引号并根据需要转义两者以减少视觉单调:

echo "He didn't look back, and said \"It can't be helped.\""

应用于代码:

ssh server.com 'mkdir "'"/foo/bar/$final"\"

即使$final包含'.

展开报价,我们有:

  1. 'mkdir "',它保留一个空格和一个左双引号。
  2. "/foo/bar/$final"$final它返回启动之前的内容ssh
  3. \"关闭双引号,保留目录名ssh

答案3

我认为真正的需求很大程度上取决于您希望在何处/何时扩展变量 - 在本地发送命令之前或在远程发送命令之后。两种情况都是有效的。无论哪种方式,如果您的命令适合一行,我建议您<<<分别使用双引号或单引号来重定向命令

1.发送命令前解析变量

final="defined_locally"; ssh server.com <<<"final="defined_remotely" ;mkdir /foo/bar/"$final" "

2. 发送命令后解析变量

final="defined_locally"; ssh server.com <<<'final="defined_remotely"; mkdir /foo/bar/"$final" '

第一个将创建

/foo/bar/define_locally

第二个将创建

/foo/bar/define_remotely

远程服务器上的目录

正如您所看到的,在这两种情况下都不需要转义,直到您想在一个命令中混合本地和远程定义的变量。

更新:

<<<

严格来说不是重定向,而是这里字符串

更新2:

感谢@Rastapopoulos 指出

Pseudo-terminal will not be allocated because stdin is not a terminal 伴随命令执行的消息

虽然没有什么坏处

答案4

这是内置的工作吗printf

ldo@theon:~> f='He didn'\''t look back, and said "It can'\''t be helped."'
ldo@theon:~> echo "$f"
He didn't look back, and said "It can't be helped."
ldo@theon:~> ssh hypatia echo "$f"
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file
ldo@theon:~> ssh hypatia echo $(printf %q "$f")
He didn't look back, and said "It can't be helped."

相关内容