5

I wonder if it's possible to reduce the last four lines in the following example:

#!/bin/bash

function xxx {
  echo $#
  echo $1
}

[[ -n $SOME_ENV ]] && P="-Dabc=$SOME_ENV"

if [[ -n $P ]]; then
  xxx "$P" abc
else
  xxx abc
fi

Replacing the if-else-fi by just

xxx "$P" abc

does work if $P is not empty, otherwise not because "" still counts as empty parameter. Omitting the quotes around $P does not work if SOME_ENV contains spaces. I know that it's possible with "eval", but eval is evil: http://mywiki.wooledge.org/BashFAQ/048

Any other solution?

0

3 Answers 3

9

I like using an array the best. An alternative, for what it's worth, is to use alternate value substitution.

xxx ${P:+"$P"} abc

This will be substituted with "$P" if $P is set and not blank. If it is empty, the entire word is removed. The neat thing is you could get rid of $P altogether.

xxx ${SOME_ENV:+"-Dabc=$SOME_ENV"} abc
Sign up to request clarification or add additional context in comments.

Comments

4

If you want to use an options variable, p, make it an array:

p=()
[[ -n $SOME_ENV ]] && p+=("-Dabc=$SOME_ENV")

xxx "${p[@]}" abc

If p is empty, then "${p[@]}" expands to nothing, just as you want.

For example, with SOME_ENV unset, $# is 1 as it should be:

$ bash script
1
abc

With SOME_ENV set, then $# is 2 as it should be:

$ SOME_ENV='1 2 3' bash script
2
-Dabc=1 2 3

Comments

2

You already test the length of $SOME_ENV and set $P only when $SOME_ENV is not empty. $P and $SOME_ENV are either both empty or both non-empty. Do you have any good reason to test $P?

I would merge the two tests and then just make $P disappear (it is just a temporary variable in the code you posted). Something like this:

if [[ -n $SOME_ENV ]]; then
  xxx -Dabc="$SOME_ENV" abc
else
  xxx abc
fi

1 Comment

Your solution is perfect if one would keep the last 4 lines. But i want to get rid of it. My intention is to have only one line starting with "xxx". The real example contains much more that just a common "abc". I want to avoid that redundancy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.