bash를 가정 해 봅시다쉘 스크립트좋다:
#!/bin/bash
a=3
b=7
set -o posix
set
이 경우 변수 set
나 다른 명령을 실행하십시오.환경 변수 인쇄( env
, declare
... 등) my a
및 b
변수와 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|...
...하지만 그건 영원할 뿐이야포함하다설정 여부에 관계없이 목록에 있습니다. 이전 요점으로 돌아갑니다.