koalaman / shellcheck

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

SC2154 from strict bash mode example using trap #2980

Closed peterjc closed 4 months ago

peterjc commented 6 months ago

For bugs

For new checks and feature suggestions

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

#!/bin/bash
set -uo pipefail
trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
IFS=$'\n\t'

echo "Example of strict bash mode from Michael Daffin, see"
echo "https://olivergondza.github.io/2019/10/01/bash-strict-mode.html"

Here's what shellcheck currently says:

[Line 3:](javascript:setPosition(3, 6))
trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
     ^-- [SC2154](https://www.shellcheck.net/wiki/SC2154) (warning): s is referenced but not assigned.

Here's what I wanted or expected to see:

No error, my understanding is this does define s. Currently https://www.shellcheck.net/wiki/SC2154 currently says:

ShellCheck intentionally does not attempt to figure out runtime or dynamic assignments like with source "$(date +%F).sh" or eval var=value. See SC2034 for an extended discussion of why this is the case.

Is using trap equivalent, and if so it that worth adding to the documentation?

Is the recommendation as per the SC2034 documentation to use a throw-away variable _ like so:

#!/bin/bash
set -uo pipefail
trap '_=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $_' ERR
IFS=$'\n\t'

echo "Example of strict bash mode from Michael Daffin, see"
echo "https://olivergondza.github.io/2019/10/01/bash-strict-mode.html"

This passes shellcheck 🚀

taiki-e commented 4 months ago

FYI, workaround is using trap -- '...'.

peterjc commented 4 months ago

Thank you Taiki - that workaround is simpler, but I don't understand this well enough to suggest a wiki change for other people:

#!/bin/bash
set -uo pipefail
trap -- 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
IFS=$'\n\t'

echo "Example of strict bash mode from Michael Daffin, see"
echo "https://olivergondza.github.io/2019/10/01/bash-strict-mode.html"

We can probably close this issue.