Skip to content
Will Holen edited this page Feb 7, 2020 · 11 revisions

Declare and assign separately to avoid masking return values.

Problematic code in the case of export:

export foo="$(mycmd)"

Correct code:

foo="$(mycmd)"
export foo

Rationale:

In the original code, the return value of mycmd is ignored, and export will instead always return true. This may prevent conditionals, set -e and traps from working correctly.

When first marked for export and assigned separately, the return value of the assignment will be that of mycmd. This avoids the problem.

Exceptions:

If you intend to ignore the return value of an assignment, you can either ignore this warning or use

foo=$(mycmd) || true
export foo

Shellcheck does not warn about export foo=bar because bar is a literal and not a command substitution with an independent return value. It also does not warn about local -r foo=$(cmd), where declaration and assignment must be in the same command.

Problematic code in the case of local:

local foo="$(mycmd)"

Correct code:

local foo
foo=$(mycmd)

Rationale

The exit status of the command is overridden by the exit status of the creation of the local variable. For example:

$ f() { local foo=$(false) || echo foo; }; f
$ f() { local foo; foo=$(false) || echo foo; }; f
foo

Problematic code in the case of readonly:

readonly foo="$(mycmd)"

Correct code:

foo="$(mycmd)"
readonly foo

ShellCheck

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

Clone this wiki locally
You can’t perform that action at this time.