How to update shell programs

Solution 1:

Where is the executable?

command -v cron

The result shows /usr/sbin/cron. System Integrity Protection (SIP) protects the contents of /usr; thus we cannot affect a change anyway as long as SIP is enabled. You installed BASH via Homebrew, I take it. Searching Homebrew for cron-related formulae or casks reveals no candidates (brew search cron), perhaps for reasons given by @nohillside. Perhaps cron was a bad example and a better example might be vim. As you have discovered, one can utilize a package manager like Homebrew or Macports to install more recent software. For each installed package, Homebrew, at least, installs a symbolic link to wherever the executable was installed (/usr/local/Cellar/[...]); thus, we could utilize a shell alias or modify the PATH environment variable to utilize better versions of common software. I use the shell alias approach.

For example, my shell is zsh, and I have installed MacVim. If the symbolic link for MacVim's version of vim exists (-h), then define a new alias. Now, every time I execute vim, I am not executing the vim located in /usr/bin; rather, I am executing the vim located in /usr/local/bin. The below test and definition works the same for bash.

[ -h '/usr/local/bin/vim'  ] && alias vim='/usr/local/bin/vim'
[ -h '/usr/local/bin/view' ] && alias view='/usr/local/bin/view'

And then use the package manager to update the software periodically.

if brew update 2>/dev/null; then
    brew upgrade
    brew cleanup
    rm -rf "$(brew --cache)"
fi

Solution 2:

The content of /usr/bin and friends is updated with each release of macOS, but usually the versions shipped by Apple are significantly older than what's available on Linux. There are various reasons for this, in a lot of cases it's related to changes in the GPL. In case of crontab it may also play a role that the use of cron is deprecated, launchd should be used instead.

If you want to update Unix binaries yourself

  • Use Homebrew (https://brew.sh)
  • Compile from source yourself and install in /usr/local/bin