나는 env
이것이 현재 환경 변수 목록을 인쇄하는 데 사용할 수 있는 쉘 명령이라는 것을 알고 있습니다. 내가 아는 한 RANDOM
그것은 또한 환경 변수입니다.
그렇다면 env
Linux에서 부팅할 때 출력에 왜 포함되지 않습니까 RANDOM
?
답변1
RANDOM
환경변수가 아닙니다. 일부 쉘에서 유지 관리하는 쉘 변수입니다. 기본적으로 일반적으로 내보내지지 않습니다. 이것이 출력에 나타나지 않는 이유입니다 env
.
한 번 이상 사용하면회의에 표시된 출력 자체에는 set
현재 셸 세션의 셸 변수(및 함수)와 해당 값이 나열되어 있습니다. 이 동작은 쉘에 따라 다르며 pdksh
OpenBSD에서 사용되며 RANDOM
이전에 사용되지 않은 경우에도 나열됩니다.set
RANDOM
이 답변의 나머지 부분에서는 내보낸 경우(즉, 환경 변수로 전환된 경우) 발생할 수 있는 일을 다룹니다.
이를 내보내면 export RANDOM
환경 변수가 되지만 하위 프로세스의 값은 "임의이지만 정적"(불변의 난수가 됨을 의미)이므로 사용이 심각하게 제한됩니다. 정확한 동작은 쉘마다 다릅니다.
pdksh
OpenBSD에서 사용하고 있는 아래 예에서는 awk
실행할 때마다 새로운 임의의 값을 얻습니다(그러나동일한매번 동일한 인스턴스 awk
의 값 ). 을 사용하면 bash
정확히 동일한 임의의 값을 얻습니다.모두부르다 awk
.
$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
25444 25444
$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
30906 30906
에서 bash
내보낸 값은 셸에서 사용되는 방식(사용할 때마다 여전히 새 값을 제공함)에 관계없이 정적으로 유지됩니다.RANDOM
RANDOM
$RANDOM
왜냐하면 모든 언급이쉘 변수 RANDOM
in은 bash
쉘이 내부 get_random()
함수에 액세스하여 변수에 새로운 임의의 값을 할당하도록 하지만 쉘은 업데이트되지 않습니다.환경 변수 RANDOM
. 이는 다른 동적 bash
변수(예: LINENO
, SECONDS
등 BASHPID
)와 유사하게 작동합니다.
RANDOM
환경 변수를 업데이트하려면 bash
셸 변수 값을 할당해야 합니다.RANDOM
그리고다시 내보내기:
export RANDOM="$RANDOM"
이것이 난수 생성기를 다시 시드하는 추가 부작용이 있는지는 확실하지 않습니다 bash
(그러나 교육받은 추측은 그렇지 않을 것입니다).
답변2
셸 세션에 설정된 모든 변수가 환경 변수는 아닙니다. "환경 변수"는 내장 함수를 사용하여 환경으로 내보낸 변수만 참조합니다 export
. 이 env
명령은 다음과 같은 내용을 인쇄합니다.환경변하기 쉬운. 예를 들어:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
내보냈는지 여부에 관계없이 세션에 설정된 모든 변수를 보려면 다음을 사용할 수 있습니다 set
.
$ set | grep foo=
foo=bar
내장 set
기능도 함수를 반환하므로 사용할 수 있는 변수만 보려면 다음을 수행하세요.
set | grep '^[^[:space:]]*='
마지막으로, 이 RANDOM
변수는 참조될 때만 값이 할당된다는 점에서 특별합니다. 이것은큰 타격(1):
RANDOM
이 매개변수가 참조될 때마다 0에서 32767 사이의 임의의 정수가 생성됩니다. 값을 할당하여 일련의 난수를 초기화할 수 있습니다.
RANDOM
. 만약에RANDOM
설정하지 않으면 나중에 재설정하더라도 특수 속성이 손실됩니다.
env
따라서 환경 변수라고 생각하더라도 처음 호출할 때까지 설정되지 않았기 때문에 표시되지 않습니다 . 이것이 다음 항목에 표시되지 않는 이유이기도 합니다 set
.
$ set | grep RAN ## returns nothing, RANDOM is unset
$ echo "$RANDOM" ## this will assign a value to RANDOM
1234
$ set | grep RAN ## so now it will also appear in the output of set
RANDOM=1234
답변3
대부분의 쉘은 기본적으로 하위 프로세스로 내보내지지 않는 다른 많은 변수를 설정하거나 사용합니다.
Bash에는 분명히 Bash에만 해당되는 몇 가지 사항이 있습니다.
$ echo "${!BASH*}"
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_LINENO BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION
$ echo $BASH_VERSION
4.4.12(1)-release
$ env|grep -c BASH
0
OPTIND
그런 다음 and OPTERR
(by getopts
), and PS2
, PS3
(보조 프롬프트)와 같은 더 많은 표준 변수와 또 다른 "마법" 변수도 있습니다 : ( SECONDS
쉘이 시작된 이후의 시간을 초 단위로 표시)
Bash에서는 를 통해 모든 변수와 해당 내보내기 상태를 볼 수 있습니다 declare -p
. 표시된 항목은 -x
내보내지고 표시되지 않은 항목은 x
내보내지지 않습니다. (일부에는 i
정수 또는 r
읽기 전용 과 같은 다른 플래그가 있습니다 .)
Zsh 또는 ksh93에서는 사용할 수 있지만 Zsh는 typeset -p
플래그를 사용하는 대신 출력에서 로 변경하여 내보낸 변수를 표시합니다. 자체적으로는 내보낸 모든 변수도 표시하지만 이는 실행을 통해 얻는 것과 거의 동일합니다.typeset
export
export
env
답변4
구글에 검색해 보면 설명서에 다음과 같은 내용이 나와 있습니다.
$RANDOM
내부 Bash입니다기능(상수 아님) 의사 난수를 반환합니다.[1]0 - 32767 범위의 정수입니다. 암호화 키를 생성하는 데 사용해서는 안 됩니다.
를 사용하면 "변수"가 일반 쉘 변수나 환경 변수인 것처럼 명령에 직접 전달되는 strace
것을 볼 수 있지만 이는 쉘에 내장된 내부 함수일 뿐이며 Bash가 확장을 수행하고 있습니다.$RANDOM
$ strace -t echo "random value: $RANDOM"
04:37:58 execve("/bin/echo", ["echo", "random value: 30795"], [/* 27 vars */]) = 0
04:37:58 brk(NULL) = 0x19c1000
04:37:58 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9841351000
...
이 일반 변수와 비교하면 다음과 같습니다.
$ strace -t echo "random value: $SOMEVAR"
04:40:19 execve("/bin/echo", ["echo", "random value: helloworld"], [/* 27 vars */]) = 0
04:40:19 brk(NULL) = 0x154b000
04:40:19 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f659d2eb000
...
변수는 참조로 전달되지 않습니다.