Skip to content
Home » Why Your Linux Commands Fail on macOS (BSD vs GNU)

Why Your Linux Commands Fail on macOS (BSD vs GNU)

macOS’s command-line tools come from BSD, not the GNU coreutils that ship with most Linux distributions. They cover the same ground, but their flags don’t always match — so a command copied straight from a Linux tutorial can error out or quietly behave differently. Here’s the pattern, the two standalone commands people hit most beyond find and sed, and the clean way to get GNU behavior when you need it. Checked on macOS 26.5.2.

The pattern: BSD, not GNU

Almost every difference comes down to the same root: macOS inherits its userland from BSD, while Linux uses GNU. GNU tends to add extra convenience flags — -printf, -d, -c, case-conversion escapes — that the leaner BSD versions never had. The two commands people trip over most each have their own guide: the find command on macOS and the sed command on macOS. This page covers two more standalone cases, and the escape hatch for when you want GNU behavior outright.

date: -v and -j, not -d

GNU’s date -d, for relative dates and parsing arbitrary strings, doesn’t exist in BSD date:

$ date -d 'yesterday'
date: illegal option -- d

BSD date does relative math with -v, and parses a specific input format with -j -f:

$ date -v-1d '+%Y-%m-%d'                       # yesterday
2026-07-18
$ date -j -f '%Y-%m-%d' '2020-06-15' '+%A'    # weekday of a given date
Monday

-v-1d means “adjust by minus one day,” and the adjustments chain — -v-1m -v+2d is “one month back, then two days forward.” -j -f reads the input using the format you give it, then reformats it however you like.

stat: -f, not -c

GNU’s stat -c format flag isn’t recognized either:

$ stat -c '%s %n' file
stat: illegal option -- c

BSD stat uses -f with its own set of format letters — %z for size, %N for name, where GNU used %s and %n:

$ stat -f '%z %N' file
3 file

This is the same stat -f that the find guide reaches for as a replacement for GNU’s -printf.

The ones that have caught up

Not every old warning still holds — recent macOS has quietly closed some gaps, so it’s worth testing before you work around one. readlink -f, long cited as a GNU-only way to resolve a symlink to its full real path, now works on macOS:

$ readlink -f link
/Users/you/project/target

So does \n in a sed replacement, another difference that guides still warn about. And realpath is now built in as another way to canonicalize a path. The lesson is to check the behavior on your own version rather than trusting a blanket “doesn’t work on Mac.”

The escape hatch: GNU coreutils

When a script genuinely needs GNU behavior, the cleanest move is to install the GNU tools alongside the BSD ones instead of rewriting every flag. Homebrew‘s coreutils formula installs them with a g prefix — gdate, gstat, greadlink, gsort, and the rest — leaving the system versions untouched:

brew install coreutils
gdate -d 'yesterday'          # GNU date, with GNU flags

find and sed live in their own formulas — findutils gives you gfind, and gnu-sed gives you gsed. A portable script can then call the g-prefixed tools everywhere and behave the same on macOS and Linux.

The rule of thumb: macOS commands are BSD, so reach for -v and -j on date, -f on stat, and check whether an old “doesn’t work on Mac” claim still applies before you route around it. When you need Linux behavior wholesale, the g-prefixed coreutils are the tidy way to get it. All checked on macOS 26.5.2.

Leave a Reply

Your email address will not be published. Required fields are marked *