"env" 출력에 $RANDOM이 포함되지 않는 이유는 무엇입니까?

"env" 출력에 $RANDOM이 포함되지 않는 이유는 무엇입니까?

나는 env이것이 현재 환경 변수 목록을 인쇄하는 데 사용할 수 있는 쉘 명령이라는 것을 알고 있습니다. 내가 아는 한 RANDOM그것은 또한 환경 변수입니다.

그렇다면 envLinux에서 부팅할 때 출력에 왜 포함되지 않습니까 RANDOM?

답변1

RANDOM환경변수가 아닙니다. 일부 쉘에서 유지 관리하는 쉘 변수입니다. 기본적으로 일반적으로 내보내지지 않습니다. 이것이 출력에 나타나지 않는 이유입니다 env.

한 번 이상 사용하면회의에 표시된 출력 자체에는 set현재 셸 세션의 셸 변수(및 함수)와 해당 값이 나열되어 있습니다. 이 동작은 쉘에 따라 다르며 pdkshOpenBSD에서 사용되며 RANDOM이전에 사용되지 않은 경우에도 나열됩니다.set


RANDOM이 답변의 나머지 부분에서는 내보낸 경우(즉, 환경 변수로 전환된 경우) 발생할 수 있는 일을 다룹니다.

이를 내보내면 export RANDOM환경 변수가 되지만 하위 프로세스의 값은 "임의이지만 정적"(불변의 난수가 됨을 의미)이므로 사용이 심각하게 제한됩니다. 정확한 동작은 쉘마다 다릅니다.

pdkshOpenBSD에서 사용하고 있는 아래 예에서는 awk실행할 때마다 새로운 임의의 값을 얻습니다(그러나동일한매번 동일한 인스턴스 awk의 값 ). 을 사용하면 bash정확히 동일한 임의의 값을 얻습니다.모두부르다 awk.

$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
25444 25444

$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
30906 30906

에서 bash내보낸 값은 셸에서 사용되는 방식(사용할 때마다 여전히 새 값을 제공함)에 관계없이 정적으로 유지됩니다.RANDOMRANDOM$RANDOM

왜냐하면 모든 언급이쉘 변수 RANDOMin은 bash쉘이 내부 get_random()함수에 액세스하여 변수에 새로운 임의의 값을 할당하도록 하지만 쉘은 업데이트되지 않습니다.환경 변수 RANDOM. 이는 다른 동적 bash변수(예: LINENO, SECONDSBASHPID)와 유사하게 작동합니다.

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플래그를 사용하는 대신 출력에서 ​​로 변경하여 내보낸 변수를 표시합니다. 자체적으로는 내보낸 모든 변수도 표시하지만 이는 실행을 통해 얻는 것과 거의 동일합니다.typesetexportexportenv

답변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
...

변수는 참조로 전달되지 않습니다.

인용하다

관련 정보