I've seen some weird syntax and I don't fully understand it. It seems to me that this alternative would be simpler and cleaner...

If you've been in that position, what you're reading may be a workaround for some known issue. This page is meant to showcase and explain a few of those.

Workaround:   somecommand ${1+"$@"}
Alternative:  somecommand "$@"

Some of the older Bourne shells expanded this to somecommand "" (with one empty argument).

${1+"$@"} expands to nothing if $1 is unset, and to "$@" (quoted) otherwise.

This is not required nor recommended for any shell that's less than 20 years old.

Workaround:   [ "X$var" = "Xvalue" ]
Alternative:  [ "$var" = "value" ]

If $var starts with a -, some old shell will interpret it as an option, resulting in something like [ -z = value ] which causes an error. Prepending any string (usually X) to both sides prevents this problem.

This is extremely ugly. As above, it's not required nor recommended for any shell that's less than 20 years old.

For some reason, users on StackOverflow will always recommend this. PLEASE DON'T USE IT.

Workaround:   [ -z "${var-}" ]
Alternative:  [ -z "$var" ]

With set -u, an unset variable will cause the shell to exit. ${var-} expands to an empty string if var is unset.

This happens in any shell, including bash. Most people just don't care much about set -u and use the cleaner version anyway.

Workaround:   command shift 10
Alternative:  [ "$#" -ge 10 ] && shift 10

In some shells, shifting too many arguments (over $#) is a syntax error and may cause the shell to exit. Using command as a prefix to a special builtin such as shift or . (dot) is a perfectly good workaround, as POSIX requires the shell to modify behavior in this case, however it is not a widely known solution. Some older shells and shells that don't correctly implement this feature may exit anyway. The workaround is also not required in the default non-POSIX mode of bash and zsh. See also: https://web.archive.org/web/20230320213458/https://wiki.bash-hackers.org/commands/builtin/shift#portability_considerations, https://austingroupbugs.net/view.php?id=882

Workaround:   sh -c 'shift "$1"; command' 2 1 arg1 arg2
Alternative:  sh -c 'command' _ arg1 arg2

All modern shells use the first parameter after the command string as $0. Older shells may not behave as expected, and use it as $1.

A clever shift solves the issue in a portable way. Found here: https://www.in-ulm.de/~mascheck/various/find/#shell

Workaround:   cmd && :
Alternative:  cmd

With set -e, an unchecked command will cause the shell to exit. This is a way to preserve the exit status of the previous command, and not exit even if set -e is active.

Workarounds (last edited 2024-03-28 14:51:09 by emanuele6)