echo
Bash 3.2.52에서는 환경이 아닌 모든 변수(모든 자체 선언 변수)를 원합니다 .
모든 변수를 인쇄하는 이 명령은 내가 이해할 수 없는 출력을 제공하며 내 생각에는 set -x && clear -r
내가 이미 작업 중인 패턴과 충돌합니다.
diff -U 1 <(set -o posix ; set |cut -d= -f1) <(
exec bash -ic 'set -o posix ; set' | cut -d= -f1) |
grep '^[-][^-]' |
cut -d- -f2 |
grep -vE '^(COLUMNS|HISTFILESIZE|HISTSIZE|LINES|PIPESTATUS)$'
echo
그러한 목록을 얻으려면 또는 printf
(또는 다른 "더 간단한") 작업이 필요합니다 .
이 버전의 Bash에서 가능하다면 어떻게 달성할 수 있나요?
답변1
GNU 병렬 포함 env_parallel
섹션에는 env_parallel
지원되는 셸에 대한 모든 변수가 나열되어 있습니다.
이 코드 의 경우 bash
다음과 같습니다.
_names_of_VARIABLES() {
compgen -A variable
}
_bodies_of_VARIABLES() {
typeset -p "$@"
}
따라서 모든 변수가 주어지면 사용자가 어떤 변수를 설정했는지 알아내야 합니다. 우리를할 수 있는이는 특정 버전에 대한 모든 변수를 하드코딩하여 수행되지만 향후 버전( 사용자 또는 향후 버전 ?) 에서 더 많은 변수가 설정될 수 있으므로 bash
이는 미래에 대한 증거가 아닙니다 .bash
$BASH_MYVAR
bash
따라서 env_parallel
깨끗한 환경을 정의하고 env_parallel --session
그 안에서 실행해야 합니다. 이는 $PARALLEL_IGNORED_NAMES
이전에 정의된 이름을 나열하여 설정됩니다(위 코드 사용).
나중에 사용자가 변수를 설정한 환경에서 실행해 보면 클린 환경과 현재 환경의 차이를 쉽게 알 수 있다.
env_parallel --session
각 세션마다 깔끔한 환경을 정의하는 것이 가능하지만, 세션 전반에 걸쳐 사용할 수 있는 참조 환경을 갖고 싶다면 변수 목록을 파일에 저장하면 됩니다. 그래서:
# In clean envronment
compgen -A variable > ~/.clean-env-vars
# In environment with user defined vars
compgen -A variable | grep -Fxvf ~/.clean-env-vars
예를 들어:
#!/bin/bash
# In clean envronment
compgen -A variable > ~/.clean-env-vars
myvar=4
yourvar=3
# In environment with user defined vars
compgen -A variable | grep -Fxvf ~/.clean-env-vars
# This prints:
# myvar
# yourvar
# PIPESTATUS (which is set when running a pipe)
답변2
이것을 당신의~/.bashrc
pre () {
set -o posix;set > /tmp/tmp-original-envs
}
post () {
set -o posix;set > /tmp/tmp-new-envs
diff /tmp/tmp-original-envs /tmp/tmp-new-envs | grep -v BASH_LINENO | grep -v FUNCNAME | grep '>'
}
pre
그런 다음 수정 전후에 post
실행하십시오 .
예:
[localhost]$ pre
[localhost]$ test=new
[localhost]$ post
> test=new
[localhost]$
답변3
필요에 따라 간단한 솔루션은 다음과 같습니다.
- 수정하기 전에
set > tmp
현재 변수를 사용하거나 저장하십시오.set > /tmp/current
- 애플리케이션을 수정/실행하시나요?
diff -u <(cat tmp) <(set)
또는로 수정된 콘텐츠 추출
diff -u <(cat tmp) <(set) | tail -n +3 | grep -v PIPESTATUS | grep -v "_=" | grep -E "^\+"
어디:
tail -n +3
: diff 명령의 첫 번째 줄에서 불필요한 줄을 삭제합니다.
grep -v PIPESTATUS | grep -v "_="
: 불필요한 변수 삭제
grep -E "^\+"
: 원하는/필요한 변경 사항만 표시
선택하다:
diff -u <(set -o posix; set) <(bash -lc 'set -o posix; set') | grep -E "^\+"
노트:
스크립트에서 exec
시작된 프로세스를 완전히 교체하면 달성하려는 작업이 방해받을 수 있다는 점에 유의하세요.
답변4
서투른 bash 전용 솔루션:
(setn(){
set | sed '/^{/,/^}/d;/=/!d;/^BASH[A-Z_]*=\|^PPID=\|^SHLVL=\|^PIPESTATUS=\|^HISTSIZE=\|^HISTFILESIZE=\|^_[a-z_]*=/d' | sort
}
export -f setn
comm -23 <(setn) <("$BASH" -ic setn))
또한 다른 변수를 필터링 해야 할 수도 있습니다 sed
(또는 패턴을 더 제한적으로 만들어야 할 수도 있습니다 ). 또는 와 같은 프로그래밍 가능한 완성으로 정의된 변수는 제외 BASH..
되어야 하며 이는 더 제한적일 수도 있습니다. /_[a-z_]*=/
_backup_glob
_xspecs
bash
형식에 흥미로운 문자가 포함된 변수 값이 인쇄되므로 $'...'
이를 처리해야 합니다.
foo='
bar
baz
'
...
foo=$'\nbar\nbaz\n'
bash
쉘 변수는 envvar에서 생성되지 않습니다.이름줄 바꿈 문자가 포함되어 있으므로 이와 같은 트릭으로 이 해킹을 해독할 방법이 없습니다.