`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"

하나는 전역 변수이고 하나는 로컬 변수라는 사실은 declare의 출력에 반영되지 않으며 둘 다 함수 내에서 사용되는 경우 결과 변수는 결국 해당 함수에 대해 로컬 변수가 됩니다.

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 이전에는 재사용 가능한 출력을 생성한다고 문서화되어 있습니다.

답변2

Bash의 많은 기능은 Ksh에서 복사되었습니다. 동일한 스위치는 bash와 ksh에서 동일한 기능을 가지므로 Ksh 답변이 Bash에도 적용될 것으로 예상해야 합니다.

개인적으로 이해한 바에 따르면 의 출력은 declare -p재사용이 가능하며 재사용할 수 없는 상황은 본 적이 없습니다.

관련 정보