Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

resolving shellcheck printf warnings have me stuck with either SC2059 or SC2089

For the following code, I’m getting SC2089 "Quotes/backslashes will be treated literally, use an array"

# Quotes/backslashes will be treated literally, use an array
CMD_AVAIL_MSG='%s is required for this script but the "%s" command is missing. Exiting...'
if [ -z "$(which valet)" ]; then
    printf -v err $CMD_AVAIL_MSG "Laravel Valet" "valet";
    echo $err; # there's other stuff I do here, but using echo for conciseness
    exit 1;
fi

However, converting this to an array gives me shellcheck warning SC2059 "Don’t use variables in the printf format string, use ‘…%s…’ $foo"

CMD_AVAIL_MSG=("%s" 'is required for this script but the "' '%s' '" command is missing. Exiting...')
if [ -z "$(which valet)" ]; then
    # Don't use variables in the printf format string, use '...%s...' "$foo"
    printf -v err "${CMD_AVAIL_MSG[@]}" "Laravel Valet" "valet";
    echo $err; # there's other stuff I do here, but using echo for conciseness
    exit 1;
fi

How do I resolve both of these warnings?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Warning SC2059 is intended to prevent people from passing data in the format-string position. You aren’t doing that (your "data" is in fact a format string), so it isn’t intended for you and can be safely disabled.

On the other hand, you are still misusing printf: Because each invocation of printf accepts only a single format string, CMD_AVAIL_MSG should be a regular string, not an array. (It also should be lowercase; all-caps names are reserved by POSIX-specified convention for variables that reflect or modify behavior of the shell or other POSIX-specified tools).

cmd_avail_msg='"%s" is required for this script but the "%s" command is missing. Exiting...'
if ! command -v valet >/dev/null 2>&1; then
    # shellcheck disable=SC2059
    printf -v err "$cmd_avail_msg" 'Laravel Valet' valet
    echo "$err" >&2
    exit 1;
fi

Note the use of if ! command -v valet >/dev/null 2>&1 instead of if [ -z "$(which valet)" ]. This is both more efficient and more portable: which is a separate executable being run as a subprocess, whereas command -v is a POSIX-specified command internal to the shell itself.


The above being said, this looks like a place where you can, and perhaps should, use a function instead of a variable with a format string — that way you can reuse the entire code block, not just the single message.

check_for_cmd() {
  local cmd=$1 name=$2 err
  command -v "$cmd" >/dev/null 2>&1 && return 0
  printf -v err \
    '"%s" is required for this script but the "%s" command is missing. Exiting...' \
    "$name" "$cmd"
  # do other stuff here
  echo "$err" >&2
  exit 1
}

check_for_cmd valet "Laravel Valet"
check_for_cmd other "Something Else"
1 comments
  1. how can i do ?
    In WooComerece we have to add a product in that product there is 1 box in box there is 6 peace of pastry and user can select those 6 in different different flavors

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading