it-swarm-ko.tech

bash에서 정의 된 변수 (쉘 및 / 또는 환경 변수) 만 인쇄하는 방법

Bash 내장 명령 set는 인수없이 호출되면 모든 셸 및 환경 변수뿐만 아니라 정의 된 모든 함수를 인쇄합니다. 이로 인해 사람이 출력을 사용할 수없고 grep하기가 어렵습니다.

Bash 내장 명령 set를 변수가 아닌 함수 만 인쇄하도록하려면 어떻게해야합니까?

함수없이 쉘 변수 만 인쇄하는 다른 명령이 있습니까?

참고 : bash는 셸 변수와 환경 변수를 구분합니다. 여기를 참조하십시오 bash에서 환경 변수와 내 보낸 환경 변수의 차이점

59
lesmana

"함수없이 셸 변수 만 인쇄하는 다른 명령이 있습니까?"

Man bash의 Shell BUILTIN COMMANDS 섹션 (set 섹션)에 "posix 모드에서는 Shell 변수 만 나열됩니다."라는 메시지가 표시됩니다.

(set -o posix; set)

노트: () 구문은 서브 쉘을 생성합니다. 포크를 원하지 않으면 더 자세한 버전 만 사용하십시오.

set -o posix; set; set +o posix
54
temp

몇 가지 해결 방법은 다음과 같습니다.

$ comm -3 <(declare | sort) <(declare -f | sort)

고장:

  1. declare는 정의 된 모든 변수 (내 보낸 여부)와 함수를 인쇄합니다.
  2. declare -f는 기능 만 인쇄합니다.
  3. comm -3는 둘 모두에 공통 인 모든 행을 제거합니다. 실제로 이것은 변수 만 남기고 함수를 제거합니다.

내 보내지 않은 변수 만 인쇄하려면 :

$ comm -3 <(comm -3 <(declare | sort) <(declare -f | sort)) <(env | sort)

다른 해결 방법 :

$ declare -p

변수 만 인쇄하지만 추악한 속성이 표시됩니다.

declare -- BASH="/bin/bash"
declare -ir BASHPID=""
declare -A BASH_ALIASES='()'
declare -a BASH_ARGC='()'
...

다음을 사용하여 속성을 잘라낼 수 있습니다.

$ declare -p | cut -d " " -f 3

한 가지 단점은 IFS의 값이 표시되는 대신 해석된다는 것입니다.

비교:

$ comm -3 <(declare | sort) <(declare -f | sort)
...
IFS=$' \t\n'
...
$ declare -p | cut -d " " -f 3
...
IFS="
"
...

한 줄에 "가 있기 때문에 출력을 추가 처리에 사용하기가 매우 어렵습니다. 이를 방지하기 위해 IFS-fu를 수행 할 수 있습니다.


compgen를 사용하는 또 다른 해결 방법 :

$ compgen -v

Bash 내장 compgen은 완성 스크립트에서 사용하기위한 것입니다. 이를 위해 compgen -v는 정의 된 모든 변수를 나열합니다. 단점 : 변수 이름 만 나열하고 값은 나열하지 않습니다.

다음은 값을 나열하는 해킹입니다.

$ compgen -v | while read var; do printf "%s=%q\n" "$var" "${!var}"; done

장점은 순수한 bash 솔루션입니다. 단점 : printf을 통한 해석으로 인해 일부 값이 엉망입니다. 또한 파이프 및/또는 루프의 서브 쉘은 추가 변수를 추가합니다.

32
lesmana

typeset 내장 기능에는 이상하게 만 기능 (-f) 만 표시하는 옵션이 있지만 매개 변수 만 표시하지는 않습니다. 다행히 typeset (또는 set)은 모든 함수, 함수 및 매개 변수 이름에 개행이나 등호를 포함 할 수없고 매개 변수 값의 개행을 인용하기 전에 모든 매개 변수를 표시합니다 (\n). 따라서 등호가 포함되지 않은 첫 번째 줄에서 멈출 수 있습니다.

set | awk -F '=' '! /^[0-9A-Z_a-z]+=/ {exit} {print $1}'

