쉘 스크립트에 정의된 변수만 인쇄하는 방법은 무엇입니까?

쉘 스크립트에 정의된 변수만 인쇄하는 방법은 무엇입니까?

bash를 가정 해 봅시다쉘 스크립트좋다:

#!/bin/bash 
a=3
b=7
set -o posix
set

이 경우 변수 set나 다른 명령을 실행하십시오.환경 변수 인쇄( env, declare... 등) my ab변수와 a를 출력합니다.많은 변수(및 기능)은 환경( PATH, PWD, TEMP... 등)에서 나옵니다.

이미 존재하는 변수만 인쇄하는 방법이 있습니까?스크립트 중에 정의됨몸?

답변1

스크립트 시작 부분에 변수 목록을 저장하고 이를 스크립트 어딘가에 있는 값과 비교할 수 있습니다. 유사한 명령의 출력은 set명확하지 않습니다. 유사한 명령은 set | sed 's/=.*//'값에 개행 문자가 포함된 변수에서는 작동하지 않습니다. (Bash에서는 실제로 문자열 변수에 대해 작동하지만 배열에는 작동하지 않으며 함수 코드도 표시합니다.) 다음 코드 조각은 현재 정의된 변수(알파벳순)를 안정적으로 나열한다고 생각합니다.

variables=$(tmp=$(declare -p +F); declare () { echo "${2%%=*}"; }; eval "$tmp")

따라서 initial_variables=…스크립트 시작 부분에 설정하고 나중에 값과 비교하십시오. echo목록에서 직접 작업하는 것 외에도 다른 방법을 사용할 수 있습니다 .

initial_variables=" $(tmp=$(declare -p +F); declare () { echo "${2%%=*}"; }; eval "$tmp") "
( tmp=$(declare -p +F)
  declare () {
    case "$initial_variables" in
      *" $2 "*) :;; # this variable was present initially
      *) eval "set -- \"\$$2\" \"\$2\""; echo "locally defined $2=$1";;
    esac
  }
)

답변2

나는 속임수를 썼습니다. 나열하고 싶지 않은 변수의 이름을 "aaa"(다른 파일에서 가져온 것과 같은) 문자로 시작하는 변수로 바꾼 다음 내장 명령을 호출했습니다 compgen -v. 그럼 나는 누른다숫자나는 스크립트에 존재하는 변수를 알고 있습니다.

예를 들어, 다른 파일에서 aaa로 시작하는 두 개의 변수를 얻었고 내 스크립트에는 무작위로 이름이 지정된 세 개의 변수가 있습니다(첫 번째 문자의 범위는처음부터 끝까지), 이 간단한 명령을 스크립트에 입력하면 출력에 다음 세 가지 변수만 나열할 수 있습니다.

compgen -v | tail -n 3

편집하다:
스크립트에 변수가 몇 개 있는지 모르는 경우 다음과 같이 할 수 있습니다.

compgen -v | awk '$0 == "aaauser" {i=1;next};i && i++ <= 100'

어디AAA 사용자~이다마지막으로 알파벳순다른 파일에서 가져온 변수입니다. 알려진 변수에 적용할 수 있습니다.

답변3

comm, 절차적 대체를 사용한 2줄 전략 compgen -v...

ENVVARS="$(compgen -v)"
    :
  <script>
    :
comm -1 -3 <(sort <<< "$ENVVARS") <(compgen -v | sort)

에서 comm --help...

Usage: comm [OPTION]... FILE1 FILE2

Compare sorted files FILE1 and FILE2 line by line.

With no options, produce three-column output.  Column one contains
lines unique to FILE1, column two contains lines unique to FILE2, and
column three contains lines common to both files.

    -1              suppress lines unique to FILE1
    -2              suppress lines unique to FILE2
    -3              suppress lines that appear in both files

comm명령을 사용하면 스크립트 끝에 있는 전체 환경 변수 집합에서 스크립트에 전달된 환경 변수 집합을 "뺄" 수 있으며, 스크립트에서 생성된 환경 변수만 남깁니다.

옵션 -1 및 -3은 이 스크립트에서 생성된 변수(예: "파일 2"의 줄)를 제외한 모든 변수를 삭제합니다. Bash 프로세스 대체는 <(...)변수를 나열하고 정렬한 다음 출력을 파일로 처리하는 데 사용됩니다.

함수에 대해 로컬로 선언된 변수는 기본 스크립트의 범위를 벗어나므로 포함되지 않습니다.

동일한 기술을 사용하여 함수 내에서 생성된 변수를 나열할 수 있습니다. 그러나 이 경우 (_)밑줄로 시작하는 변수 이름을 지정하고 호출 앞에 밑줄을 붙이는 규칙이 compgen더 이상적일 수 있습니다.

LOCALVARS="$(compgen -v _)"

답변4

현재 정의된 모든 변수 이름의 정렬된 목록을 가져오는 이식 가능한 방법은 다음과 같습니다.

v(){ set "${IFS+IFS=\$2}" "$IFS"; unset IFS
     set  $(set|sed -n '/^[_[:alpha:]][[:alnum:]]*=/s/=.*//p'|sort -u) "$@"
     while [ "$#" -gt 2 ] 
     do    eval '[ "${'$1'+1}" = 1 ]' && 
           echo "$1"; shift
     done; eval "$1"
}

목록은 표준 출력 echo으로 편집 됩니다 v()(한 줄에 이름 하나씩). ed 이기 때문에 sort나중에 유사하게 생성된 목록(예: 사용하거나 유사)과 비교할 수 있는 좋은 후보입니다 comm. 이 목록은 의도적으로 제외되었습니다 $IFS. 그 이유는 -가 설정되었거나 설정되지 않았기 때문입니다 $IFS.언제나따라서 실제로 그러한 목록에 포함되어야 합니다. 다음과 같이 변경할 수 있습니다.

set "${IFS+IFS=\$2}" "$IFS"; IFS='
'; set $(set|... 

...하지만 그건 영원할 뿐이야포함하다설정 여부에 관계없이 목록에 있습니다. 이전 요점으로 돌아갑니다.

관련 정보