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

[SC2317] False positive with nested functions #3057

Open GrabbenD opened 2 months ago

GrabbenD commented 2 months ago

For bugs


Non-problematic code example

#!/usr/bin/env bash

PARENT () {
  echo 'ok'

  NESTED () {
    echo 'ok'
  }
}

PARENT # SC2317 isn't triggered despite NESTED never being invoked (unless exit is specified on next line)

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

1) When PARENT function is exported:

PARENT () {
  echo 'ok'

  NESTED () {
    echo 'SC2317 ERROR triggered only for this line'
  }
}

func=$(declare -f PARENT)
$func  # PARENT echo works
NESTED # NESTED echo works

2) When NESTED function definition is printed:

PARENT () {
  echo 'ok'

  NESTED () {
    echo 'SC2317 ERROR triggered only for this line'
  }
}

func=$(PARENT && declare -f NESTED) 
echo "$func" # Contents of NESTED are printed

3) When exported PARENT function is called in a new shell

PARENT () {
  echo 'ok'

  NESTED () {
    echo 'SC2317 ERROR triggered only for this line'
  }
}

cmd="$(declare -f PARENT); PARENT; NESTED"
bash -c "${cmd}" # Both echo works
#runuser --login "${USER}" --shell "/bin/bash" -- -c "${cmd}" # Another example

4) When PARENT function is called indirectly through a function argument (this pattern is commonly used for callback functions):

PARENT () {
  echo 'ok'

  NESTED () {
    echo 'SC2317 ERROR triggered only for this line'
  }
}

HANDLER () {
  $1     # PARENT echo works
  NESTED # NESTED echo works
}

HANDLER PARENT

Here's what shellcheck currently says:

www.shellcheck.net

SC2329 (info): This function is never invoked. Check usage (or ignored if invoked indirectly).

VSCode

Command appears to be unreachable. Check usage (or ignore if invoked indirectly). shellcheck(SC2329)


Here's what I wanted or expected to see:

Indirectly invoked NESTED function(s) shouldn't trigger SC2329 if the PARENT function isn't detected as unused

Summary

Looks like this false-positive is triggered for NESTED function(s) only when the PARENT function is called indirectly