0

System: Mac Big Sur

I been working more in the terminal and I thought it would be fun to have a fortune present a different message regularly during login. I know I can just add the fortune command to my .bash_profile but I wanted to run it as a motd for every user of the system and schedule it with launchd/crontab. The last time I setup a crontab to run my script as root but it emailed me an error about not being able to locate the commands in my script. Here's my script:

#!/bin/bash

#create a motd to be run by crontab every hour
fortune quotes | cowsay -f blowfish | lolcat > /etc/motd

I haven't tried this yet but I was thinking I could either use the absolute paths to the executables, if that is the issue. Or do I need back quotes around the commands. Would I need to change the root .bashrc file to have a search path to the file locations?

1 Answer 1

1

The issue is most likely that the script does not have the correct value of the environment variable PATH. It is in any case not any form of syntax issue.

You can solve this in one of three (or more) ways:

  1. Use absolute paths for each command, as you yourself suggest.

    The only instance when you need to do this is when you have multiple variants of utilities in the directories that you would otherwise add to PATH, and it's important that you pick the correct variant of the utility.

    For example, you may have lolcat in both /usr/local/bin and /opt/bin, and you really want to use the lolcat from /opt/bin. At the same time, you want to use the cowsay in /usr/local/bin and not the one in /opt/bin. In this situation, you can't just add the two paths to PATH.

  2. Add the directory (or directories) where the commands are located to the PATH variable in the script, before running your pipeline. E.g.,

    #!/bin/sh
    
    PATH=$PATH:/usr/local/bin
    
    fortune quotes | cowsay -f blowfish | lolcat >/etc/motd
    

    The PATH variable does not need to be exported as it's already an environment variable. The benefit of this would be that the script isn't littered with absolute paths to commands (easier to read).

  3. You can also modify the PATH variable as you call the script from your crontab:

    0 * * * * PATH=$PATH:/usr/local/bin /path/to/my-motd-script.sh
    

    (or whatever your schedule looks like.) Setting a variable on the command line like this sets it in the environment of your script.

    You could also use the env utility with the same effect:

    0 * * * * env PATH="$PATH:/usr/local/bin" /path/to/my-motd-script.sh
    

    This would allow you keep your current script unmodified.

Changing the PATH in root's .bashrc file would have no effect at all as that file is not read for non-interactive shell sessions, like cron jobs.

Note that I changed the #! line to #!/bin/sh. I did that as there is nothing in the script that actually needs bash. In this case, this has more to do with aesthetics than with actual functionality.

1
  • That's perfect! Thank you!
    – epsilonv
    Commented Jan 14, 2021 at 14:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .