6

I have set some environment variables in the following way:

MY_VAR='helloworld'
export MY_VAR

Then I have switched to another user via

su SOME_OTHER_USER

I echo the MY_VAR variable.. and I see its value!

1) Could you please explain this issue. As far as I understand when I export variable via export command it is not a "global" export, its just a user-local variable. Why I see it?

2) Initially I had a guess: may be, when I switch to another user I start some child process of my bash process, and thats why I can see my variable because the exported vars are passed to any child process of current shell. But command ps ---pid <my bash's pid which I got with echo $$> shows only the same pid in output. So looks like this means there are no child processes related to my bash process and su is not starting any process. Am I right? (by the way, I dont see a single 'child' this way, even if I start another bash with bash command, I dont know why)

3) Finally, who can see the variable I have exported that way? Given I start some other process from my OS GUI - am I about to see it? Looks like no, because if I start another terminal I dont see it there. So what is the scope and lifetime of my exported variable?

I use Debian Wheezy. I was running my command from RootTerminal under Root user.

2 Answers 2

4
  • OK, for starters, I think you mean ps --pid and not ps ---pid.
  • You don't need to echo $$ and then type the number into ps --pid number; it's good enough to type ps --pid $$.  Unless you're talking about

    # echo $$
    42
    # su joe
    % ps --pid 42
    

    in which case you're doing the right thing.

  • What were you expecting?

    --pid pidlist

      Select by process ID.  Identical to -p and p.


    -p pidlist

      Select by PID.  This selects the processes whose process ID numbers appear in pidlist.  Identical to p and --pid.

    So, when you do ps --pid PID_of_shell, you're getting the line of ps's output for the shell process only.  You might find ps -l | grep PID_of_shell more useful; it will show any line that contains PID_of_shell anywhere, including in the PPID column.  I.e., it will show child processes of the shell.  But, of course, grep 42 will find things like 7428.

  • Your guess is right; environment variables are passed from parent to child.  As indicated above, your su shell is a child of your login shell (or other parent shell).  Note, however, that a process can change its environment; sudo is somewhat notorious for doing this, and su does it too (e.g., it changes $USER, $LOGNAME, and $HOME unless you specify --preserve-environment, and even more if you do specify --login).  Also, a process can pass its children a different environment than the one it is using; the shell does that when you say something like PAGER=cat man man_page_topic.  References: 1, 2.
  • So, no, if you set (export) an environment variable in the shell in one terminal, and then start another terminal through the window manager, it will not see the environment variable, because it is not a child (or descendent) of the shell that set it.  But, if you start a new terminal window from the shell (e.g., by xterm&), then that terminal window will inherit the shell's environment.
3
  • Thanks for a great answer, Scott! Still cannot get one thing: given I issue ps -l and I see: 0 S 0 26083 4862 0 80 0 - 4918 - pts/3 00:00:00 bash; then I go su SOME_USER and see 4 S 116 26780 26772 0 80 0 - 4850 - pts/3 00:00:00 bash. There are no 26083 PID of my main bash process! So how can I 'prove' that su creates a sub-process?
    – MiamiBeach
    Commented Mar 22, 2015 at 21:19
  • Got it: I just need ps -Al | grep 26083
    – MiamiBeach
    Commented Mar 22, 2015 at 21:21
  • Here's an exercise: type ps -lp $$. Note the number in the PPID column. Then do ps -lp (that number). Repeat. Commented Mar 22, 2015 at 21:31
0

It might be easier to understand if you were accessing the machine with ssh, rlogin, or telnet, even as the same user. (rlogin/telent are not recommended)

If you set and export a variable from tty1 as user foo, any child process can see the variable and its value. But if you start a whole new session, ie. from tty2, as user foo, the variable will not be visible.

1) When you export a variable, you make it global (in session context). As a side note, I strongly discourage the use of working in a "root" shell. Mistakes and accidents are far less forgiving when executed by this user/account.

2) The su command is a set (or switch) user utility. You are still in your original session. This is why you can still see your exported variable.

3) The scope is the current session and the lifetime is the duration of that session (until you logout, assuming you do not reset or change the variable again). If you spawn new xterms from the parent session, the children still see your exported variable. If you start new sessions/terminals, variables and their values from the other tty(s) are not visible.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .