shellcheck icon indicating copy to clipboard operation
shellcheck copied to clipboard

Detect variable assignment in `eval`

Open stanio opened this issue 2 months ago • 3 comments

For new checks and feature suggestions

  • [x] https://www.shellcheck.net/ (i.e. the latest commit) currently gives no useful warnings about this
  • [x] I searched through https://github.com/koalaman/shellcheck/issues and didn't find anything related

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

#!/bin/sh

# shellcheck disable=SC2034
foo1="bar"
foo2="baz"
foo3="qux"

for i in 1 2 3; do
  eval value="\$foo${i}"
  echo "$value"
done

Here's what shellcheck currently says:

Using version 0.11.0:

In test.sh line 10:
  echo "$value"
        ^----^ SC2154 (warning): value is referenced but not assigned.

For more information:
  https://www.shellcheck.net/wiki/SC2154 -- value is referenced but not assig...

Here's what I wanted to see:

No warnings. Detect a variable has been assigned in eval value=... and don't warn about it: SC2154 (warning): value is referenced but not assigned.

stanio avatar Nov 05 '25 09:11 stanio

So, you're using eval to simulate namerefs in Bourne shell?

On Wed, Nov 5, 2025, 01:10 Stanimir Stamenkov @.***> wrote:

stanio created an issue (koalaman/shellcheck#3350) https://github.com/koalaman/shellcheck/issues/3350 For new checks and feature suggestions

  • https://www.shellcheck.net/ (i.e. the latest commit) currently gives no useful warnings about this
  • I searched through https://github.com/koalaman/shellcheck/issues and didn't find anything related

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

#!/bin/sh

shellcheck disable=SC2034

foo1="bar" foo2="baz" foo3="qux" for i in 1 2 3; do eval value="$foo${i}" echo "$value"done

Here's what shellcheck currently says:

Using version 0.11.0:

In test.sh line 10: echo "$value" ^----^ SC2154 (warning): value is referenced but not assigned.

For more information: https://www.shellcheck.net/wiki/SC2154 -- value is referenced but not assig...

Here's what I wanted to see:

No warnings. Detect a variable has been assigned in eval value=... and don't warn about it: SC2154 (warning): value is referenced but not assigned.

— Reply to this email directly, view it on GitHub https://github.com/koalaman/shellcheck/issues/3350, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUF2F25HAHV6VYA7XOAVDBD33G5ITAVCNFSM6AAAAACLGCHGZWVHI2DSMVQWIX3LMV43ASLTON2WKOZTGU4TAMBRGYYTMMI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

wileyhy avatar Nov 06 '25 22:11 wileyhy

I'm using it to implement POSIX-compatible lookup table.

stanio avatar Nov 07 '25 06:11 stanio

Hm. Well, use of eval can have some unintended side effects. Perhaps you've already read this link:

https://mywiki.wooledge.org/BashFAQ/048

Otherwise, it sounds like you're trying to gerry-mander a data structure. In Bash, an indexed array would be one such data structure. In POSIX shell, the only array-like construct is the positional parameters, which are the options after the script name.

$ bash ./script.sh --foo --bar --etc

These are available during runtime as "$@" or "$*". They can be defined from within the script using the set built-in.

~ $ bash --posix bash-5.3$ echo "${POSIXLY_CORRECT}" y bash-5.3$ set -- a b c bash-5.3$ printf '<%s>\n' "$@"

Another option would be to use a case statement in a function.

bash-5.3$ fn ()

{ case "$1" in foo) echo bla;; bar) echo quux;; esac } bash-5.3$ fn foo bla

Or, as an alternative, awk can also be used with a lookup table written into a file.

bash-5.3$ printf ' 5 strawberry\n 6 apple\n 7 banana\n' > ./lookup-table bash-5.3$ cat ./lookup-table 5 strawberry 6 apple 7 banana bash-5.3$ awk '$1 == "6" { print $2 }' ./lookup-table apple

The advantage of using awk is that each record (row) can have multiple fields (columns), and that each command can print multiple fields.

bash-5.3$ printf ' 8 key lime cheese cake\n' > ./lookup-table bash-5.3$ cat ./lookup-table 8 key lime cheese cake bash-5.3$ awk '$1 == "8" { print $4 }' ./lookup-table cheese bash-5.3$ awk '$1 == "8" { print $3, $5 }' ./lookup-table lime cake

Cheers,

Wiley

On Thu, Nov 6, 2025, 22:10 Stanimir Stamenkov @.***> wrote:

stanio left a comment (koalaman/shellcheck#3350) https://github.com/koalaman/shellcheck/issues/3350#issuecomment-3500909607

I'm using it to implement POSIX-compatible lookup table.

— Reply to this email directly, view it on GitHub https://github.com/koalaman/shellcheck/issues/3350#issuecomment-3500909607, or unsubscribe https://github.com/notifications/unsubscribe-auth/AUF2F2ZAYRVFYY6DDZLCWZL33QZVVAVCNFSM6AAAAACLGCHGZWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTKMBQHEYDSNRQG4 . You are receiving this because you commented.Message ID: @.***>

wileyhy avatar Nov 08 '25 05:11 wileyhy