Why isn't $RANDOM included in the output of 'env'?

The name of the pictureThe name of the pictureThe name of the pictureClash 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?







share|improve this question

















  • 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















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?







share|improve this question

















  • 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













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?







share|improve this question













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?









share|improve this question












share|improve this question




share|improve this question








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













  • 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











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).






share|improve this answer



















  • 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






  • 1




    It isn't, the bash manual mentions it.
    – terdon♦
    Jul 5 at 8:45






  • 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






  • 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


















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 to RANDOM.  If RANDOM 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





share|improve this answer























  • 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




    P.S. Congratulations on reaching 120,000. (I guess I just put you over.)
    – G-Man
    Jul 6 at 4:22

















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.






share|improve this answer




























    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





    share|improve this answer



















    • 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










    • 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




      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







    • 2




      So, nothing like an environment variable, then.
      – Toby Speight
      Jul 5 at 9:21










    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    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






























    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).






    share|improve this answer



















    • 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






    • 1




      It isn't, the bash manual mentions it.
      – terdon♦
      Jul 5 at 8:45






    • 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






    • 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















    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).






    share|improve this answer



















    • 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






    • 1




      It isn't, the bash manual mentions it.
      – terdon♦
      Jul 5 at 8:45






    • 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






    • 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













    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).






    share|improve this answer















    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).







    share|improve this answer















    share|improve this answer



    share|improve this answer








    edited Jul 5 at 21:35


























    answered Jul 5 at 8:24









    Kusalananda

    101k13199312




    101k13199312







    • 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






    • 1




      It isn't, the bash manual mentions it.
      – terdon♦
      Jul 5 at 8:45






    • 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






    • 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




      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




      It isn't, the bash manual mentions it.
      – terdon♦
      Jul 5 at 8:45






    • 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






    • 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













    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 to RANDOM.  If RANDOM 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





    share|improve this answer























    • 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




      P.S. Congratulations on reaching 120,000. (I guess I just put you over.)
      – G-Man
      Jul 6 at 4:22














    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 to RANDOM.  If RANDOM 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





    share|improve this answer























    • 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




      P.S. Congratulations on reaching 120,000. (I guess I just put you over.)
      – G-Man
      Jul 6 at 4:22












    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 to RANDOM.  If RANDOM 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





    share|improve this answer















    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 to RANDOM.  If RANDOM 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






    share|improve this answer















    share|improve this answer



    share|improve this answer








    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, 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




      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






    • 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










    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.






    share|improve this answer

























      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.






      share|improve this answer























        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.






        share|improve this answer













        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.







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jul 5 at 9:09









        ilkkachu

        47.3k668130




        47.3k668130




















            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





            share|improve this answer



















            • 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










            • 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




              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







            • 2




              So, nothing like an environment variable, then.
              – Toby Speight
              Jul 5 at 9:21














            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





            share|improve this answer



















            • 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










            • 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




              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







            • 2




              So, nothing like an environment variable, then.
              – Toby Speight
              Jul 5 at 9:21












            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





            share|improve this answer















            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






            share|improve this answer















            share|improve this answer



            share|improve this answer








            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 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







            • 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










            • 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




              So, nothing like an environment variable, then.
              – Toby Speight
              Jul 5 at 9:21












            • 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










            • 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




              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







            • 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












             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            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













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay