* Many shells will throw a fatal error when attempting to ''shift'' more than the number of positional parameters. **POSIX does not require that behavior**. Bash (even in POSIX mode) and Zsh return 1 when there are no args, and no error output is produced unless the [[internals/shell_options#shift_verbose | shift_verbose]] [[commands/builtin/shopt | shopt]] option is enabled. Ksh93, pdksh, posh, mksh, and dash, all throw useless fatal shell errors.<code>
</code> In most shells, you can work around this problem using the [[commands:builtin:command | command]] builtin to suppress fatal errors caused by //special builtins//. <code> $ dash -c 'f() { if command shift 2>/dev/null; then echo "$1"; else echo "no args"; fi; }; f'
</code> While, POSIX requires this behavior, it isn't very obvious and some shells don't do it correctly. To work around this, you can use something like:
<del>The mksh maintainer refuses to change either the ''shift'' or ''command'' builtins.</del> [[https://github.com/MirBSD/mksh/commit/996e05548ab82f7ef2dea61f109cc7b6d13837fa | Fixed]]. (Thanks!)
* Perhaps almost as bad as the above, busybox sh's ''shift'' always returns success, even when attempting to shift beyond the final argument. <code> $ bb -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f'