koalaman / shellcheck

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

RFC: Should SC2312 warn on testing pipelines? #3025

Open hseg opened 1 month ago

hseg commented 1 month ago

For bugs

For new checks and feature suggestions

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


#!/bin/bash
# shellcheck enable=all

if false | grep hello; then echo failure; fi

Here's what shellcheck currently says:

Line 4:
if false | grep hello; then echo failure; fi
   ^-- SC2312 (info): Consider invoking this command separately to avoid masking its return value (or use '|| true' to ignore).

Here's what I wanted or expected to see:

Either nothing (after all, the fact that I'm testing the result of the pipeline indicates I am capturing the return value, albeit only of the last command), or a tailored warning indicating that the test as written will make me blind to which command failed.

Judging by the wiki page, the intent of the warning is more to flag that command substitutions can fail and leave null strings in their place. If this is the intent, then the wording of the warning doesn't communicate it efectively.

hseg commented 1 month ago

In fact, this fires on any usage of a pipeline:

#!/bin/bash
# shellcheck enable=all

echo "hello world" | grep hello | grep world

I wouldn't consider the "corrected" script to be idiomatic bash, especially considering PIPESTATUS exists. The only case I would consider perhaps leaving intact is

f() { echo "hello world" | grep hello | grep world; }

where the user has left the return code to implicitly be that of the final command, which might be surprising -- perhaps warn to set -o pipefail instead? Though I'm not sure how to make that setting scope only to the function, and am not sure we want to advise users to use it globally.