Bash 相当于 Python 的 shlex.quote

Bash equivalent of Python's shlex.quote

Python 的标准库有一个 shlex.quote 函数,它接受一个字符串和 returns 一个保证被 Unix shell 解释为相同字符串的函数秒。这是通过将字符串放在单引号中并转义其中出现的任何单引号字符来实现的。

这个功能很有用,例如当您正在模板化 shell 脚本并且不能保证替换值仅包含“shell-safe”字符串时。

我的问题:是否有一个用纯 bash 编写的等效项,最多依赖 coreutils?或者甚至是我不知道的 bash 内置机制?


展示如何使用此类实用程序的最小示例(此处称为 shlex_quote 作为占位符):

generate_greeting_script.sh:

#!/bin/bash
cat > greet.sh <<HEREDOC
#!/bin/bash
greeting=$(shlex_quote "")
echo "$greeting $(whoami)!"
HEREDOC
chmod +x greet.sh
$ ./generate_greeting_script.sh "'ello"
$ ./greet.sh
'ello govnah!

它与使用 Python 的 shlex.quoteshlex_quote 实用程序一起工作得很好,但是仅将 Python 作为依赖项就太过分了。

既然你引用了bash,你可以在printf中使用bash特定格式字符“q”:

$ printf '%q\n' "The world is fuiled by $s isn't it?" 
The\ world\ is\ fuiled\ by\ $s\ isn\'t\ it\?

来自 bash 上的文档:

%q
Causes printf to output the corresponding argument in a format that can be reused as shell input.

https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html

我想你正在寻找 Bash-specific printf %q 格式说明符:

$ read &&  printf "%q\n" "$REPLY"
"very*complicated_&&;$stuff--string'""""'"<<!!
\"very\*complicated_\&\&\;$stuff--string\'\"\"\"\"\'\"\<\<\!\!
$ echo \"very\*complicated_\&\&\;$stuff--string\'\"\"\"\"\'\"\<\<\!\!
"very*complicated_&&;$stuff--string'""""'"<<!!

</code>引用的内容放入变量<code>greeting:

printf -v greeting '%q' ""

printf.

使用 Bash-specific -v 选项和 %q 格式字符串

或使用@Q变量展开

cat generate_greeting_script:

#!/usr/bin/env bash

cat >greet <<HEREDOC
#!/usr/bin/env bash

printf ${1@Q}' %s!\n' "$USER"
HEREDOC
chmod +x greet
./generate_greeting_script 'I say hello to'

不需要带有 shebang 的可执行脚本的 .sh 扩展。

生成greet:

#!/usr/bin/env bash

printf 'I say hello to'' %s!\n' "$USER"

输出:

./greet
I say hello to lea!

引用man bash:

${parameter@operator}

Parameter transformation.

The expansion is either a transformation of the value of parameter or information about parameter itself, depending on the value of operator. Each operator is a single letter:

Q

The expansion is a string that is the value of parameter quoted in a format that can be reused as input.