gpt4 book ai didi

bash - bash printf 转义/引用功能背后的基本原理是什么?

转载 作者:行者123 更新时间:2023-11-29 09:45:26 25 4
gpt4 key购买 nike

使用 bash 4.4,如果我想将参数打印到我的脚本并转义所有可能的非文字字符,那么我可以使用:

printf '%q\n' "${@}"

如果我想引用参数,那么我可以使用:

printf '%s\n' "${@@Q}"

例如:

$ cat tst.sh
#!/usr/bin/env bash

printf 'Escaped: %q\n' "${@}"
echo '---'
printf 'Quoted: %s\n' "${@@Q}"

$ ./tst.sh 'foo bar' 'other .* args'
Escaped: foo\ bar
Escaped: other\ .\*\ args
---
Quoted: 'foo bar'
Quoted: 'other .* args'

为什么?为什么我们不简单地使用一些格式说明符,例如 %E 用于 Escaped%Q 用于 Quoted 而不是%q 的格式说明符表示 Escaped,然后是一个完全不同的、神秘的 "${*@Q}" 语法,在使用时与 %s 组合表示 Quoted?

使用字母 q 而不是 E 来生成 Escapes 令人费解,但我认为这背后有一些历史原因,但我更感兴趣的是出于技术原因,为什么他们不能在第二种情况下使用简单的 %Q 或类似的 printf 修饰符来提高我对 shell 一般工作方式的理解,因为现在我只是不明白为什么当前语法是必需的。

最佳答案

为了编写使用这些工具的脚本,唯一可以信任的保证是文档中给出的保证,如下所示:

对于 printf '%q':

%q - quote the argument in a way that can be reused as shell input

对于@Q参数转换:

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


值得注意的是,不能保证其中一个会使用单引号、反斜杠或任何其他特定形式; 唯一保证是两者都将生成可作为输入重复使用的输出。

其他一切都是未记录的实现细节,因此很容易发生变化。


此外,一些证明这两种构造的行为在实践中可能与问题中给出的描述不同:

$ nl=$'\n'
$ printf '%q\n' "$nl" # in bash 5.0, emits $'\n', not a backslash followed by a newline
$ printf '%s\n' "${nl@Q}" # in bash 5.0, emits $'\n', not a newline in single-quotes

...这进一步证明了这两种构造都可以生成不可移植到基线 POSIX shell 的代码,因此“重用为 shell 输入”或“重用为输入”规范指的是评估由 bash 本身。

关于bash - bash printf 转义/引用功能背后的基本原理是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56103838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com