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"
모든 셸 변수 이름을 인쇄해야 합니다.파일을 소싱하기 전과 후에 어떤 변수가 새로운지 "설정"과 마찬가지로 목록을 얻을 수 있습니다(다른 답변 참조).그러나 diff를 사용한 이러한 필터링은 파일을 소스하기 전에 필요하지만 존재하는 일부 변수를 필터링할 수 있습니다.
이 경우 변수 이름이 "VARIVEL"로 시작하는 경우 스크립트를 소스화하여 다음 작업을 수행할 수 있습니다.
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
스크립트의 시작과 끝에 각각 다른 파일을 호출하고 두 파일에 대해 다른 작업을 수행합니다.여기에는 여전히 약간의 소음이 포함되어 있습니다.
프로그램적으로 이 작업을 수행할 수도 있습니다.출력을 현재 범위로만 제한하려면 변수 생성 래퍼를 구현해야 합니다.예를들면
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
파티에 조금 늦었지만 다른 제안이 있습니다.
#!/bin/bash
set_before=$( set -o posix; set | sed -e '/^_=*/d' )
# create/set some variables
VARIABLE1=a
VARIABLE2=b
VARIABLE3=c
set_after=$( set -o posix; unset set_before; set | sed -e '/^_=/d' )
diff <(echo "$set_before") <(echo "$set_after") | sed -e 's/^> //' -e '/^[[:digit:]].*/d'
diff+sed 파이프라인 명령줄은 OP의 게시물에 지정된 대로 원하는 형식으로 모든 스크립트 정의 변수를 출력합니다.
VARIABLE1=a
VARIABLE2=b
VARIABLE3=c
답과 @ 또는 의해 @ @GinkoFr @Tino @DujayClayton @Douglas @보다 더 합니다.한 리더의리함영.set -o posix
슬롯:
+ function SOLUTION() { (set +o posix; set) | sed -ne '/^\w\+=/!q; p;'; }
이가 없는 첫 보고서를 들어 차: 된▁reported예▁by▁function▁first,▁the▁stops▁reportable▁solution▁this▁the▁that▁non▁first-vari다것▁after▁diffe이▁e니입는rence▁isg차후다중▁the(이에 의해 보고된 첫 번째 함수가 보고된 후에 의해 중지된다는 것입니다.set
BTW: "티노" 문제는 해결되었습니다.이 POSIX에 의해 에도 POSIX에 보고됩니다.set
,sed ...
▁through(▁()를 통해서만 가변 합니다.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
@: @Douglas에서 하는 은 "포함된 값) 을 있습니다.Leeder는 "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에 대해 100%>, < % 확신합니다.set
항상 값 내의 새 줄을 다음으로 변환합니다.\n
이 솔루션은 "Dejay Clayton" 문제를 피하기 위해 사용됩니다.그게 현대적인 행동일까요?아니면 컴파일 시간 변화? 라오.set -o
또는shopt
옵션 설정?그러한 변형을 알고 있다면 코멘트를 추가해 주십시오...
정적 값이 있는 변수 목록을 인쇄하는 데만 관심이 있다면(예: 이 경우 확장이 작동하지 않음) 다른 옵션은 정적 변수 정의 블록이 어디에 있는지 알려주는 시작 및 끝 마커를 파일에 추가하는 것입니다.
#!/bin/bash
# some code
# region variables
VAR1=FOO
VAR2=BAR
# endregion
# more code
그러면 파일의 그 부분만 인쇄하면 됩니다.
제가 생각해 낸 것은 다음과 같습니다.
function show_configuration() {
local START_LINE=$(( $(< "$0" grep -m 1 -n "region variables" | cut -d: -f1) + 1 ))
local END_LINE=$(( $(< "$0" grep -m 1 -n "endregion" | cut -d: -f1) - 1 ))
< "$0" awk "${START_LINE} <= NR && NR <= ${END_LINE}"
}
변수 이 이 가 있는하십시오. 할 동 파 있 사 로 므 으 수 있 습 니 다 에 일 한 일 는 가 록 함 수 이 이 있 ▁first 니 다 습 ▁use$0
파일 내용에 액세스할 수 있습니다.
코드의 다른 영역을 구분하기 위해 "지역" 마커를 사용합니다.그래서 저는 간단하게grep
"선택된" 영역 마커의 경우(첫 번째 일치:grep -m 1
및 ) 및셋grep
번호에 접두사를 붙입니다.grep -n
는 매치 출력에서 줄은 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .:
이나 뺄셈을 .1
마커가 출력물의 일부가 되는 것을 원하지 않기 때문입니다.
그 이제사는파범일인쇄면려하위를용을 사용합니다.awk
라인 번호 조건을 사용합니다.
스크립트를 사용해 보십시오("ls_vars"라고 부릅니다).
#!/bin/bash
set -a
env > /tmp/a
source $1
env > /tmp/b
diff /tmp/{a,b} | sed -ne 's/^> //p'
chmod +xit, 그리고:
ls_vars your-script.sh > vars.files.save
보안 측면에서 볼 때, @akostadinov의 답변이나 @YoungXu의 답변 중 하나가 가상 머신의 비정형 출력에 의존하는 것보다 더 좋습니다.set
다음과 같은 잠재적인 보안 결함으로 인해 명령이 실행됩니다.
#!/bin/bash
function doLogic()
{
local COMMAND="${1}"
if ( set -o posix; set | grep -q '^PS1=' )
then
echo 'Script is interactive'
else
echo 'Script is NOT interactive'
fi
}
doLogic 'hello' # Script is NOT interactive
doLogic $'\nPS1=' # Script is interactive
의 함수는 다음과 .doLogic
사용하다set
변수가 합니다.PS1
스크립트가 대화형인지 여부를 확인합니다(이 방법이 해당 목표를 달성하는 가장 좋은 방법인지는 신경쓰지 마십시오. 예에 불과합니다.).
그나, 출은의 set
비정형이므로 새 줄이 포함된 변수가 결과를 완전히 오염시킬 수 있습니다.
물론 이것은 잠재적인 보안 위험입니다.확장을 하거나 Bash의 지원을 합니다.compgen -v
.
사용해 보십시오.set | egrep "^\w+="
(| less
배관)
번째 해결책인 첫번째제해은책결된안,,,( set -o posix ; set ) | less
는 작동하지만 터미널에 제어 코드를 전송하여 제대로 표시되지 않는 단점이 있습니다.그래서 예를 들어, 만약 (가능성이) 있다면,IFS=$' \t\n'
변수, 우리는 볼 수 있습니다:
IFS='
'
…어쨌든.
나의egrep
솔루션은 이를 올바르게 표시하고 최종적으로 다른 유사한 항목도 표시합니다.
제가 아마 아까 답을 훔쳤을 거예요...어쨌든 func로서 약간 다릅니다.
##
# usage source bin/nps-bash-util-funcs
# doEchoVars
doEchoVars(){
# if the tmp dir does not exist
test -z ${tmp_dir} && \
export tmp_dir="$(cd "$(dirname $0)/../../.."; pwd)""/dat/log/.tmp.$$" && \
mkdir -p "$tmp_dir" && \
( set -o posix ; set )| sort >"$tmp_dir/.vars.before"
( set -o posix ; set ) | sort >"$tmp_dir/.vars.after"
cmd="$(comm -3 $tmp_dir/.vars.before $tmp_dir/.vars.after | perl -ne 's#\s+##g;print "\n $_ "' )"
echo -e "$cmd"
}
그printenv
명령:
printenv
인쇄합니다. 인.environment variables
그들의 가치관과 함께.
행운을 빕니다...
간단한 방법은 스크립트를 실행하기 전에 시스템 환경 변수를 설정하여 bash strict 모드를 사용하고 diff를 사용하여 스크립트의 변수만 정렬하는 것입니다.
# Add this line at the top of your script :
set > /tmp/old_vars.log
# Add this line at the end of your script :
set > /tmp/new_vars.log
# Alternatively you can remove unwanted variables with grep (e.g., passwords) :
set | grep -v "PASSWORD1=\|PASSWORD2=\|PASSWORD3=" > /tmp/new_vars.log
# Now you can compare to sort variables of your script :
diff /tmp/old_vars.log /tmp/new_vars.log | grep "^>" > /tmp/script_vars.log
이제 /tmp/script_vars.log에서 스크립트의 변수를 검색할 수 있습니다.아니면 적어도 그것을 기반으로 한 무언가!
TL;DR
포함:typeset -m <GLOBPATH>
$ VARIABLE1=abc
$ VARIABLE2=def
$ VARIABLE3=ghi
$ noglob typeset -m VARIABLE*
VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi
대 한 문에 대한 설명서.typeset
에서 찾을 수 있습니다.man zshbuiltins
또는man zshall
.
언급URL : https://stackoverflow.com/questions/1305237/how-to-list-variables-declared-in-script-in-bash
'programing' 카테고리의 다른 글
ID ######인 다른 프로세스가 현재 ngcc를 실행하고 있습니다. (0) | 2023.05.17 |
---|---|
깃 분기의 태그를 다른 커밋으로 이동하려면 어떻게 해야 합니까? (0) | 2023.05.17 |
인터페이스에 정의된 C#4 옵션 매개 변수가 구현 클래스에 적용되지 않는 이유는 무엇입니까? (0) | 2023.05.17 |
이클립스 Tomcat 7 빈 서버 이름 추가 (0) | 2023.05.17 |
NSA 속성 문자열은 어떻게 사용합니까? (0) | 2023.05.17 |