LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux From Scratch (https://www.linuxquestions.org/questions/linux-from-scratch-13/)
-   -   Where should I initialize $BASH_ENV and $ENV? (https://www.linuxquestions.org/questions/linux-from-scratch-13/where-should-i-initialize-%24bash_env-and-%24env-852524/)

Sam Hawkens 12-26-2010 10:02 PM

Where should I initialize $BASH_ENV and $ENV?
 
Greetings dear community,

lately I finished my first LFS (6.6) installation and as I came along the topic 'Bash Startup Files' I stumbled into the $BASH_ENV and $ENV enviroment variables. Well, in the invocation section of the Bash manual pages it is written, that if Bash is invoked non-interactive, it would attempt to read $BASH_ENV (or $ENV if invoked as sh). After noticing these variables are empty in my environment I asked myself the same question as in the title.

1. Where should I initialize $BASH_ENV and $ENV?

or

2. Should I initialize these variables at all?
3. If used, what is the default value of these variables?

After some research I found the /etc/enviroment file interesting but I am not sure if I should put them there, since always when I am reading something like 'global' or 'for all processes accessible' my stomach starts aching. Maybe I am paranoid, but statements of some experts like you ;) would really ease my mind.

Thanks in advance

Sam

PS: Hope my English is understandable. :)

crts 12-27-2010 01:04 AM

Hi,

I'm afraid there is no easy answer to your question. As you already read in the manpage the BASH_ENV variable simply holds the location of a script that will be sourced when bash is executed as a non-interactive shell. This is one way to include some general functionality in all your scripts which are run in a non-interactive shell. So you will have to decide if you need the variable. Here is a very simple example how to utilize BASH_ENV:
Create the following text file and save it in /etc/global
Code:

echo "'sayItAsItIs' function available!"
sayItAsItIs ()
{
        echo "I'm just saying: $@"
}

Notice that there is no shebang! If you set your BASH_ENV like
Code:

BASH_ENV=/etc/global
Then all your scripts will be able to call the function 'sayItAsItIs', e.g.
Code:

$ /bin/bash -c  'sayItAsItIs This script has no purpose!'
This will output
Code:

'sayItAsItIs' function available!
I'm just saying: This script has no purpose!

Real scripts will also be able to call 'sayItAsItIs':
Code:

$ cat script.bash
#!/bin/bash

sayItAsItIs No purpose
$ ./script.bash
'sayItAsItIs' function available!
I'm just saying: No purpose
$

So BASH_ENV holds the location of a "substitute" for .bashrc if the shell is non-interactive. The variable ENV comes into the picture when you call bash as 'sh'. Read the according section of the manpage again for more details.

I hope this very simple example makes it a bit clearer on how to use these variables. As for your questions:
Quote:

1. Where should I initialize $BASH_ENV and $ENV?
It depends. If you want all your users to have implicit functionality available in their scripts then declare them somewhere global, as in /etc/environment or /etc/bash.bashrc. Do not forget to make sure that the script that is to be sourced is also in a place which is accessible by every user.
If you want different implicit functionality for every user then declare them in their personal ~/.bashrc files. Put the script that is to be sourced in their home directories.
Quote:

2. Should I initialize these variables at all?
Same answer as for Q1. I personally have never used them. While this concept seems to implement some convenience there might be also side effects, e.g. what happens if you redefine a variable that has been previously sourced into your script? This is a potential source of trouble.
Quote:

3. If used, what is the default value of these variables?
I am not sure if there is any convention on how to name the script that is to be sourced. Since I haven't found anything in the manpage my guess is that there is no default value; I might be wrong though.


It is probably best to play with those two variables a bit to familiarize yourself with the concept. That's what LFS is there for. E.g., try the following variations of the above command:
Code:

$ /bin/bash -c -i  'sayItAsItIs This script has no purpose!'
# OR
$ /bin/sh -c 'sayItAsItIs This script has no purpose!'

Try to understand why those variations yield a different result.

Hope this helps.


PS:
Quote:

PS: Hope my English is understandable.
It is. :)

Sam Hawkens 12-29-2010 07:13 PM

Good day,

sorry for my late answer but now, including the examples above, here are my case studies. I wrote an extra script, which determines if a login/interactive bash was started. It is just considering $BASH_ENV since I am interested in non-interactive bash shell behaviour.

test.sh:
Code:

#!/bin/bash

sayItAsItIs 'I am ONLY working in non-interactive shells!'
echo

if [ "$(shopt login_shell | sed -e 's@\t@ @g' | tr -s ' ' | cut -d ' ' -f 2)" = "on"  ] ; then
        echo "Login"
else
        echo "NoLogin"
fi

case "$-" in
        *i*) echo "Interactive" ;;
        *) echo "NoInteractive" ;;
esac

Results for the different cases:
Code:

$ bash --login -ci '. test.sh'
bash: sayItAsItIs: Command not found.

Login
Interactive
$ bash --login -c '. test.sh'
'sayItAsItIs' function available!
I'm just saying: I am ONLY working in non-interactive shells!

Login
NoInteractive
$ bash -ci '. test.sh'
bash: sayItAsItIs: Command not found.

NoLogin
Interactive
$ bash -c '. test.sh'
'sayItAsItIs' function available!
I'm just saying: I am ONLY working in non-interactive shells!

NoLogin
NoInteractive


crts 12-29-2010 07:49 PM

Quote:

Originally Posted by Sam Hawkens (Post 4207161)
It is just considering $BASH_ENV since $ENV shows the same behaviour as $BASH_ENV (just for sh invocation).

sh treats ENV in an opposite manner than bash treats BASH_ENV. While BASH_ENV gets evaluated when the shell is non-interactive, ENV is evaluated by sh only when the shell is interactive. Set ENV also to global, just like BASH_ENV. Do not forget to export it. Now issue
Code:

sh -c 'echo Hello'
bash -c 'echo Hello'

Both are non-interactive shells. Now make them both interactive
Code:

sh -c -i 'echo Hello'
bash -c -i 'echo Hello'

Hope this clears things up a bit.

Just out of curiosity, have you decided whether to use BASH_ENV or not? If yes, what script are you planning to source?

Sam Hawkens 12-29-2010 08:21 PM

I wanted to know the behaviour of these variables since the manual page wasn't that clear to me and I hadn't found anything useful. After searching I just got results including the same phrase about these variables as in the bash manual page (in the invocation section) or about the command 'env'.

I read that non-interactive shells use another environment than interactive shells and I want both variations to run the same enviroment. I know not the whole enviroment is another but for example $PS1 is unset in non-interactive mode. I am not sure about this topic and maybe I will write another thread if I won't find anything useful.

Sam Hawkens 01-01-2011 10:32 PM

Since there is no reply, I guess this topic is a closed one.


All times are GMT -5. The time now is 12:03 PM.