LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (https://www.linuxquestions.org/questions/slackware-14/)
-   -   How are variables set for interactive shells? (https://www.linuxquestions.org/questions/slackware-14/how-are-variables-set-for-interactive-shells-806052/)

Josh000 05-05-2010 04:50 AM

How are variables set for interactive shells?
 
I am trying to figure out where variables are set for interactive shells?

In particular, I am trying to have LS_OPTIONS inherited by interactive shells as it is by login shells.

I understand LS_OPTIONS is set in /etc/profile, and this may not be processed by interactive shells but by login shells.

However, I also note other variables such as PATH and INPUTRC are set correctly in interactive shells, and these are also set in /etc/profile from what I understand.

So how is it determined which variables are inherited by all shells, and which are just for login shells?

catkin 05-05-2010 05:18 AM

You are right -- /etc/profile is used by login shells but not by non-login shells -- but any environment variables set in /etc/profile (by export varname=value) are inherited by all processes that are descendants of the login shell (including non-shell processes) unless they are explicitly removed, for example by bash' unset command.

Can you give us more detail about LS_OPTIONS? How do you know it is set for login shells? How do you know it is not set for non-login shells? What are the lines that set it in /etc/profile (is it terminal-type dependent)? Is it unset in the non-login bash startup files.

Josh000 05-05-2010 05:26 AM

Well, I am actually using zsh, and I know that I have not set LS_OPTIONS myself at all in any zsh specific files.

Code:

josh@pts/1:~#  zsh -l
josh@pts/1:~#  echo $LS_OPTIONS                                       
-F -b -T 0 --color=auto
josh@pts/1:~#  zsh -i                                                 
josh@pts/1:~#  echo $LS_OPTIONS

josh@pts/1:~#

It is the same for bash.

LS_OPTIONS is set in /etc/profile.d/coreutils-dircolors.sh which is sourced by /etc/profile

I just don't get why it is sourced only for login shells. I can't see anything in /etc/profile that would make this so.

catkin 05-05-2010 05:43 AM

Quote:

Originally Posted by Josh000 (Post 3957890)
I just don't get why it is sourced only for login shells. I can't see anything in /etc/profile that would make this so.

The idea is that the login shell sets up the environment variables and the non-login shells inherit them. Is $LS_OPTIONS an environment variable? env | grep LS_OPTIONS would show.

Josh000 05-05-2010 05:46 AM

Quote:

Originally Posted by catkin (Post 3957905)
The idea is that the login shell sets up the environment variables and the non-login shells inherit them. Is $LS_OPTIONS an environment variable? env | grep LS_OPTIONS would show.

Yes, LS_OPTIONS is an environment variable

Have a look at /etc/profile

Near the end, there is a section that iterates through all the scripts in /etc/profile.d and adds them.

Since the rest of what is set in /etc/profile is set then I don't understand why LS_OPTIONS is not set.

It is even stranger because LS_COLORS is set correctly.

There is nothing that I can see that would unset LS_OPTIONS for interactive shells.

catkin 05-05-2010 06:38 AM

Quote:

Originally Posted by Josh000 (Post 3957907)
There is nothing that I can see that would unset LS_OPTIONS for interactive shells.

Same mechanism on Slackware (but I don't use it). Was not able to reproduce your problem
Code:

c@CW8:/etc/profile.d$ . coreutils-dircolors.sh
c@CW8:/etc/profile.d$ echo $LS_OPTIONS
-F -b -T 0 --color=auto
c@CW8:/etc/profile.d$ bash -i
c@CW8:/etc/profile.d$ echo $LS_OPTIONS
-F -b -T 0 --color=auto

I could not find anything about interactive shells in the GNU Bash Reference that explains the reported behaviour.

According to the same reference on startup files the only action taken while starting an interactive shell is the read ~/.bashrc and you have already written that it contains nothing to explain the behaviour. Just to rule it out, it might be worth trying
Code:

bash -i --norc

Josh000 05-05-2010 06:46 AM

Interesting

When you start a terminal, do you have the terminal start a login shell or an interactive shell?

Although I don't think even that would make a difference. Here if I use "xterm -ls" LS_OPTIONS is set correctly, although if I start an interactive shell from that instance it is not.

It seems quite odd...

catkin 05-05-2010 06:55 AM

Quote:

Originally Posted by Josh000 (Post 3957957)
When you start a terminal, do you have the terminal start a login shell or an interactive shell?

Although I don't think even that would make a difference. Here if I use "xterm -ls" LS_OPTIONS is set correctly, although if I start an interactive shell from that instance it is not.

Desktop lanucher command is /usr/bin/mrxvt -name c -ic /usr/share/pixmaps/mrxvt.xpm which doesn't help you much! The mrxvt configuration dictates what to do for user "c".

For simplicity, I opened a virtual terminal (Ctrl+Alt+F2) and necessarily logged on then did exactly as in the last post with exactly the same results.

GazL 05-05-2010 06:57 AM

profile.d/coreutils-dircolors.sh is broken in slackware. I changed it to fix the syntax errors it generates in ash, but it'll also resolve your issue.

The problem is that as written LS_OPTIONS is set as an Array when used with zsh and you can't export an array.

Replace it with the script in the attachment and you'll be fine.


I sent this fix along with a couple of other shell related ones to Pat a month or so back.


edit: This has been adopted by Pat in official Slackware now, so I'm removing the attachment to save space.

catkin 05-05-2010 07:02 AM

Quote:

Originally Posted by GazL (Post 3957967)
profile.d/coreutils-dircolors.sh is broken in slackware. I changed it to fix the syntax errors it generates in ash, but it'll also resolve your issue.

The problem is that as written LS_OPTIONS is set as an Array when used with zsh and you can't export an array.

Thanks GazL :) -- I was getting confuzzled by this one; Josh000 can you re-test "It is the same for bash"?

GazL 05-05-2010 09:20 AM

Quote:

Originally Posted by catkin (Post 3957970)
Thanks GazL :) -- I was getting confuzzled by this one; Josh000 can you re-test "It is the same for bash"?

No problem. It's a sneaky one isn't it. :)