매개 변수 이름 만 인쇄합니다. 값을 원하면 print $1print $0로 변경하십시오.

이는 환경 변수뿐만 아니라 모든 매개 변수 이름 (여기에서 매개 변수 및 변수는 동의어로 사용됨)을 인쇄합니다 ( "환경 변수"는 "내 보낸 매개 변수"와 동의어 임).

또한 매개 변수 이름에 대한 bash의 제한 조건과 일치하지 않는 이름을 가진 환경 변수가 없다고 가정합니다. 이러한 변수는 bash 내부에서 만들 수 없지만 bash가 시작될 때 환경에서 상속 될 수 있습니다.

env 'foo ()
{
  =oops' bash

set가 변수 만 인쇄하는 방법을 잘 모르겠습니다. 그러나 set의 결과를 살펴보면 변수를 얻는 것처럼 보이는 다음을 생각 해낼 수있었습니다.

$ set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" 

기본적으로 문자, 숫자 또는 문장 부호로 시작하고 "="로 시작하는 줄을 찾고 있습니다. 내가 본 결과에서, 이것은 모든 변수를 잡습니다. 그러나 이것이 매우 이식성이 있는지 의심합니다.

제목에서 알 수 있듯이 내 보낸 변수를이 목록에서 빼서 내 보내지 않은 변수의 목록을 얻으려면 다음과 같이 할 수 있습니다

$ set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars && env | sort | comm -23 ./setvars - 

이것을 조금 나누려면 다음과 같이하십시오.

  1. set | grep "^\([[:alnum:]]\|[[:punct:]]\)\+=" | sort > ./setvars : 이것은 희망적으로 모든 변수를 가져오고 (앞서 설명한대로) 정렬 한 후 결과를 파일에 붙여 넣습니다.
  2. && env | sort : 이전 명령이 완료되면 env를 호출하고 출력을 정렬합니다.
  3. | comm -23 ./setvars - : 마지막으로 env의 정렬 된 출력을 comm에 파이프하고 -23 옵션을 사용하여 첫 번째 인수에 고유 한 행을 인쇄합니다. 이 경우 set의 출력에 고유 한 행입니다.

완료되면 rm ./setvars 명령으로 생성 한 임시 파일을 정리할 수 있습니다.

7
Steven D

env 명령 만 사용하십시오. 기능을 인쇄하지 않습니다.

6
unxnut

Printenv 명령을 시도하십시오 :

$printenv
2
Emilio R.

Bash에서는 변수 이름 만 인쇄합니다.

compgen -v

또는 값이 필요한 경우 다음을 사용하십시오.

declare -p
1
Isaac

받아 들여진 대답은 훌륭합니다. POSIX 모드 설정을 포함하지 않는 대안을 제공하고 있습니다.

다음은 함수 상태를 파일에 저장하는 데 사용한 기술이므로 나중에 계속 진행할 수 있습니다. 첫 번째는 상태 덤프를 생성하고 두 번째는 변수 이름 목록 만 생성합니다.

set 2>/dev/null | while read a; do [[ $a == *=* ]] || break; echo $a; done 

set 2>/dev/null | while read a; do [[ $a == *=* ]] || break; echo ${a/=*}; done 

두 함수 모두 첫 번째 함수가 나열 될 때 발생하는 '='문자가없는 줄을 찾을 때까지 줄을 덤프하여 작동합니다. 후자는 과제를 잘라냅니다.

0
Wil

rc 스크립트의 vars가 빠지지 않도록 깨끗한 ​​Shell과 비교

## get mostly local vars
diff_env(){
    diff <(bash -cl 'set -o posix && set') \
        <(set -o posix && set && set +o posix) | \
        grep -E "^>|^\+" | \
        grep -Ev "^(>|\+|\+\+) ?(BASH|COLUMNS|LINES|HIST|PPID|SHLVL|PS(1|2)|Shell|FUNC)" | \
        sed -r 's/^> ?|^\+ ?//'
}

comm 버전은 너무 복잡합니다.

0
untore