[bash] bash에서 스크립트에 선언 된 변수를 나열하는 방법은 무엇입니까?

bash의 내 스크립트에는 많은 변수가 있으며 파일에 저장할 무언가를 만들어야합니다. 내 질문은 내 스크립트에 선언 된 모든 변수를 나열하고 다음과 같은 목록을 얻는 방법입니다.

VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi



답변

set 변수를 출력하지만 불행히도 함수 정의도 출력합니다.

다행히 POSIX 모드는 변수 만 출력합니다.

( set -o posix ; set ) | less

로 파이핑 less하거나 옵션을 원하는 위치로 리디렉션합니다.

따라서 스크립트에서 선언 된 변수를 얻으려면 :

( set -o posix ; set ) >/tmp/variables.before
source script
( set -o posix ; set ) >/tmp/variables.after
diff /tmp/variables.before /tmp/variables.after
rm /tmp/variables.before /tmp/variables.after

(또는 적어도 그것을 기반으로 한 것 :-))


답변

compgen -v

지역 변수를 포함한 모든 변수를 나열합니다. 이름이 특정 패턴과 일치하는 변수 목록 가져 오기에서 배웠고 스크립트 에서 사용했습니다 .


답변

for i in _ {a..z} {A..Z}; do eval "echo \${!$i@}" ; done | xargs printf "%s\n"

모든 쉘 변수 이름을 인쇄해야합니다. 어떤 변수가 새로운 것인지 비교하기 위해 “set”을 사용하는 것처럼 파일을 소싱하기 전후에 목록을 얻을 수 있습니다 (다른 답변에서 설명 됨). 그러나 diff를 사용한 이러한 필터링은 필요하지만 파일을 소싱하기 전에 존재했던 일부 변수를 필터링 할 수 있음을 명심하십시오.

귀하의 경우 변수 이름이 “VARIABLE”로 시작하는 것을 알고 있다면 스크립트를 소싱하고 다음을 수행 할 수 있습니다.

for var in ${!VARIABLE@}; do
   printf "%s%q\n" "$var=" "${!var}"
done

업데이트 : 순수 BASH 솔루션의 경우 (외부 명령이 사용되지 않음) :

for i in _ {a..z} {A..Z}; do
   for var in `eval echo "\\${!$i@}"`; do
      echo $var
      # you can test if $var matches some criteria and put it in the file or ignore
   done 
done


답변

위의 답변 중 일부를 바탕으로 이것은 나를 위해 일했습니다.

before=$(set -o posix; set | sort);

소스 파일 :

comm -13 <(printf %s "$before") <(set -o posix; set | sort | uniq) 


답변

후 처리를 할 수 있다면 (이미 언급했듯이) set스크립트의 시작과 끝에 (각각 다른 파일에 대해) 호출하고 두 파일에 대해 diff를 수행 할 수 있습니다. 여기에는 여전히 약간의 소음이 포함되어 있음을 인식하십시오.

프로그래밍 방식으로도 수행 할 수 있습니다. 출력을 현재 범위로만 제한하려면 변수 생성에 대한 래퍼를 구현해야합니다. 예를 들면

store() {
    export ${1}="${*:2}"
    [[ ${STORED} =~ "(^| )${1}($| )" ]] || STORED="${STORED} ${1}"
}

store VAR1 abc
store VAR2 bcd
store VAR3 cde

for i in ${STORED}; do
    echo "${i}=${!i}"
done

어느 양보

VAR1=abc
VAR2=bcd
VAR3=cde


답변

다음은 @GinkgoFr 답변과 비슷하지만 @Tino 또는 @DejayClayton으로 식별되는 문제가 없으며 @DouglasLeeder의 영리한 set -o posix비트 보다 더 강력합니다 .

+ function SOLUTION() { (set +o posix; set) | sed -ne '/^\w\+=/!q; p;'; }

차이점은이 솔루션이 첫 번째 비 변수 보고서 (예 : set

BTW : “티노”문제가 해결되었습니다. POSIX가 꺼져 있고 함수가에 의해보고 되더라도 솔루션 setsed ...일부는 (예 : VAR=VALUE줄)을 통한 변수 보고서 만 허용합니다 . 특히 A2는 가짜로 출력으로 만들지 않습니다 .

+ function a() { echo $'\nA2=B'; }; A0=000; A9=999;
+ SOLUTION | grep '^A[0-9]='
A0=000
A9=999

AND : “DejayClayton”문제가 해결되었습니다 (변수 값에 포함 된 줄 바꿈 은 출력을 방해 하지 않습니다VAR=VALUE .

+ A1=$'111\nA2=222'; A0=000; A9=999;
+ SOLUTION | grep '^A[0-9]='
A0=000
A1=$'111\nA2=222'
A9=999

참고 : @DouglasLeeder에서 제공하는 솔루션은 “DejayClayton”문제 (새 줄이 포함 된 값)로 어려움을 겪습니다. 아래 A1는 잘못된 것이며 A2전혀 표시해서는 안됩니다.

$ A1=$'111\nA2=222'; A0=000; A9=999; (set -o posix; set) | grep '^A[0-9]='
A0=000
A1='111
A2=222'
A9=999

마지막으로 : bash문제 의 버전은 생각하지 않지만 그럴 수도 있습니다. 나는 이것을 테스트 / 개발했습니다.

$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-msys)

POST-SCRIPT : OP에 대한 다른 응답 중 일부를 감안할 때 set 항상 값 내에서 줄 바꿈을으로 변환 하는 것이 100 % 미만임을 확신합니다. \n이 솔루션은 “DejayClayton”문제를 피하기 위해 의존합니다. 아마도 그것은 현대적인 행동일까요? 아니면 컴파일 시간 변형입니까? 또는 set -o또는 shopt옵션 설정? 이러한 변형 알고 있다면 의견을 추가하십시오 …


답변

스크립트를 사용해보십시오 ( “ls_vars”라고 부릅니다).

  #!/bin/bash
  set -a
  env > /tmp/a
  source $1
  env > /tmp/b
  diff /tmp/{a,b} | sed -ne 's/^> //p'

chmod + x it 및 :

  ls_vars your-script.sh > vars.files.save