3

I am trying to make a shell script which will ask some questions to the user, and will issue a final command with some or other options depending on what the user chose. Right now, the script looks like this:

if [[ $a == "y" ]] ; then

    command --option 1 argument

elif [[ $a == "n" ]] ; then

    command --option 2 argument

else

    command --option 3 argument

fi

Considering the command is very long, and contains a lot of options and arguments which remain constant between the different statements, I was wondering if I could in some way write a single line, with variable options being considered only if the corresponding condition is true.

This also applies to GNU parallel issuing one or more commands

if [[ $b == "n" ]] ; then

    find ./ -name '*.extension' | parallel -j $(nproc) command1 --option argument

else

    find ./ -name '*.extension' | parallel -j $(nproc) command1 --option argument\; command2 --option argument
2
  • FYI this looks like a good candidate for a case construct Commented Sep 9, 2016 at 0:43
  • -j $(nproc) is redundant: It has been the default for several years now. Commented Sep 9, 2016 at 6:36

1 Answer 1

6

Sure, you can store the options to pass in a variable. Your first example could be something like this (also, [[ is a bash feature, not available in POSIX shell):

if [[ $a == "y" ]] ; then
    arg=1
elif [[ $a == "n" ]] ; then
    arg=2
else
    arg=3
fi

command --option "$arg" argument

Your second example:

if [[ $b != "n" ]] ; then
    extra="; command2 --option argument"
fi

find ./ -name '*.extension' | parallel -j $(nproc) command1 --option argument$extra
# if unset, $extra will be empty—you can of course explicitly
# set it to '' if this bothers you.

These work because of how variable expansion works: it's just substituted in to the command line, then (if unquoted) word-splitted, then passed to the command. So the called command doesn't know about the variables at all, the shell expanded them before calling it.

Since you're using bash, you can also use arrays:

args=()

if [ -n "$OPT_LONG" ]; then
    args+=(-l)
fi

if [ -n "$OPT_SORT_TIME" ]; then
    args+=(-t)
fi

ls "${args[@]}"

The array feature lets you easily build up arbitrarily long argument lists without worrying about word splitting breaking your code.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.