Skip to content
Lucas Larson edited this page May 10, 2022 · 3 revisions

In POSIX sh, string indexing is undefined.

(or "In dash, ... is not supported." when using dash)

Problematic code:

#!/bin/sh
echo "Your initial is ${USER:0:1}"

Correct code:

Either switch to a shell that does support string indexing via parameter expansion, like bash or ksh, or rewrite with cut:

#!/bin/sh
echo "Your initial is $(printf '%s' "$USER" | cut -c 1)"

To find the last argument passed to a shell script without using bash’s ${@:$#}- or ${@: -1}-style string indexing, use the following, which even “works in the unix v7 bourne shell from 1979”:

#!/bin/sh
for argument in "$@"; do
  : # `:`, also called as `true`, is a no-op here
done
printf '%s\n' "${argument-}"

Rationale:

String indexing is a bash and ksh extension, and does not work in dash or POSIX sh.

Exceptions:

If you only intend to target shells that supports this feature, you can change the shebang to a shell that guarantees support, or ignore this warning.

You can use # shellcheck disable=SC3000-SC4000 to ignore all such compatibility warnings.

Related resources:

  • Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc!

ShellCheck

Each individual ShellCheck warning has its own wiki page like S001. Use GitHub "Pages" feature above to find a specific one, or see Checks.

Clone this wiki locally