`declare -p の出力です。` bashからシェル入力として再利用することは保証されていますか?

`declare -p の出力です。` bashからシェル入力として再利用することは保証されていますか?

これは具体的には次のとおりですbash。 -declare通常、次のような場合です。この回答typeset(" // , declare, "のexport -p出力に言及するksh93が、mkshzshいいえbash)。

ローカル/エクスポート/配列/連想配列(namerefではないかもしれません)変数が与えられた場合、fooinの出力は再利用可能であることが保証されますか?これ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 RaimiのBash FAQ持っている:

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ただし、変数に関する情報が見つかりません。

ベストアンサー1

その時あなたが言うことに対する私の答え、もう一つのことも言及されています。

つまり、「...」を使う人だけが安全です。

これにはbashは含まれませんdeclare -p

当時、私が書いた答えには引用された値を使用しbashませんでした。declare -p$'...'スカラー変数ですが、配列変数には使用します。これで状況が変わりました。 5.2では、declare -x a=$'\b'BS文字を含むスカラー変数を出力します(参照:メーリングリストに関する議論)。

しかし、とにかく以前のバージョンは"..."スカラー変数の値を参照する役割を果たし、`特殊\文字はいくつかのロケールで他の文字エンコーディングの一部として見つけることができるエンコーディングを持っていました。

の出力はdeclare -p次のとおりです。故意に(ようにコードの一部のコメントしかも管理者としてのメーリングリストの声明提案)再利用可能とは文書化されていませんが、実際には同じbashシェルの同じバージョンと同じシステムの同じロケール(同じ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では、再入力に適したシェルコードの出力が必要です)それ自体には、シェル変数にマップできない環境変数の定義が含まれています。

また、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"

1つはグローバル変数であり、1declareつはローカル変数であるという事実はの出力に反映されず、両方が関数内で使用される場合、結果変数は最終的にその関数のローカル変数になります。

bashはdeclare明らかにkshをモデルにしたものですtypeset(bashにもtypesetエイリアスがあります)。 ksh86以前では、出力(存在する場合)は共同プロセス(別名)として印刷されtypeset -pます。typeset双方向チューブ)。 ksh88では消えたようです。 ksh93では、typeset -p印刷変数の定義が再び登場しました。

ksh93 マニュアルの現在のバージョンは次のとおりです。:

-p 与えられたvnameの名前、属性、および値は、シェルへの入力として使用できる形式で標準出力に書き込まれます。指定した場合、+p値は表示されません。

しかし、それはすべてです。2008年ksh93tに登場

-pdeclare2.0のbashに追加され、1996年にリリースされました。

このリリースのプレスファイルから:

笑`declare'組み込みには、-a、-F、-pという新しいオプションがあります。

-Fksh93と互換性がありません)

さらにCWRU/changelog:

3/24
組み込み関数/declare.def

  • 変数、その値、および属性を表示するための新しい-pオプション declare -p xxxvarの属性と値を表示します。xxx

実際の実装日は1995年3月24日なので、ksh93以降、ksh93以前は再利用可能な出力を生成すると文書化されています。

おすすめ記事