Repository navigation
SC2155
export foo="$(mycmd)"foo="$(mycmd)"
export fooIn 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.
If you intend to ignore the return value of an assignment, you can either ignore this warning or use
foo=$(mycmd) || true
export fooShellcheck 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.
local foo="$(mycmd)"local foo
foo=$(mycmd)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
fooreadonly foo="$(mycmd)"foo="$(mycmd)"
readonly fooA serious quoting problem with dash is another reason to declare and assign separately. Dash is the default, /bin/sh shell on Ubuntu. More specifically, dash version 0.5.8-2.10 and others cannot run this code:
f(){ local e=$1; }
g(){ local g=$(printf '%s' "foo 2"); }
f "1 2"
gWhile this runs fine in other shells, dash doesn't treat this as an assignment and fails like this:
local: 2: bad variable name
The direct workaround to this bug is to quote the right-hand-side of the assignment. Separating declaraction and assignment also makes this runs fine in any shell.
(A rule to catch this problem is in the works at #1556).