在 bash 中使用 printf 在转义 ' 或 "(单引号或双引号)中转义 \e
Escaping \e in escaped ' or " (single or double) quotes with printf in bash
我正在编写一个 shell 脚本,每次我得到一台新机器时,它都会按照我喜欢的方式设置我的 osx 机器。我真正喜欢的一种命令行糖是“up arrow bash history search”。正如询问 ubuntu post 所说,添加行:
bind '"\e[A":history-search-backward'
我的 ~/.bashrc
会为我做这件事,但是,我想从我的脚本中自动完成...
为了实现它,我使用 printf 取得了最大的成功,但我需要在绑定后立即转义引号和转义序列 ('"\e
),例如:
printf "bind \'\"\e[A\":history-search-backward\'" >> ~/.bashrc
但在那个例子中,转义序列没有转义,所以在我的 ~/.bashrc
中,我得到了这一行:
bind '"^[[A":history-search-backward'
我尝试了很多不同的 quoting/escaping/interpolation 组合,但收效甚微,有没有人有一些字符转义 foo 可以实现这个,或者甚至只是解释为什么这不起作用,google 在地面上特别薄,尤其是在 \e
转义周围。
使用此处文档:
cat <<'EOF' >>~/.bashrc
bind '"\e[A":history-search-backward'
EOF
EOF
两边的引号表示 here-document 的内容将被视为单引号字符串,因此 $
将按字面意思处理,而不是作为变量前缀。这在这个特定的字符串中无关紧要,但在更一般的应用程序中可能是这样。
此处引用的文档是最简单的方法(如其他人的评论和 Barmar 的回答),但如果您真的想使用 printf
,有几种方法可以做到那。在进入主要问题之前,有两个次要问题:您不需要对字符串中的单引号进行转义,并且 do 需要添加一个换行符 (\n
) 最后(与 echo
不同,printf
不会自动添加)。
你当前命令的最大问题是你将你想要的字符串放在 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
必须在格式字符串中,因此它会被转换为实际的换行符。
或者您可以只使用此处引用的文档。
我正在编写一个 shell 脚本,每次我得到一台新机器时,它都会按照我喜欢的方式设置我的 osx 机器。我真正喜欢的一种命令行糖是“up arrow bash history search”。正如询问 ubuntu post 所说,添加行:
bind '"\e[A":history-search-backward'
我的 ~/.bashrc
会为我做这件事,但是,我想从我的脚本中自动完成...
为了实现它,我使用 printf 取得了最大的成功,但我需要在绑定后立即转义引号和转义序列 ('"\e
),例如:
printf "bind \'\"\e[A\":history-search-backward\'" >> ~/.bashrc
但在那个例子中,转义序列没有转义,所以在我的 ~/.bashrc
中,我得到了这一行:
bind '"^[[A":history-search-backward'
我尝试了很多不同的 quoting/escaping/interpolation 组合,但收效甚微,有没有人有一些字符转义 foo 可以实现这个,或者甚至只是解释为什么这不起作用,google 在地面上特别薄,尤其是在 \e
转义周围。
使用此处文档:
cat <<'EOF' >>~/.bashrc
bind '"\e[A":history-search-backward'
EOF
EOF
两边的引号表示 here-document 的内容将被视为单引号字符串,因此 $
将按字面意思处理,而不是作为变量前缀。这在这个特定的字符串中无关紧要,但在更一般的应用程序中可能是这样。
此处引用的文档是最简单的方法(如其他人的评论和 Barmar 的回答),但如果您真的想使用 printf
,有几种方法可以做到那。在进入主要问题之前,有两个次要问题:您不需要对字符串中的单引号进行转义,并且 do 需要添加一个换行符 (\n
) 最后(与 echo
不同,printf
不会自动添加)。
你当前命令的最大问题是你将你想要的字符串放在 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
必须在格式字符串中,因此它会被转换为实际的换行符。
或者您可以只使用此处引用的文档。