While we're on the subject of running shells with the '-l' option to simulate a login shell, you need to be wary, because if you run a shell of a different type to that of your default login shell then the. $SHELL can't be relied on to contain the correct value. Subsequently, the wrong parts of /etc/profile or one of its sub-scripts can easily be run.

I came up with the following alteration for /etc/profile to work around that issue:
Code:

case $0 in
  -* )  # If $0 starts with a '-' then we're being run by a real login shell
        # started by 'login', 'su', 'ssh', 'telnet' and the like.
        # We can trust the value of $SHELL
        case $SHELL in
          /bin/bash )  PS1='\u@\h:\w\$ '
                      ;;
          /bin/ksh )  PS1='! ${PWD/#$HOME/~}$ '
                      VISUAL=vi
                      ;;
          /bin/zsh )  PS1='%n@%m:%~%# '
                      ;;
          * )          PS1='$ ' 
                      ;;
        esac
        ;;
  * )  # Otherwise, we've probably been invoked from a shell that
        # has a command line switch which simulates a login shell: such as
        # 'bash -l' or 'dash -l'.  In which case, $SHELL cannot be
        # relied upon and we have to use alternative means where available.
        test -n "$BASH_VERSION" && PS1='\u@\h:\w\$ ' || \
        PS1='$ '
        ;;
esac

You'll notice my "fixed" version of coreutils-dircolor.sh still checks against $SHELL as I hadn't gotten around to fixing this second issue in that yet, but it's not going to be any worse than the original in that respect.

I think the moral of the story is don't use '-l 'unless you really need to. :)

catkin 05-05-2010 09:38 AM

