Crontab is not using PATH written in /etc/environment - cron

I am loading environment variables to crontab by writting those variables in /etc/environment. One of the variables I need to use is PATH. Although I am writting the PATH to the /etc/enviroment I see that cron uses another value of PATH still.
My /etc/environemnt:
# cat /etc/environment
...
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
...
The output of cron when it logs the output of env
...
PATH=/usr/bin:/bin
...
I managed to solve the issue by hardcoding the desired PATH to the cron job file, however I would prefer writing the PATH dynamically based on the actual PATH

Related

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

Default values of PATH variable

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.

Source to global env

I have some script, that I need to source. I want to source it from another script to global environment. Abstract example:
Script 1:
#/script1
PATH="$PATH:/something"
Script 2:
#/script2
source /script1
Than I run bash /script2 and I'm expecting to see updated PATH in global env. But it doesn't
More real example:
#/somedir/script1
A=$(./someanotherscript)
#/script2
cd /somedir
source script1
So, how can I do this thing?
After running bash script2, you won't see the change to PATH that script1 made. That change was local to the environment of the process running script2. If you want to change PATH in the current environment, from which you run script2, you need to source it as well.
$ source script2
$ echo $PATH
I believe you are not exporting the variable, see the following:
# script1.sh
PATH="/new:$PATH"
env
In this case, env, even in this script won't have access to the new path, because you need to do this:
# script1.sh
export PATH="/new:$PATH"
env

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