koalaman / shellcheck

ShellCheck, a static analysis tool for shell scripts
https://www.shellcheck.net
GNU General Public License v3.0
36.2k stars 1.77k forks source link

SC2086: False positive for "export" and "local" built-ins (POSIX Shell) #2443

Open itaranto opened 2 years ago

itaranto commented 2 years ago

For bugs

Here's a snippet or screenshot that shows the problem:

#!/bin/sh
export FOO=${BAR}

This shouldn't be a problem, it should expand the variable in the same way that FOO=$BAR does, i.e. quotes are not required here.

Here's another one:

#!/bin/sh

# shellcheck disable=SC3043

do_something() {
    local foo=${1}
    echo "${foo}"
}

I know that in POSIX local is not defined, but since almost every POSIX shell supports it, I make an exception.

However, the last example works fine on Bash:

#!/bin/bash

do_something() {
    local foo=${1}
    echo "${foo}"
}

Here's what shellcheck currently says:

SC2086 (info): Double quote to prevent globbing and word splitting.

Here's what I wanted or expected to see:

Nothing

jwilk commented 2 years ago

Double quotes are need in some shells. From example, this happens in Ubuntu 20.04 LTS, which ships with dash 0.5.10.2:

$ dash -c 'v="hello world"; export w=$v; echo "$w"'
hello

$ dash -c 'v="hello world"; export w="$v"; echo "$w"'
hello world

This was fixed only in dash 0.5.11: https://git.kernel.org/pub/scm/utils/dash/dash.git/commit/?id=cbb71a836874d176

Relevant POSIX bug: https://www.austingroupbugs.net/view.php?id=351

itaranto commented 2 years ago

Yes, makes sense. I didn't realize because I always use up-to-date versions.

Since the dash bug was fixed in 2018, and also the POSIX bug seems fixed too (correct me if I'm wrong), maybe this warning can be removed once all "mayor" distros start switching to newer dash versions.

Also, bash doesn't seem to have this issue.

And what about the local statement?

jwilk commented 2 years ago

And what about the local statement?

local is affected too:

$ dash -c 'v="hello world"; f() { local w=$v; echo "$w"; }; f'
hello

$ dash -c 'v="hello world"; f() { local w="$v"; echo "$w"; }; f'
hello world