Why isn't $RANDOM included in the output of 'env'?
Clash Royale CLAN TAG#URR8PPP
up vote
22
down vote
favorite
I know env
is a shell command, it can be used to print a list of the current environment variables. And as far as I understand, RANDOM
is also
a environment variable.
So why, when I launch env
on Linux, does the output not include RANDOM
?
shell environment-variables
add a comment |Â
up vote
22
down vote
favorite
I know env
is a shell command, it can be used to print a list of the current environment variables. And as far as I understand, RANDOM
is also
a environment variable.
So why, when I launch env
on Linux, does the output not include RANDOM
?
shell environment-variables
4
env
is not a shell command since it is usually not built into the shell.
â schily
Jul 5 at 9:24
@schily BTW for Bash,declare -x
is the equivalent in a shell builtin.
â wjandrea
Jul 5 at 17:43
add a comment |Â
up vote
22
down vote
favorite
up vote
22
down vote
favorite
I know env
is a shell command, it can be used to print a list of the current environment variables. And as far as I understand, RANDOM
is also
a environment variable.
So why, when I launch env
on Linux, does the output not include RANDOM
?
shell environment-variables
I know env
is a shell command, it can be used to print a list of the current environment variables. And as far as I understand, RANDOM
is also
a environment variable.
So why, when I launch env
on Linux, does the output not include RANDOM
?
shell environment-variables
edited Jul 5 at 8:31
terdonâ¦
122k28226398
122k28226398
asked Jul 5 at 8:22
mcmxciv
14416
14416
4
env
is not a shell command since it is usually not built into the shell.
â schily
Jul 5 at 9:24
@schily BTW for Bash,declare -x
is the equivalent in a shell builtin.
â wjandrea
Jul 5 at 17:43
add a comment |Â
4
env
is not a shell command since it is usually not built into the shell.
â schily
Jul 5 at 9:24
@schily BTW for Bash,declare -x
is the equivalent in a shell builtin.
â wjandrea
Jul 5 at 17:43
4
4
env
is not a shell command since it is usually not built into the shell.â schily
Jul 5 at 9:24
env
is not a shell command since it is usually not built into the shell.â schily
Jul 5 at 9:24
@schily BTW for Bash,
declare -x
is the equivalent in a shell builtin.â wjandrea
Jul 5 at 17:43
@schily BTW for Bash,
declare -x
is the equivalent in a shell builtin.â wjandrea
Jul 5 at 17:43
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
42
down vote
accepted
RANDOM
is not an environment variable. It's a shell variable maintained by some shells. It is generally not exported by default. This is why it doesn't show up in the output of env
.
Once it's been used at least once, it would show up in the output of set
, which, by itself, lists the shell variables (and functions) and their values in the current shell session. This behaviour is dependent on the shell and using pdksh
on OpenBSD, RANDOM
would be listed by set
even if not previously used.
The rest of this answer concerns what could be expected to happen if RANDOM
was exported (i.e. turned into an environment variable).
Exporting it with export RANDOM
would make it an environment variable but its use would be severely limited as its value in a child process would be "random but static" (meaning it would be an unchanging random number). The exact behaviour differs between shells.
I'm using pdksh
on OpenBSD in the example below and I get a new random value in each awk
run (but the same value every time within the same awk
instance). Using bash
, I would get exactly the same random value in all invocations of awk
.
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
25444 25444
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
30906 30906
In bash
, the exported value of RANDOM
would remain static regardless of the use of RANDOM
in the shell (where each use of $RANDOM
would still give a new value).
This is because each reference to the shell variable RANDOM
in bash
makes the shell access its internal get_random()
function to give the variable a new random value, but the shell does not update the environment variable RANDOM
. This is similar in behaviour as with other dynamic bash
variables, such as LINENO
, SECONDS
, BASHPID
etc.
To update the environment variable RANDOM
in bash
, you would have to assign it the value of the shell variable RANDOM
and re-export it:
export RANDOM="$RANDOM"
It is unclear to me if this would have the additional side effect of re-seeding the random number generator in bash
or not (but an educated guess would be that it doesn't).
1
DoesRANDOM
even have a value before you use it? I had always assumed it was only populated when called.
â terdonâ¦
Jul 5 at 8:33
1
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
1
Though if you do evenexport RANDOM
ordeclare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...
â ilkkachu
Jul 5 at 8:56
1
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
3
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
 |Â
show 14 more comments
up vote
16
down vote
Not all variables that are set in your shell session are environment variables. "Environment variables" refers only to those variables that have been exported to the environment using the export
builtin. The env
command only prints such environment variables. For example:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
If you want to see all variables set in your session, irrespective of whether they have been exported, you can use set
:
$ set | grep foo=
foo=bar
The set
builtin also returns functions, so to see variables only, you can use:
set | grep '^[^[:space:]]*='
Finally, the RANDOM
variable is special in that it is only assigned a value when you reference it. This is mentioned in bash(1):
RANDOM
Each time this parameter is referenced, a random integer
between 0 and
32767 is generated.ÃÂ The sequence of random numbers may be initialized by
assigning a value toRANDOM
.ÃÂ IfRANDOM
is unset, it loses its special
properties, even if it is subsequently reset.
So even if it were an environment variable as you thought, it wouldn't have been shown in env
since it wouldn't be set until the first time you called it. That is also why it isn't shown in 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
ThatâÂÂs an interesting discovery, regardingsetâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.
â G-Man
Jul 6 at 4:18
1
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
add a comment |Â
up vote
4
down vote
Most shells will have a number of other variables set or used by the shell that aren't exported to child processes by default.
In Bash, there are some obviously Bash-specific ones:
$ 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
Then there's more standard ones like OPTIND
and OPTERR
(used by getopts
), and PS2
, PS3
(the secondary prompts) and even another "magic" variable: SECONDS
(shows the time in seconds since the shell started)
In Bash, you can see all the variables and their export status with declare -p
. The ones marked with -x
are exported, the ones without x
aren't. (Some will have other flags like i
for integer or r
for read-only.)
In Zsh or ksh93, you can use typeset -p
, though Zsh marks the exported variables by changing typeset
to export
in the output, instead of using flags. export
by itself would also show all the exported variables, but that's about the same result you get by running env
.
add a comment |Â
up vote
2
down vote
If you google for this, the docs state the following:
$RANDOM
is an internal Bash function (not a constant) that returns a pseudorandom [1] integer in the range 0 - 32767. It should not be used to generate an encryption key.
If you use strace
you can see that the $RANDOM
"variable" is passed in directly to commands as if it were any ordinary shell variable or an environment variable, but it's just a internal function that's built into the shell, Bash, that's doing the expansion.
$ 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
...
vs. this regular variable:
$ 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
...
The variable is not being passed on as a reference.
References
- $RANDOM: generate random integer
1
well, isn't that passing the expanded value of$RANDOM
or$SOMEVAR
through a command line argument, and not as an environment variable? You'd need toexport
both to pass them through the environment.
â ilkkachu
Jul 5 at 8:48
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
2
Thestrace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of thestrace
. I don't understand what difference you are pointing to. What am I missing?
â terdonâ¦
Jul 5 at 8:55
Showing that the$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses$RANDOM
and passes the expanded form toecho
.
â slmâ¦
Jul 5 at 8:56
2
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
42
down vote
accepted
RANDOM
is not an environment variable. It's a shell variable maintained by some shells. It is generally not exported by default. This is why it doesn't show up in the output of env
.
Once it's been used at least once, it would show up in the output of set
, which, by itself, lists the shell variables (and functions) and their values in the current shell session. This behaviour is dependent on the shell and using pdksh
on OpenBSD, RANDOM
would be listed by set
even if not previously used.
The rest of this answer concerns what could be expected to happen if RANDOM
was exported (i.e. turned into an environment variable).
Exporting it with export RANDOM
would make it an environment variable but its use would be severely limited as its value in a child process would be "random but static" (meaning it would be an unchanging random number). The exact behaviour differs between shells.
I'm using pdksh
on OpenBSD in the example below and I get a new random value in each awk
run (but the same value every time within the same awk
instance). Using bash
, I would get exactly the same random value in all invocations of awk
.
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
25444 25444
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
30906 30906
In bash
, the exported value of RANDOM
would remain static regardless of the use of RANDOM
in the shell (where each use of $RANDOM
would still give a new value).
This is because each reference to the shell variable RANDOM
in bash
makes the shell access its internal get_random()
function to give the variable a new random value, but the shell does not update the environment variable RANDOM
. This is similar in behaviour as with other dynamic bash
variables, such as LINENO
, SECONDS
, BASHPID
etc.
To update the environment variable RANDOM
in bash
, you would have to assign it the value of the shell variable RANDOM
and re-export it:
export RANDOM="$RANDOM"
It is unclear to me if this would have the additional side effect of re-seeding the random number generator in bash
or not (but an educated guess would be that it doesn't).
1
DoesRANDOM
even have a value before you use it? I had always assumed it was only populated when called.
â terdonâ¦
Jul 5 at 8:33
1
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
1
Though if you do evenexport RANDOM
ordeclare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...
â ilkkachu
Jul 5 at 8:56
1
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
3
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
 |Â
show 14 more comments
up vote
42
down vote
accepted
RANDOM
is not an environment variable. It's a shell variable maintained by some shells. It is generally not exported by default. This is why it doesn't show up in the output of env
.
Once it's been used at least once, it would show up in the output of set
, which, by itself, lists the shell variables (and functions) and their values in the current shell session. This behaviour is dependent on the shell and using pdksh
on OpenBSD, RANDOM
would be listed by set
even if not previously used.
The rest of this answer concerns what could be expected to happen if RANDOM
was exported (i.e. turned into an environment variable).
Exporting it with export RANDOM
would make it an environment variable but its use would be severely limited as its value in a child process would be "random but static" (meaning it would be an unchanging random number). The exact behaviour differs between shells.
I'm using pdksh
on OpenBSD in the example below and I get a new random value in each awk
run (but the same value every time within the same awk
instance). Using bash
, I would get exactly the same random value in all invocations of awk
.
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
25444 25444
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
30906 30906
In bash
, the exported value of RANDOM
would remain static regardless of the use of RANDOM
in the shell (where each use of $RANDOM
would still give a new value).
This is because each reference to the shell variable RANDOM
in bash
makes the shell access its internal get_random()
function to give the variable a new random value, but the shell does not update the environment variable RANDOM
. This is similar in behaviour as with other dynamic bash
variables, such as LINENO
, SECONDS
, BASHPID
etc.
To update the environment variable RANDOM
in bash
, you would have to assign it the value of the shell variable RANDOM
and re-export it:
export RANDOM="$RANDOM"
It is unclear to me if this would have the additional side effect of re-seeding the random number generator in bash
or not (but an educated guess would be that it doesn't).
1
DoesRANDOM
even have a value before you use it? I had always assumed it was only populated when called.
â terdonâ¦
Jul 5 at 8:33
1
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
1
Though if you do evenexport RANDOM
ordeclare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...
â ilkkachu
Jul 5 at 8:56
1
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
3
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
 |Â
show 14 more comments
up vote
42
down vote
accepted
up vote
42
down vote
accepted
RANDOM
is not an environment variable. It's a shell variable maintained by some shells. It is generally not exported by default. This is why it doesn't show up in the output of env
.
Once it's been used at least once, it would show up in the output of set
, which, by itself, lists the shell variables (and functions) and their values in the current shell session. This behaviour is dependent on the shell and using pdksh
on OpenBSD, RANDOM
would be listed by set
even if not previously used.
The rest of this answer concerns what could be expected to happen if RANDOM
was exported (i.e. turned into an environment variable).
Exporting it with export RANDOM
would make it an environment variable but its use would be severely limited as its value in a child process would be "random but static" (meaning it would be an unchanging random number). The exact behaviour differs between shells.
I'm using pdksh
on OpenBSD in the example below and I get a new random value in each awk
run (but the same value every time within the same awk
instance). Using bash
, I would get exactly the same random value in all invocations of awk
.
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
25444 25444
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
30906 30906
In bash
, the exported value of RANDOM
would remain static regardless of the use of RANDOM
in the shell (where each use of $RANDOM
would still give a new value).
This is because each reference to the shell variable RANDOM
in bash
makes the shell access its internal get_random()
function to give the variable a new random value, but the shell does not update the environment variable RANDOM
. This is similar in behaviour as with other dynamic bash
variables, such as LINENO
, SECONDS
, BASHPID
etc.
To update the environment variable RANDOM
in bash
, you would have to assign it the value of the shell variable RANDOM
and re-export it:
export RANDOM="$RANDOM"
It is unclear to me if this would have the additional side effect of re-seeding the random number generator in bash
or not (but an educated guess would be that it doesn't).
RANDOM
is not an environment variable. It's a shell variable maintained by some shells. It is generally not exported by default. This is why it doesn't show up in the output of env
.
Once it's been used at least once, it would show up in the output of set
, which, by itself, lists the shell variables (and functions) and their values in the current shell session. This behaviour is dependent on the shell and using pdksh
on OpenBSD, RANDOM
would be listed by set
even if not previously used.
The rest of this answer concerns what could be expected to happen if RANDOM
was exported (i.e. turned into an environment variable).
Exporting it with export RANDOM
would make it an environment variable but its use would be severely limited as its value in a child process would be "random but static" (meaning it would be an unchanging random number). The exact behaviour differs between shells.
I'm using pdksh
on OpenBSD in the example below and I get a new random value in each awk
run (but the same value every time within the same awk
instance). Using bash
, I would get exactly the same random value in all invocations of awk
.
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
25444 25444
$ awk 'BEGIN print ENVIRON["RANDOM"], ENVIRON["RANDOM"] '
30906 30906
In bash
, the exported value of RANDOM
would remain static regardless of the use of RANDOM
in the shell (where each use of $RANDOM
would still give a new value).
This is because each reference to the shell variable RANDOM
in bash
makes the shell access its internal get_random()
function to give the variable a new random value, but the shell does not update the environment variable RANDOM
. This is similar in behaviour as with other dynamic bash
variables, such as LINENO
, SECONDS
, BASHPID
etc.
To update the environment variable RANDOM
in bash
, you would have to assign it the value of the shell variable RANDOM
and re-export it:
export RANDOM="$RANDOM"
It is unclear to me if this would have the additional side effect of re-seeding the random number generator in bash
or not (but an educated guess would be that it doesn't).
edited Jul 5 at 21:35
answered Jul 5 at 8:24
Kusalananda
101k13199312
101k13199312
1
DoesRANDOM
even have a value before you use it? I had always assumed it was only populated when called.
â terdonâ¦
Jul 5 at 8:33
1
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
1
Though if you do evenexport RANDOM
ordeclare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...
â ilkkachu
Jul 5 at 8:56
1
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
3
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
 |Â
show 14 more comments
1
DoesRANDOM
even have a value before you use it? I had always assumed it was only populated when called.
â terdonâ¦
Jul 5 at 8:33
1
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
1
Though if you do evenexport RANDOM
ordeclare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...
â ilkkachu
Jul 5 at 8:56
1
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
3
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
1
1
Does
RANDOM
even have a value before you use it? I had always assumed it was only populated when called.â terdonâ¦
Jul 5 at 8:33
Does
RANDOM
even have a value before you use it? I had always assumed it was only populated when called.â terdonâ¦
Jul 5 at 8:33
1
1
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
It isn't, the bash manual mentions it.
â terdonâ¦
Jul 5 at 8:45
1
1
Though if you do even
export RANDOM
or declare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...â ilkkachu
Jul 5 at 8:56
Though if you do even
export RANDOM
or declare -p RANDOM
, it appears, so I'm not sure if it's any use that it doesn't exist before being referenced...â ilkkachu
Jul 5 at 8:56
1
1
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
"Its value in a child process would be random, but static." If it is static, it is not random, whether it's three bytes or sixteen.
â l0b0
Jul 5 at 20:53
3
3
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
@l0b0 It would be random in the sense that you wouldn't be able to predict it. Obviously, once you've read it, it's not random any longer since it won't change (unless re-exporting as I showed, in which case the environment variable would get a new random value). This is why I said it's random but static. I've clarified this in the text somewhat now.
â Kusalananda
Jul 5 at 21:00
 |Â
show 14 more comments
up vote
16
down vote
Not all variables that are set in your shell session are environment variables. "Environment variables" refers only to those variables that have been exported to the environment using the export
builtin. The env
command only prints such environment variables. For example:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
If you want to see all variables set in your session, irrespective of whether they have been exported, you can use set
:
$ set | grep foo=
foo=bar
The set
builtin also returns functions, so to see variables only, you can use:
set | grep '^[^[:space:]]*='
Finally, the RANDOM
variable is special in that it is only assigned a value when you reference it. This is mentioned in bash(1):
RANDOM
Each time this parameter is referenced, a random integer
between 0 and
32767 is generated.ÃÂ The sequence of random numbers may be initialized by
assigning a value toRANDOM
.ÃÂ IfRANDOM
is unset, it loses its special
properties, even if it is subsequently reset.
So even if it were an environment variable as you thought, it wouldn't have been shown in env
since it wouldn't be set until the first time you called it. That is also why it isn't shown in 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
ThatâÂÂs an interesting discovery, regardingsetâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.
â G-Man
Jul 6 at 4:18
1
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
add a comment |Â
up vote
16
down vote
Not all variables that are set in your shell session are environment variables. "Environment variables" refers only to those variables that have been exported to the environment using the export
builtin. The env
command only prints such environment variables. For example:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
If you want to see all variables set in your session, irrespective of whether they have been exported, you can use set
:
$ set | grep foo=
foo=bar
The set
builtin also returns functions, so to see variables only, you can use:
set | grep '^[^[:space:]]*='
Finally, the RANDOM
variable is special in that it is only assigned a value when you reference it. This is mentioned in bash(1):
RANDOM
Each time this parameter is referenced, a random integer
between 0 and
32767 is generated.ÃÂ The sequence of random numbers may be initialized by
assigning a value toRANDOM
.ÃÂ IfRANDOM
is unset, it loses its special
properties, even if it is subsequently reset.
So even if it were an environment variable as you thought, it wouldn't have been shown in env
since it wouldn't be set until the first time you called it. That is also why it isn't shown in 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
ThatâÂÂs an interesting discovery, regardingsetâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.
â G-Man
Jul 6 at 4:18
1
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
add a comment |Â
up vote
16
down vote
up vote
16
down vote
Not all variables that are set in your shell session are environment variables. "Environment variables" refers only to those variables that have been exported to the environment using the export
builtin. The env
command only prints such environment variables. For example:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
If you want to see all variables set in your session, irrespective of whether they have been exported, you can use set
:
$ set | grep foo=
foo=bar
The set
builtin also returns functions, so to see variables only, you can use:
set | grep '^[^[:space:]]*='
Finally, the RANDOM
variable is special in that it is only assigned a value when you reference it. This is mentioned in bash(1):
RANDOM
Each time this parameter is referenced, a random integer
between 0 and
32767 is generated.ÃÂ The sequence of random numbers may be initialized by
assigning a value toRANDOM
.ÃÂ IfRANDOM
is unset, it loses its special
properties, even if it is subsequently reset.
So even if it were an environment variable as you thought, it wouldn't have been shown in env
since it wouldn't be set until the first time you called it. That is also why it isn't shown in 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
Not all variables that are set in your shell session are environment variables. "Environment variables" refers only to those variables that have been exported to the environment using the export
builtin. The env
command only prints such environment variables. For example:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
If you want to see all variables set in your session, irrespective of whether they have been exported, you can use set
:
$ set | grep foo=
foo=bar
The set
builtin also returns functions, so to see variables only, you can use:
set | grep '^[^[:space:]]*='
Finally, the RANDOM
variable is special in that it is only assigned a value when you reference it. This is mentioned in bash(1):
RANDOM
Each time this parameter is referenced, a random integer
between 0 and
32767 is generated.ÃÂ The sequence of random numbers may be initialized by
assigning a value toRANDOM
.ÃÂ IfRANDOM
is unset, it loses its special
properties, even if it is subsequently reset.
So even if it were an environment variable as you thought, it wouldn't have been shown in env
since it wouldn't be set until the first time you called it. That is also why it isn't shown in 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
edited Jul 6 at 4:17
G-Man
11.4k82656
11.4k82656
answered Jul 5 at 8:44
terdonâ¦
122k28226398
122k28226398
ThatâÂÂs an interesting discovery, regardingsetâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.
â G-Man
Jul 6 at 4:18
1
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
add a comment |Â
ThatâÂÂs an interesting discovery, regardingsetâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.
â G-Man
Jul 6 at 4:18
1
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
ThatâÂÂs an interesting discovery, regarding
setâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.â G-Man
Jul 6 at 4:18
ThatâÂÂs an interesting discovery, regarding
setâ¯|â¯grepâ¯RAN
.â I wouldnâÂÂt have expected it.â FWIW, I believe that it canâÂÂt be predicted by the documentation.â G-Man
Jul 6 at 4:18
1
1
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
P.S. Congratulations on reaching 120,000.âÂÂ(I guess I just put you over.)
â G-Man
Jul 6 at 4:22
add a comment |Â
up vote
4
down vote
Most shells will have a number of other variables set or used by the shell that aren't exported to child processes by default.
In Bash, there are some obviously Bash-specific ones:
$ 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
Then there's more standard ones like OPTIND
and OPTERR
(used by getopts
), and PS2
, PS3
(the secondary prompts) and even another "magic" variable: SECONDS
(shows the time in seconds since the shell started)
In Bash, you can see all the variables and their export status with declare -p
. The ones marked with -x
are exported, the ones without x
aren't. (Some will have other flags like i
for integer or r
for read-only.)
In Zsh or ksh93, you can use typeset -p
, though Zsh marks the exported variables by changing typeset
to export
in the output, instead of using flags. export
by itself would also show all the exported variables, but that's about the same result you get by running env
.
add a comment |Â
up vote
4
down vote
Most shells will have a number of other variables set or used by the shell that aren't exported to child processes by default.
In Bash, there are some obviously Bash-specific ones:
$ 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
Then there's more standard ones like OPTIND
and OPTERR
(used by getopts
), and PS2
, PS3
(the secondary prompts) and even another "magic" variable: SECONDS
(shows the time in seconds since the shell started)
In Bash, you can see all the variables and their export status with declare -p
. The ones marked with -x
are exported, the ones without x
aren't. (Some will have other flags like i
for integer or r
for read-only.)
In Zsh or ksh93, you can use typeset -p
, though Zsh marks the exported variables by changing typeset
to export
in the output, instead of using flags. export
by itself would also show all the exported variables, but that's about the same result you get by running env
.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Most shells will have a number of other variables set or used by the shell that aren't exported to child processes by default.
In Bash, there are some obviously Bash-specific ones:
$ 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
Then there's more standard ones like OPTIND
and OPTERR
(used by getopts
), and PS2
, PS3
(the secondary prompts) and even another "magic" variable: SECONDS
(shows the time in seconds since the shell started)
In Bash, you can see all the variables and their export status with declare -p
. The ones marked with -x
are exported, the ones without x
aren't. (Some will have other flags like i
for integer or r
for read-only.)
In Zsh or ksh93, you can use typeset -p
, though Zsh marks the exported variables by changing typeset
to export
in the output, instead of using flags. export
by itself would also show all the exported variables, but that's about the same result you get by running env
.
Most shells will have a number of other variables set or used by the shell that aren't exported to child processes by default.
In Bash, there are some obviously Bash-specific ones:
$ 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
Then there's more standard ones like OPTIND
and OPTERR
(used by getopts
), and PS2
, PS3
(the secondary prompts) and even another "magic" variable: SECONDS
(shows the time in seconds since the shell started)
In Bash, you can see all the variables and their export status with declare -p
. The ones marked with -x
are exported, the ones without x
aren't. (Some will have other flags like i
for integer or r
for read-only.)
In Zsh or ksh93, you can use typeset -p
, though Zsh marks the exported variables by changing typeset
to export
in the output, instead of using flags. export
by itself would also show all the exported variables, but that's about the same result you get by running env
.
answered Jul 5 at 9:09
ilkkachu
47.3k668130
47.3k668130
add a comment |Â
add a comment |Â
up vote
2
down vote
If you google for this, the docs state the following:
$RANDOM
is an internal Bash function (not a constant) that returns a pseudorandom [1] integer in the range 0 - 32767. It should not be used to generate an encryption key.
If you use strace
you can see that the $RANDOM
"variable" is passed in directly to commands as if it were any ordinary shell variable or an environment variable, but it's just a internal function that's built into the shell, Bash, that's doing the expansion.
$ 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
...
vs. this regular variable:
$ 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
...
The variable is not being passed on as a reference.
References
- $RANDOM: generate random integer
1
well, isn't that passing the expanded value of$RANDOM
or$SOMEVAR
through a command line argument, and not as an environment variable? You'd need toexport
both to pass them through the environment.
â ilkkachu
Jul 5 at 8:48
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
2
Thestrace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of thestrace
. I don't understand what difference you are pointing to. What am I missing?
â terdonâ¦
Jul 5 at 8:55
Showing that the$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses$RANDOM
and passes the expanded form toecho
.
â slmâ¦
Jul 5 at 8:56
2
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
add a comment |Â
up vote
2
down vote
If you google for this, the docs state the following:
$RANDOM
is an internal Bash function (not a constant) that returns a pseudorandom [1] integer in the range 0 - 32767. It should not be used to generate an encryption key.
If you use strace
you can see that the $RANDOM
"variable" is passed in directly to commands as if it were any ordinary shell variable or an environment variable, but it's just a internal function that's built into the shell, Bash, that's doing the expansion.
$ 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
...
vs. this regular variable:
$ 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
...
The variable is not being passed on as a reference.
References
- $RANDOM: generate random integer
1
well, isn't that passing the expanded value of$RANDOM
or$SOMEVAR
through a command line argument, and not as an environment variable? You'd need toexport
both to pass them through the environment.
â ilkkachu
Jul 5 at 8:48
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
2
Thestrace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of thestrace
. I don't understand what difference you are pointing to. What am I missing?
â terdonâ¦
Jul 5 at 8:55
Showing that the$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses$RANDOM
and passes the expanded form toecho
.
â slmâ¦
Jul 5 at 8:56
2
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
add a comment |Â
up vote
2
down vote
up vote
2
down vote
If you google for this, the docs state the following:
$RANDOM
is an internal Bash function (not a constant) that returns a pseudorandom [1] integer in the range 0 - 32767. It should not be used to generate an encryption key.
If you use strace
you can see that the $RANDOM
"variable" is passed in directly to commands as if it were any ordinary shell variable or an environment variable, but it's just a internal function that's built into the shell, Bash, that's doing the expansion.
$ 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
...
vs. this regular variable:
$ 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
...
The variable is not being passed on as a reference.
References
- $RANDOM: generate random integer
If you google for this, the docs state the following:
$RANDOM
is an internal Bash function (not a constant) that returns a pseudorandom [1] integer in the range 0 - 32767. It should not be used to generate an encryption key.
If you use strace
you can see that the $RANDOM
"variable" is passed in directly to commands as if it were any ordinary shell variable or an environment variable, but it's just a internal function that's built into the shell, Bash, that's doing the expansion.
$ 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
...
vs. this regular variable:
$ 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
...
The variable is not being passed on as a reference.
References
- $RANDOM: generate random integer
edited Jul 6 at 3:45
G-Man
11.4k82656
11.4k82656
answered Jul 5 at 8:44
slmâ¦
233k65479651
233k65479651
1
well, isn't that passing the expanded value of$RANDOM
or$SOMEVAR
through a command line argument, and not as an environment variable? You'd need toexport
both to pass them through the environment.
â ilkkachu
Jul 5 at 8:48
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
2
Thestrace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of thestrace
. I don't understand what difference you are pointing to. What am I missing?
â terdonâ¦
Jul 5 at 8:55
Showing that the$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses$RANDOM
and passes the expanded form toecho
.
â slmâ¦
Jul 5 at 8:56
2
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
add a comment |Â
1
well, isn't that passing the expanded value of$RANDOM
or$SOMEVAR
through a command line argument, and not as an environment variable? You'd need toexport
both to pass them through the environment.
â ilkkachu
Jul 5 at 8:48
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
2
Thestrace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of thestrace
. I don't understand what difference you are pointing to. What am I missing?
â terdonâ¦
Jul 5 at 8:55
Showing that the$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses$RANDOM
and passes the expanded form toecho
.
â slmâ¦
Jul 5 at 8:56
2
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
1
1
well, isn't that passing the expanded value of
$RANDOM
or $SOMEVAR
through a command line argument, and not as an environment variable? You'd need to export
both to pass them through the environment.â ilkkachu
Jul 5 at 8:48
well, isn't that passing the expanded value of
$RANDOM
or $SOMEVAR
through a command line argument, and not as an environment variable? You'd need to export
both to pass them through the environment.â ilkkachu
Jul 5 at 8:48
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
No that would make no difference. The shell expands them regardless. The way I showed it is basically highlighting the fact that the shell is doing the expansion.
â slmâ¦
Jul 5 at 8:50
2
2
The
strace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of the strace
. I don't understand what difference you are pointing to. What am I missing?â terdonâ¦
Jul 5 at 8:55
The
strace
output doesn't seem to catch the internal function run by the shell. In both cases, the variable has already been expanded in the first line of the strace
. I don't understand what difference you are pointing to. What am I missing?â terdonâ¦
Jul 5 at 8:55
Showing that the
$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses $RANDOM
and passes the expanded form to echo
.â slmâ¦
Jul 5 at 8:56
Showing that the
$RANDOM
expansion is done internally to the shell. It's basically confirmation that the shell is determining the value, and not passing a reference to a variable. The shell when it's expanding the command line to execute parses $RANDOM
and passes the expanded form to echo
.â slmâ¦
Jul 5 at 8:56
2
2
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
So, nothing like an environment variable, then.
â Toby Speight
Jul 5 at 9:21
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f453547%2fwhy-isnt-random-included-in-the-output-of-env%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
4
env
is not a shell command since it is usually not built into the shell.â schily
Jul 5 at 9:24
@schily BTW for Bash,
declare -x
is the equivalent in a shell builtin.â wjandrea
Jul 5 at 17:43