2

Has anybody noticed that crontab doesnt seem to recognize ~ to mean the home directory?

I tried using a full expansion of /Users/username/filename.txt in crontab, which worked, but using ~/filename.txt results in failure.

Does anybody know why?

0

3 Answers 3

10

The question proposed using ~/username/filename.txt instead of /Users/username/filename.txt, but the proposed syntax should instead be either ~username/filename.txt or ~/filename.txt. For an illustration of a crontab entry which uses ~, see the top rated answer to Get low battery notifications for mouse earlier.

You can also test a simple example with this crontab entry:

* * * * * touch ~/NOT_A_FILE_I_CARE_ABOUT.txt
0
7

~ is a symbol shells automatically expand to $HOME, a standard /bin/sh (which cron uses to run the commands) does not need to support ~ expansion. The portable way is to use $HOME instead in your crontab file.

0
-1

Some shells support ~, and some don't. Perhaps Apple uses dash as the default cron shell in Catalina, and bash in Monterey?; perhaps Apple changes the cron environment depending upon the phase of the moon?

Better than guessing what Apple has (or has not) done on some particular version of macOS, and on a machine that may or may not have user modifications... wouldn't it be better to run some simple tests - ask cron to tell you something about its environment? This would be an objective truth; one that requires no assumptions, and is not dependent upon vagaries in Apple's documentation.

Once a day (or whenever you wish), you can run a cron job that logs its environment and some other useful information from your system to a file. The file is always there, and its never more than 24 hours old (assuming your system was operating at the time you scheduled it).

A job similar to the one below in your crontab would answer your questions "definitively" (however see NOTE 3. below):

0 12 * * * (echo $(date); echo "What is '~'?:" ~; printenv) > /Users/seamus/mycronenv.txt 2>&1

This produces a file named mycronenv.txt in my $HOME directory that looks similar to this:

Sat Jul 30 23:35:00 CDT 2022
What is '~'?: /Users/seamus
SHELL=/bin/sh
MAILTO=
USER=seamus
PATH=/usr/bin:/bin
PWD=/Users/seamus
SHLVL=1
HOME=/Users/seamus
LOGNAME=seamus
_=/usr/bin/printenv

As you can see, my system's (Catalina) cron recognizes ~ as $HOME. To verify this, I added another job to my crontab (see NOTE 1. below):

* * * * * (echo "Write this line to the file ~/testdir/testfile with a timestamp: "; echo $(date)) >> ~/testdir/testfile.txt 2>&1

Which worked as expected, writing the result to $HOME/testdir/testfile.txt.

And since I used the append form of the redirect (>>), it adds a new entry every minute - i.e. remove this job after your test!

Hope this helps clear the confusion - please let us know if the issue persists, or you have other questions.


NOTES:
  1. If you want to try this on your machine, create the directory testdir first:

    % cd
    % mkdir testdir
    
  2. On my system (Catalina), Apple has set the default configuration to send mail to me with a note re my cron job - which is not something I want. Consequently, I have added a line to my crontab to disable that:

    MAILTO=""
    
  3. Wrt definitively:

    From man sh it seems that, rather than being definitive, Apple has given themselves some latitude: cron may use any one of three shells (bash, dash or zsh) in service of /bin/sh:

    sh is a POSIX-compliant command interpreter (shell). It is implemented by re-execing as either bash(1), dash(1), or zsh(1) as determined by the symbolic link located at /private/var/select/sh. If /private/var/select/sh does not exist or does not point to a valid shell, sh will use one of the supported shells.

12
  • Wow. So much here based on speculation. Let’s start here: the default shell for cron is /bin/sh unless otherwise specified by the she bang in the script. Environment variables aren’t typically set so any tilde expansion (~) will result in access the home directory of the user that the cron job is executed under.
    – Allan
    Commented Jun 5, 2023 at 22:54
  • @Allan: ?! The primary point is not to speculate. If you had read the answer instead of looking for excuses to downvote, you might have picked up on that.
    – Seamus
    Commented Jun 6, 2023 at 20:47
  • I never down voted. That said, your second sentence re: dash starts it all off. A quick reading of the man page would tell you the default shell for cron is /bin/sh if SHELL isn’t set. Your SHELL is set to the default making it redundant. The ~ falls under parameter expansion for Bourne (sh), Bourne Again (Bash) and Zsh. I can’t speak to dash.
    – Allan
    Commented Jun 6, 2023 at 21:15
  • @Allan: I apologize if I made an error in deducing you were the downvoter; it's apparently a coincidence getting a comment and a downvote on the same day ~ 1 year after posting. But wrt the second sentence, the quote is verbatim from man sh, and it seems definitive to me. IOW, while /bin/sh might be the default for cron, man sh tells us that another shell may in fact be executed instead - depending upon the various settings. Also, I tend to rely upon the local man pages instead of third-party versions. Again, the point of my answer was to avoid speculation.
    – Seamus
    Commented Jun 7, 2023 at 0:00
  • No worries… I get accused of downvoting because I prefer to leave feedback. But, to make this short, what you’re referencing isn’t accurate. cron/bin/sh. That’s a given. However, /bin/sh → anything else if and only if it doesn’t exist. There’s no latitude for Apple there (as you put it). That’s also not an Apple thing, but the devs of the Bourne Shell - it’s that way across all platforms.
    – Allan
    Commented Jun 7, 2023 at 0:34

You must log in to answer this question.

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