Default values of PATH variable - linux

After searching all over the internet, I came know where to alter the values of PATH variable in case of interactive/non-interactive - login/non-login shell combinations.
Found from another post
https://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/
I have "/bin/sh" as default login shell and only /etc/profile file is being used to export all needed environment variables in my system. And in case of non-interactive login shell, /etc/profile is not being referred too, even though above link says it would. But still when I execute,
ssh -4 -q -o StrictHostKeyChecking=no root#xxxx "env"
Password:
SHELL=/bin/sh
...
**PATH=/usr/bin:/bin:/usr/sbin:/sbin**
...
I could see some default values for PATH variable. I would like to know where exactly these default values of PATH are being set.

You should not care at all where PATH is set. You should set PATH always in your shell startup file (.profile or .bashrc).
This way you do not rely on someone else's soon useless assumption what directories should be in your PATH. The only one who knows is YOU.
Start out with
PATH=$(getconf PATH)
and then add to your liking with
PATH=$PATH:$HOME/bin
PATH=$PATH:/usr/local/bin
PATH=$PATH:<...any other directory you need...>
PS: In your specific case, it looks like the PATH is inherited from the remote end's SSH daemon which eventually forks your shell. If a shell does not inherit a PATH from its parent, it will set a default value that you can query with env -i /bin/sh -c 'echo $PATH'.

It depends on your distribution. In Debian and its derivatives, the definition is found in /etc/environment and it is read into the current session by inclusion of pam_env.so in the appropriate /etc/pam.d/ files.

Related

Can't find who sets http_proxy environment variable on Ubuntu

I'm on Ubuntu 16.10,
When running in terminal:
env | grep proxy
I get:
https_proxy=https://127.0.0.1:8888/
http_proxy=http://127.0.0.1:8888/
I can't find who sets these environment variables.
I've tried all the answers here and could not find anything.
Tried different shells / terminals. Variables are always there.
Any idea what else can it be?
No luck in checking all the usual suspects? Then it's time to use the big gun:
find /etc $HOME /usr/local -type f | xargs grep -E 'https?_proxy'
Run this as root. Add directories to your liking.
An environment variable in your current shell can only be set in the parent process, or in a file sourced by your shell. I would start by turning on the shell trace in the respective rc-files which are sourced when you log in, in your home directory. This is also the place where I would verify whether the environment variables is already set at this point (which would mean that it was set by the global initialization process, for instance in the rc files which reside in /etc). Now log in and check the output.
If the environment variable is already set initially, you can't do much except bugging your admin that he should remove it (which probably won't work). If it is not set initially, you need to look through the output of the shell trace, until you either find the point, where the variable is set, or where you see that some malicious script turns off the trace.
Since you didn't give any information, which shell you are using, I can't go into deeper detail.
In my case those env variables were set by Fiddler web debugger and I was able to remove them manually by editing ~/.bashrc file. There are 2 lines with export http(s)_proxy... located at the end of this file. Hope that it helps!

Import PATH environment variable into Bash script launched with cron