Quote:

Originally Posted by GazL (Post 3958095)
No problem. It's a sneaky one isn't it. :)

While we're on the subject of running shells with the '-l' option to simulate a login shell, you need to be wary, because if you run a shell of a different type to that of your default login shell then the. $SHELL can't be relied on to contain the correct value.
[snip]
I think the moral of the story is don't use '-l 'unless you really need to. :)

Thanks for the heads up. From the bash man page
Code:

      SHELL  The full pathname to the shell is kept in this environment variable.  If it is not set when the shell starts, bash assigns  to
              it the full pathname of the current user's login shell.

I only have bash and ash so can't explore much. Presumably "the current user's login shell" is the one in /etc/passwd. Here's exploring at the command line with bash
Code:

c@CW8:~$ export SHELL=foo
c@CW8:~$ bash -l
localhost being added to access control list
c@CW8:~$ echo $SHELL
foo

I was vaguely aware that $SHELL is not robust. Is there no way to ask the current shell "what are you?"?

GazL 05-05-2010 09:57 AM

bash sets it if it's unset, but unless you manually unset it before running bash, that's not likely to be the case.

zsh doesn't set it whether it's unset or not, so for most cases it's just going to contain the value that you inherited from the parent's environment.

In the example I posted above, you'll see that I check for $BASH_VERSION as a way to identify it's being run by bash. zsh has a $ZSH_VERSION that you can use to the same ends, but not all shells have anything like that that gives the game away.

Josh000 05-05-2010 02:05 PM

Quote:

Originally Posted by GazL (Post 3957967)
profile.d/coreutils-dircolors.sh is broken in slackware. I changed it to fix the syntax errors it generates in ash, but it'll also resolve your issue.

The problem is that as written LS_OPTIONS is set as an Array when used with zsh and you can't export an array.

Replace it with the script in the attachment and you'll be fine.


I sent this fix along with a couple of other shell related ones to Pat a month or so back.

Hi Gazl,

I'm about to try your fix now.

I just have a question though, because my problem does not seem zsh specific.

For my user account zsh is the default shell, while bash is the default shell for root.

Logged in as my user, if I start a login shell with either xterm -ls, or zsh -l from within then $LS_OPTIONS is set correctly.

In an interactive shell, LS_OPTIONS is just blank.

It's the same as root..., if I use su -, then LS_OPTIONS is set correctly.

If I use bash in interactive mode, then it is the same as with zsh in interactive mode under a user account, LS_OPTIONS is just blank.

However, if I start a bash interactive shell from with zsh as a user, then LS_OPTIONS is set to just "-F". That seems like an array issue certainly,

But with zsh and bash behaving the same way is it really an issue specific to zsh?

Josh000 05-05-2010 02:17 PM

OK, I just tried with the new coreutils-dircolors.sh

This is the result

Code:

%n@%m:%~%# bash --login
%n@%m:%~%# ls
bash: ${=LS_OPTIONS}: bad substitution
%n@%m:%~%# echo $LS_OPTIONS
-F -b -T 0 --color=auto
%n@%m:%~%# bash
%n@%m:%~%# ls
-files are listed without color
%n@%m:%~%# echo $LS_OPTIONS
-F -b -T 0 --color=auto
%n@%m:%~%# zsh -l
josh@pts/0:~#  echo $LS_OPTIONS                                                           
-F -b -T 0 --color=auto
josh@pts/0:~#  ls                                                                       
-files are listed with color
josh@pts/0:~#  zsh -i     
josh@pts/0:~# ls
-files are listed without color                                                               
josh@pts/0:~#  echo $LS_OPTIONS
-F -b -T 0 --color=auto
josh@pts/0:~#

So at the moment, it does not work with a bash login shell, and while both interactive shells have LS_OPTIONS set correctly, neither of them output color by default when running ls


All times are GMT -5. The time now is 07:34 PM.