在bash中使用printf在转义的'或'(单或双)引号中转义\ e

时间:2018-10-24 22:57:38

标签: bash shell escaping printf heredoc

我正在编写一个shell脚本,该脚本可以在每次获得一台新机器时完全按照自己的喜好设置osx机器。我真正喜欢的一个命令行糖是“ up arrow bash history search”。正如Ask ubuntu帖子所述,添加以下行:

bind '"\e[A":history-search-backward'

我的~/.bashrc会帮我做这个,但是,我想从我的脚本中自动执行此操作...

要实现这一点,我在printf上获得了最大的成功,但是我需要在绑定('"\e之后立即转义引号和转义序列,例如:

printf "bind \'\"\\e[A\":history-search-backward\'" >> ~/.bashrc

但是在该示例中,转义序列不会转义,因此在我的~/.bashrc中我得到了:

bind '"^[[A":history-search-backward'

我尝试了多种不同的引号/转义/插值组合,但收效甚微,有人能逃脱foo来实现此目的吗,甚至只是解释为何此举不起作用,google特别擅长尤其是在\e转义的情况下。

2 个答案:

答案 0 :(得分:2)

使用此处文档:

cat <<'EOF' >>~/.bashrc
bind '"\e[A":history-search-backward'
EOF

EOF周围的引号表示,此处文档的内容将被视为单引号字符串,因此$将被视为字面而非可变前缀。在这个特定的字符串中这无关紧要,但是在更通用的应用程序中则可能。

答案 1 :(得分:1)

此处引用的文档是执行此操作的最简单方法(就像其他人的评论和Barmar的回答一样),但是如果您真的想使用printf,则有两种方法可以执行此操作。在我解决主要问题之前,有两个辅助问题:您不需要转义字符串中的单引号,并且要做需要添加换行符({{1} )结尾(与\n不同,echo不会自动添加)。

当前命令的最大问题是您要将所需的字符串放在printf的第一个参数中,该参数被视为格式字符串-其中包括,这意味着它将解释转义序列。在外壳程序已经解释它们之后。由于转义解释分为两个阶段,因此您需要quadruple the escape结尾于最后一个字符串:

printf

或者,您可以将字符串放在printf "bind '\"\\\\e[A\":history-search-backward'\n" 的第二个参数中,并使用只包含字面意义的格式字符串(printf指令)逃生解释的水平:

%s

请注意,printf '%s\n' "bind '\"\\e[A\":history-search-backward'" 必须采用格式字符串,因此它将转换为实际的换行符。

或者您也可以使用带引号的此处文档。