When creating Bash scripts, I have always had a line right at the start defining the PATH environment variable. I recently discovered that this doesn't make the script very portable as the PATH variable is different for different versions of Linux (in my case, I moved the script from Arch Linux to Ubuntu and received errors as various executables weren't in the same places).
Is it possible to copy the PATH environment variable defined by the login shell into the current Bash script?
EDIT:
I see that my question has caused some confusion resulting in some thinking that I want to change the PATH environment variable of the login shell with a bash script, which is the exact opposite of what I want.
This is what I currently have at the top of one of my Bash scripts:
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
# Test if an internet connection is present
wget -O /dev/null google.com
I want to replace that second line with something that copies the value of PATH from the login shell into the script environment:
#!/bin/bash
PATH=$(command that copies value of PATH from login shell)
# Test if an internet connection is present
wget -O /dev/null google.com
EDIT 2: Sorry for the big omission on my part. I forgot to mention that the scripts in question are being run on a schedule through cron. Cron creates it's own environment for running the scripts which does not use the environment variables of the login shell or modify them. I just tried running the following script in cron:
#!/bin/bash
echo $PATH >> /home/user/output.txt
The result is as follows. As you can see, the PATH variable used by cron is different to the login shell:
user#ubuntu_router:~$ cat output.txt
/usr/bin:/bin
user#ubuntu_router:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Don't touch the user's PATH at all unless you have a specific reason. Not doing anything will (basically) accomplish what you ask.
You don't have to do anything to get the user's normal PATH since every process inherits the PATH and all other environment variables automatically.
If you need to add something nonstandard to the PATH, the usual approach is to prepend (or append) the new directory to the user's existing PATH, like so:
PATH=/opt/your/random/dir:$PATH
The environment of cron jobs is pretty close to the system's "default" (for some definition of "default") though interactive shells may generally run with a less constrained environment. But again, the fix for that is to add any missing directories to the current value at the beginning of the script. Adding directories which don't exist on this particular system is harmless, as is introducing duplicate directories.
I've managed to find the answer to my question:
PATH=$PATH:$(sed -n '/PATH=/s/^.*=// ; s/\"//gp' '/etc/environment')
This command will grab the value assigned to PATH by Linux from the environment file and append it to the PATH used by Cron.
I used the following resources to help find the answer:
How to grep for contents after pattern?
https://help.ubuntu.com/community/EnvironmentVariables#System-wide_environment_variables

Understanding LFS environment setup

I have some questions regarding the suggested setup from LFS.
Question:
what is this command really doing
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
it mentions that the "new instance of the shell is a non-login shell" so we have to setup .bashrc ....however it doesn't really explains how we use this bashrc once created. It goes back to bash_profile at the end.
Most of it is well explained, but perhaps it is more technical for this section than what I expected and it also involves some important concepts I would like to understand in greater detail. I have marked in bold some commands I am unable to understand what they are doing.
From: http://www.linuxfromscratch.org/lfs/view/stable/chapter04/settingenvironment.html
Set up a good working environment by creating two new startup files for the bash shell. While logged in as user lfs, issue the following command to create a new .bash_profile:
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
When logged on as user lfs, the initial shell is usually a login shell which reads the /etc/profile of the host and then .bash_profile. The exec env -i.../bin/bash command in the .bash_profile file replaces the running shell with a new one with a completely empty environment, except for the HOME, TERM, and PS1 variables. This ensures that no unwanted and potentially hazardous environment variables from the host system leak into the build environment.
The new instance of the shell is a non-login shell, which does not read the /etc/profile or .bash_profile files, but rather reads the .bashrc file instead. Create the .bashrc file now:
cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL LFS_TGT PATH
EOF
The set +h command turns off bash's hash function. Hashing is ordinarily a useful feature—bash uses a hash table to remember the full path of executable files to avoid searching the PATH time and again to find the same executable. However, the new tools should be used as soon as they are installed. By switching off the hash function, the shell will always search the PATH when a program is to be run. As such, the shell will find the newly compiled tools in $LFS/tools as soon as they are available without remembering a previous version of the same program in a different location.
Setting the user file-creation mask (umask) to 022 ensures that newly created files and directories are only writable by their owner, but are readable and executable by anyone (assuming default modes are used by the open(2) system call, new files will end up with permission mode 644 and directories with mode 755).
The LFS variable should be set to the chosen mount point.
The LC_ALL variable controls the localization of certain programs, making their messages follow the conventions of a specified country. If the host system uses a version of Glibc older than 2.2.4, having LC_ALL set to something other than “POSIX” or “C” (during this chapter) may cause issues if you exit the chroot environment and wish to return later. Setting LC_ALL to “POSIX” or “C” (the two are equivalent) ensures that everything will work as expected in the chroot environment.
The LFS_TGT variable sets a non-default, but compatible machine description for use when building our cross compiler and linker and when cross compiling our temporary toolchain. More information is contained in Section 5.2, “Toolchain Technical Notes”.
Finally, to have the environment fully prepared for building the temporary tools, source the just-created user profile:
source ~/.bash_profile
See Bash Startup Files
cat > ~/.bash_profile << "EOF" exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash EOF
In that, env summons a new interactive non-login bash (/bin/bash) instance with environmental variables ignored (-i) besides those set explicitly. Non-login bash instances don't read .bash_profile, .bash_login and .profile, but read .bashrc. Login instances however read those files but not .bashrc. Since env doesn't pass -l to /bin/bash, bash would not run as a login shell.
And exec overwrites the current shell process with env. env on the other hand exec's bash so it's like over-all the old shell is transformed to a new bash but the process ID would still be the same.

