【问题标题】:Escaping \e in escaped ' or " (single or double) quotes with printf in bash在 bash 中使用 printf 在转义的 ' 或 " (单引号或双引号)中转义 \e
【发布时间】:2019-03-29 11:03:30
【问题描述】:

我正在编写一个 shell 脚本,每次我得到一台新机器时,它都会按照我喜欢的方式设置我的 osx 机器。我真正喜欢的一种命令行糖是'up arrow bash history search'。正如询问 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 可以实现这一点,甚至只是解释为什么这不起作用,谷歌特别薄弱尤其是在\e 转义周围。

【问题讨论】:

  • 当你想写任意字符串时,省去麻烦,使用here document

标签: bash shell escaping printf heredoc


【解决方案1】:

使用此处的文档:

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

EOF 周围的引号意味着 here-document 的内容将被视为单引号字符串,因此 $ 将被视为字面意思而不是变量前缀。这在这个特定的字符串中无关紧要,但在更一般的应用程序中可以。

【讨论】:

    【解决方案2】:

    引用的此处文档是执行此操作的最简单方法(如其他人的评论和 Barmar 的回答),但如果您真的想使用 printf,有几种方法可以做到这一点。在我谈到主要问题之前,有两个次要问题:您不需要转义字符串中的单引号,并且您确实需要在以下位置添加换行符 (\n)结尾(不像echoprintf 不会自动添加)。

    你当前命令的最大问题是你把你想要的字符串放在printf的第一个参数中,它把它当作一个格式字符串——除其他外,这意味着它解释了转义序列它。在 shell 已经解释它们之后。因为转义解释有两个阶段,所以你需要quadruple the escape你想在最终字符串中结束:

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

    或者,您可以将字符串放在printf 的第二个参数中,并使用只包含它的格式字符串(%s 指令)没有额外级别的转义解释:

    printf '%s\n' "bind '\"\\e[A\":history-search-backward'"
    

    请注意,\n 必须在格式字符串中,因此它会被转换为实际的换行符。

    或者您可以只使用此处引用的文档。

    【讨论】:

    • 我已将此标记为正确答案,因为它回答了我提出的具体问题,但是,我已经实现了 Barmar 和使用引用的此处文档的其他人解决方案,因为它可能更清晰和清洁工。
    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    相关资源
    最近更新 更多