You should probably not be using $0, as it doesn't contain a pathname. Nonetheless, I believe there's truly a bug. Retyped from the manual for dirname 8.5: SYNOPSIS dirname NAME dirname OPTION While simple, this doesn't describe the GNU implementation, which is more like: dirname -- NAME dirname OPTION where OPTION begins with a hyphen or two. The '97 SUS 2 spec has the most simple synopsis: dirname string
GNU dirname 8.5 (and some earlier versions) and FreeBSD dirname as shipped with an OS X 10.4 fail to filter strings starting with an ASCII hyphen-minus, followed by one or more characters. FreeBSD dirname conformingly fails with exit code 1 (presumably EXIT_FAILURE) in all cases except if argv[1] is "--", in which case both GNU and FreeBSD dirname ignore it, and use argv[2] instead. As does GNU dirname 8.5, except for the strings "--version" and "--help", in which case it writes non-conforming user messages to stdout and exits successfully. Busybox 1.14 considers the string "--help" as invalid, and writes usage message to stderr and exits unsuccessfully. It's conforms to all aspects of the standard, but the definition of a valid pathname. It fails uniformly in the undefined case of more than two arguments. Henceforth, there's no portable way to invoke dirname, as GNU and FreeBSD dirnames fail if invoked as per SUS (with GNU dirname sometimes exiting successfully, to confuse matters further), and busybox fails if invoked per GNU conventions. Note bene that the former method has to be tried first as GNU dirname may fail successfully. dirname() { env dirname -- "$1" || env dirname "$1" } ------------ tl;dr dirname -bash should output a single dot followed by a newline.