AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 769335
Accepted
muru
muru
Asked: 2024-02-15 12:22:28 +0800 CST2024-02-15 12:22:28 +0800 CST 2024-02-15 12:22:28 +0800 CST

bash 中 `declare -p <variable>` 的输出是否保证可重用为 shell 输入?

  • 772
赏金将在 5 天后到期。此问题的答案有资格获得+100声誉奖励。 muru正在从信誉良好的来源寻找答案。

这是专门关于bash的- 在这个答案declare中对一般情况进行了非常详尽的处理(其中提到“ // , ,的输出”,但没有提到的输出)。typesetdeclareexport -pksh93mkshzshbash

给定一个本地/导出/数组/关联数组(但可能不是 nameref)变量, infoo的输出是否保证可重用?官方文档没有提到类似的内容:declare -p foobashbash

该-p选项将显示每个的属性和值name。当-p与参数一起使用时,除和name之外的其他选项将被忽略。-f-F

我浏览了一下CHANGES,看到了关于函数的内容:

This document details the changes between this version, bash-2.05-beta1,
and the previous version, bash-2.05-alpha1.
...
b.  When `set' is called without options, it prints function definitions in a
    way that allows them to be reused as input.  This affects `declare' and
    `declare -p' as well.

对于其他几个命令,-p旨在生成可重用的输出:

s.  The `shopt' `-p' option now causes output to be displayed in a reusable
    format.
...
u.  `umask' now has a `-p' option to print output in a reusable format.

Chet Ramey 的 Bash 常见问题解答有:

Bash-2.0 contained extensive changes and new features from bash-1.14.7.
Here's a short list:
...
most builtins use -p option to display output in a reusable form
    (for consistency)

但我找不到任何关于declare -p变量的信息。

bash
  • 2 2 个回答
  • 70 Views

2 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2024-02-19T18:47:11+08:002024-02-19T18:47:11+08:00

    在您提到的我的答案中,其他要点之一也提到:

    或者换句话说,只有那些使用“...”的才是安全的

    其中不包括 bash 的declare -p.

    在我写到的时候,答案bash并declare -p没有用于引用标量$'...'变量的值,但它确实将其用于数组变量。现在情况已经改变,因为我可以看到 5.2 输出包含 BS 字符的标量变量(请参阅邮件列表上的相关讨论)。declare -x a=$'\b'

    但是,无论如何,旧版本确实用于"..."引用标量变量的值,其中`和\是特殊的,并且这些字符具有可以作为某些语言环境中其他字符的编码的一部分找到的编码。

    的输出declare -p是有意的(正如代码中的一些注释以及邮件列表上维护者的声明所暗示的那样)如果没有记录为可重用,但实际上仅(如果有的话)在同一 bash shell 的同一版本中并在同一系统上的同一语言环境中(相同的 libc 和语言环境定义)。

    在带有 bash 5.0.17 的 Ubuntu 20.04 上:

    $ a=$'\n\xa3`' bash -c 'declare -p a; echo declare -p a' | LC_ALL=zh_CN.gb18030 bash
    bash: line 2: unexpected EOF while looking for matching ``'
    bash: line 4: syntax error: unexpected end of file
    
    $ a=$'\n\xa3`uname; : \xa3`' bash -c 'declare -p a; echo declare -p a' | LC_ALL=zh_CN.gb18030 bash
    declare -x a="
    �\\Linux\""
    

    unamedeclare -p当在使用 UTF-8 作为字符映射的语言环境中获得的输出被在使用 GB18030 作为字符映射的语言环境中运行的 bash 解释时,运行(幸运的是,无害) 。

    过去已修复了许多错误(请参阅此或此作为示例),其中引用未正确完成,或者declare -p(或export -pPOSIX 要求输出适合重新输入的 shell 代码)仅包括来自环境的变量定义无法映射到 shell 变量。

    另请注意,在 bash 中,有效变量名的构成取决于区域设置。

    $ locale charmap
    UTF-8
    $ LC_ALL=fr_FR locale charmap
    ISO-8859-1
    $ env -i $'\xe9=zzz' LC_ALL=fr_FR bash -c $'declare -p \xe9' | bash
    bash: line 1: declare: `�=zzz': not a valid identifier
    

    字节 0xe9 在 ISO-8859-1 中是 é,它是一个单字节[[:alpha:]],因此允许在变量名称中使用,而在 UTF-8 中,它甚至不能形成有效字符。

    还要注意:

    $ bash -c 'a=1; f() { local b=2; declare -p a b; }; f'
    declare -- a="1"
    declare -- b="2"
    

    一个是全局的,一个是局部的这一事实并未反映在declare的输出中,如果两者都在函数内部使用,则生成的变量最终将成为该函数的局部变量。

    bashdeclare显然是仿照 ksh 的typeset(bash 也有一个typeset别名)。在 ksh86 及更早版本中,typeset -p是将输出(如果有)打印typeset到协进程(也称为双向管道)。看来它在 ksh88 中消失了。在 ksh93 中,typeset -p重新出现打印变量定义。

    当前版本的 ksh93 手册有:

    -p 给定 vname 的名称、属性和值以可用作 shell 输入的形式写入标准输出。如果+p指定,则不显示值。

    但这种说法直到2008 年才出现在 ksh93t 中。

    -pdeclare在 1996 年发布的 2.0 中被添加到 bash 中

    从该版本的新闻文件中:

    kk。`declare' 内置命令有新选项:-a、-F、-p。

    (-F与 ksh93 不兼容)

    还有CWRU/changelog:

    3/24
    内置函数/declare.def

    • 用于显示变量及其值和属性的新 -p 选项 declare -p xxx显示 var 的 attribs 和值xxx

    实际实现日期为 1995 年 3 月 24 日,因此在 ksh93 之后但在 ksh93 之前,记录了它生成可重用的输出。

    • 4
  2. Thomas Guyot-Sionnest
    2024-02-15T16:39:02+08:002024-02-15T16:39:02+08:00

    Bash 的很多功能都是从 Ksh 复制的。由于 bash 和 ksh 下具有相同功能的相同开关,因此应该预期 Ksh 答案也适用于 Bash。

    我个人的理解是, 的输出declare -p是可重用的,而且我还没有见过不可以重用的情况。

    • 0

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve