2

Example script:

#!/bin/bash

printf '1\n1\n1\n1\n' | ./script2*.sh >/dev/null 2>/dev/null

Shellcheck returns the following:

In script1.sh line 3:
printf '1\n1\n1\n1\n' | ./script2*.sh >/dev/null 2>/dev/null
                        ^-- SC2211: This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting?

According to https://github.com/koalaman/shellcheck/wiki/SC2211, there should be no exceptions to this rule.

Specifically, it suggests "If you want to specify a command name via glob, e.g. to not hard code version in ./myprogram-*/foo, expand to array or parameters first to allow handling the cases of 0 or 2+ matches."

The reason I'm using the glob in the first place is that I append or change the date to any script that I have just created or changed. Interestingly enough, when I use "bash script2*.sh" instead of "./script2*.sh" the complaint goes away.

Have I fixed the problem or I am tricking shellcheck into ignoring a problem that should not be ignored? If I am using bad bash syntax, how might I execute another script that needs to be referenced to using a glob the proper way?

Harold Fischer
  • 279
  • 1
  • 9

1 Answers1

2

The problem with this is that ./script2*.sh may end up running

./script2-20171225.sh ./script2-20180226.sh ./script2-copy.sh

which is a strange and probably unintentional thing to do, especially if the script is confused by such arguments, or if you wanted your most up-to-date file to be used. Your "fix" has the same fundamental problem.

The suggestion you mention would take the form:

array=(./script2*.sh)
[ "${#array[@]}" -ne 1 ] && { echo "Multiple matches" >&2; exit 1; }
"${array[0]}"

and guard against this problem.

Since you appear to assume that you'll only ever have exactly one matching file to be invoked without parameters, you can turn this into a function:

runByGlob() {
  if (( $# != 1 ))
  then
    echo "Expected exactly 1 match but found $#: $*" >&2
    exit 1
  elif command -v "$1" > /dev/null 2>&1
  then
    "$1"
  else
    echo "Glob is not a valid command: $*" >&2
    exit 1
  fi
}

whatever | runByGlob ./script2*.sh

Now if you ever have zero or multiple matching files, it will abort with an error instead of potentially running the wrong file with strange arguments.

that other guy
  • 116,971
  • 11
  • 170
  • 194