3

I have a script running on Linux that accepts some parameters.
I would like to do something like:

if [[ $CONDITION == "true" ]]; then  
  script param1 --param2  
else
  script param1  
fi 

I would like to avoid the forking path of the if.
Is there a more optimal way to pass the second parameter?

  • 1
    Where is this if? In the script itself? In another script that calls the target script? Are these options (--param2) or arguments (param1)? Please edit your question and give us more details. – terdon May 30 '18 at 8:17
  • One other note: true is a shell builtin that returns a success exit status. If you use CONDITION=false when CONDITION is not true, then you could write: if "$CONDITION"; then echo yes; fi or "$CONDITION" && echo yes – glenn jackman May 30 '18 at 19:21
  • @glennjackman:The true is not the same as "true" right? – Jim May 30 '18 at 20:40
  • They are the same: gnu.org/software/bash/manual/bash.html#Quote-Removal -- you can execute the command "echo" "foo" with no difficulty because the shell will remove the quotes before executing the command. – glenn jackman May 30 '18 at 20:44
  • For example I often do valid=false if someCondition; then valid=true; fi; if ! $valid; then echo Invalid; exit 1; fi – glenn jackman May 30 '18 at 20:47
11

The cleanest way would probably be to use an array to hold the optional parameter(s):

params=()
if [[ $CONDITION == true ]]; then
    params+=(--param2)
fi
script param1 "${params[@]}"

Or in shorthand:

[[ $CONDITION == true ]] && params+=(--param2)
script param1 "${params[@]}"

That avoids repeating the constant part of the command.

Note that it's important to do this with an array: if you replace the array with a regular variable (params="--param2"; script param1 $params) you'll either have to expand the variable unquoted, with all the problems that brings, or expand it quoted, in which case you'll pass an empty string as argument if the variable is empty.

  • it should be noted that this is passing in part the literal string --, and not the unary -- operator – Steven Penny May 30 '18 at 18:22
  • 1
    @StevenPenny, well, the whole idea of a -- operator only exists in the shell within arithmetic expansions, and there aren't any here. I can't think of any special meaning for the dash in the shell outside of them, either. – ilkkachu May 30 '18 at 18:39
4

A versatile way to do this is to set the arguments in an array. The most basic array is the list of positional parameters defined with set. You can build the list of parameters in sequence.

set -- param1
if [[ $CONDITION == "true" ]]; then  
    set -- "$@" --param2  
fi 

command "$@"  

Which could be reduced to:

set -- param1
[[ $CONDITION == "true" ]] && set -- "$@" --param2
command "$@"  

If the list of positional parameters needs to be preserved, then either:

  • Use a function:

    callcommand(){     set -- param1
                       [[ $CONDITION == "true" ]] && set -- "$@" --param2
                       command "$@"       
                 }
    callcommand
    
  • Or use some other array variable:

    paramArray=()
    paramArray+=(param1)
    [[ $CONDITION == "true" ]] && paramArray+=( "--param2" )
    command "${paramArray[@]}"
    
  • I don't really understand this. param1 is already a parameter. Does this change the parameter array of the script? – Jim May 31 '18 at 20:48
  • @Jim No, param1 is not an argument of the script code above, it become a parameter of the command called. Yes, the positional parameters are changed (as they are used). See some alternatives in the edited answer. – Isaac Jun 1 '18 at 6:53
-1
PARAMS+=" param1"
if [[ $CONDITION == "true" ]]; then  
  PARAMS+=" --param2"
fi
script ${PARAMS}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.