PATH suddenly changed

Out of nothing I noticed I could not run some commands anymore, like ‘runuser’ and ‘rfkill’.

When I looked in /etc/profile I saw these lines:

if [ “id -u” -eq 0 ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi

It seems like the second option is missing /usr/sbin and ‘runuser’ is located there.

When I added /usr/sbin there, everything started working again.

So now I have two questions:

  • How is it possible that this happened so suddenly? I cannot remember making any changes to my system except for updating to the latest release.

  • Why is /usr/sbin not included in /etc/profile?

I even had to include the new path to my cron jobs, because they dont use /etc/profile. So I think the problem is at a deeper level than just /etc/profile.

When you login as non-root user, it is normal that sbin locations (s for super user) are missing in the path, or do you mean it’s missing for the root user?

Cron jobs do not read /etc/profile (only for login sessions). ~/.bashrc is generally read with all bash shells, including scripts and cron jobs and can change the path, but by default it contains an exit path for noninteractive sessions.

So when you create a cron job with calls root-only commands like the ones you miss, either create is for the root user or use sudo within the script.

I have a cron-job as root user, and it reported:

/bin/sh: 1: rfkill: not found

and also:

runuser: command not found

So it looks like the PATH of the root user changed?

For my normal user the PATH also changed, because normally I can execute:

sudo runuser 

or even normal

runuser (who will complain that it needs root)

But now nothing worked anymore, everything gave: command not found.

My .bashrc is default (untouched) and my /etc/profile was also untouched. By manually adding /usr/sbin I could execute runuser again.

For the root users cronjob I added the PATH explicitly using PATH="" and now it works again.

But I never needed to set the PATHs manually before in cron, so there is still something wrong.

Hmm, can you show the output of the following commands:

bash -c 'echo $PATH'
sudo bash -c 'echo $PATH'
dash -c 'echo $PATH'
sudo dash -c 'echo $PATH'

So the PATH variable on fresh non-interactive bash and dash (sh) sessions as root and non-root user.

dietpi@xxx:~$ bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
dietpi@xxx:~$ sudo bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
dietpi@xxx:~$ dash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
dietpi@xxx:~$ sudo dash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Hmm those are expected the shell internal defaults and contain the sbin locations :thinking:.

Cron is non-interactive as well, so I’m puzzled how it can be different there.

Did you reboot in between or restarted the cron service?

systemctl restart cron

I executed those commands over SSH so it was running interactive I guess.

To get them non-interactice does it mean I have to connect a keyboard and screen to the Pi? Or is there a simpeler way?

The cron jobs are executed non-interactive. To do the same from console, wrap the commands into bash -c 'commands...'.

Okay, then I executed them correctly already.

To see if the problem was solved, I disabled the PATH= line from the root cron, so it looked like this:

#PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
@reboot rfkill block wifi

and rebooted. But it resultes in the error again:

/bin/sh: 1: rfkill: not found

Do you have a command that I can put in the root cron that dumps the path? Should I just put someting like

 @reboot echo $PATH

in it?

I echoed the PATH in root cron, and it returned:

/usr/bin:/bin

So clearly this is the root cause of the problem.

Interesting, does /etc/crontab contain a PATH line?

Yes:

# Please use dietpi-cron to change cron start times
SHELL=/bin/dash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""

that’s how it looks for me on my RPi 4B

root@DietPiProd:~# cat /etc/crontab
# Please use dietpi-cron to change cron start times
SHELL=/bin/dash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""

# m h dom mon dow user command
#*/0 * * * * root cd / && run-parts --report /etc/cron.minutely
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 1 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }
47 1 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }
52 1 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
root@DietPiProd:~#

For me it looks the same, I just copied only the top part.

My problem is just that the root cronjob has this PATH by default now:

/usr/bin:/bin

And before it included more directories, so now suddenly all of my cronjobs start to fail unless I manually specify the full path.

Does it work for you on a regular root login shell/session? Actually I wonder whether it is expected on user crontabs. AFAIK all the ones I use are no sbin commands.

I tried running

su -s

But it does not accept the password: dietpi ?

When I do

sudo echo $PATH

I get the correct path:

usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Okay, so I mixed it up and only the cron job is affected?

Not sure about the password, in case it’s the one you set during first boot of this DietPi system. If you didn’t change or yet, you should do so:

sudo passwd root

I logged in as root and the path was:

usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

So it seems only the cronjob is affected.

What do you get when you echo $PATH from the root cron?

Okay, it’s the same here on various systems, so this seems to be normal. I’ve never recognised it since I never used sbin commands in user cron tabs. So you need to define PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin (or whatever you need) in the individual crontab, or use full command paths.

/etc/crontab is affecting only the cron jobs in /etc/cron.*/.

Okay! I also tried it on three Ubuntu machines, and there I got the full path in root cron. But maybe this is different between pure Debian and Ubuntu?

The weird thing is I had a backup script running in root cron for weeks. And these backups always worked. Suddenly I get email notifications from the cron daemon about this problem. So for one reason or another, in the past I had the full path. Otherwise the backup script could have never worked like it did before.

So that will always be mystery, but let’s close this issue then. Thanks for the excellent support in any case!