Linux environment variable set but not used

I have added a new environment variable in /etc/environment, which now looks like this
$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64
MYVAR_HOME=/include/var
This variable does not appear when listing all env variables with env. Nor it is printed when I 'echo' it
$ echo $MYVAR_HOME
$
did I miss some steps in adding it?
As far as I remember /etc/environment is not a file which is loaded upon shell initialization. Usually a POSIX compatible shell upon startup with login loads its own configuration file usually named /etc/<shell-name>rc (I.e. /etc/bashrc, /etc/zshrc and so on), profile settings (/etc/profile) and corresponding files from user's home directory.
Loading /etc/profile may cause loading other files such as files from /etc/profile.d/ but all these additional files are explicitly loaded from main profile, look for lines containing source smth or single dot: . /etc/somefile. You may check if /etc/environment is mentioned in /etc/profile of your distro.
Also you may try to run bash --login -x and see what commands are being executed.

When I execute bash, the $PATH keeps repeating itself

I have added entries such as the following in my /etc/bashrc (on Fedora).
#=========== Maven Related variables
export JAVA_HOME='/usr/java/default'
export PATH=${JAVA_HOME}:$PATH
#=========== Maven Related variables
export M2_HOME=/usr/local/apache-maven/apache-maven-3.0.4
export PATH=${M2_HOME}/bin:$PATH
#=========== Ant Related variables
export ANT_HOME=/usr/local/apache-ant
export Path=${ANT_HOME}/bin:$PATH
Now, each time that I execute bash command to refresh the environment variables, all these additions are repeated, and the PATH just keep adding itself recursively; if I keep doing bash for a few dozen times, then the $PATH becomes a hundred lines of repeating content. What am I doing wrong?
Note that I have added these entries to /etc/bashrc since I want to have these values in PATH no matter what user I login as.
Thanks,
Shannon
Don't set your PATH incrementally in .bashrc; set it once in .profile and leave it alone thereafter. Or, since you mention /etc/bashrc, don't set the PATH incrementally in /etc/bashrc; set it once in /etc/profile and leave it alone.
One side-benefit; things will work a little faster.
See also the code in How do I manipulate PATH elements in shell scripts for code to clean up a repetitive PATH.
If by this statement:
... execute bash command to refresh the environment variables ...
you mean that you are entering the command
bash
at the command prompt, you are not "refreshing the environment variables". You are launching a new subshell of the current shell. The new shell inherits the path of the original shell, to which you are once again making additions. Each time you do this the PATH will get longer.
You can use something like:
PATH=$(echo "$PATH" | awk -v RS=: -v ORS=: '!(a[$0]++)' | sed 's/:$//')
to clean up your path after changing it. Also, since the the first match is used when scanning the path, having duplicates doesn't really matter.
I had also faced the same problem (CentOS). This is how I fixed it.
Added the following lines to my user's .profile
export PATH=/usr/local/apache-maven-3.3.3/bin:$PATH
export JAVA_HOME=/usr
export SHELL=/bin/bash
# to run bash (because ksh was my default shell)
/bin/bash
No changes to my user's .bashrc file
No changes to /etc/profile
No changes to /etc/bashrc

Resources