Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to securely quote an optional flag?

Tags:

bash

If $FOO is set, I want to run:

cd "$OUTPUTDIR" && fpm -s dir -t rpm \
  -a x86_64 \
  --epoch "${PKGEPOCH}" \
  -n "${PACKAGENAME}" \
  --version "${PKGVERSION}" \
  --iteration "${PKGRELEASE}" \
  -C "$OUTPUTDIR/installroot" \
  --description="${PKGDESCRIPTION}" \
  .

If $FOO is not set, I don't want to include the flag at all.

The program fails if --description= (empty).

However, sometimes descriptions include quotes and other special characters so I don't want to do:

if [[ -z "PKGDESCRIPTION" ]]; then
    D=--description="${PKGDESCRIPTION}"
fi
cd "$OUTPUTDIR" && fpm -s dir -t rpm \
  -a x86_64 \
  --epoch "${PKGEPOCH}" \
  -n "${PACKAGENAME}" \
  --version "${PKGVERSION}" \
  --iteration "${PKGRELEASE}" \
  -C "$OUTPUTDIR/installroot" \
  $D
  .

If I put quotes around $D then it becomes an additional (blank) arg.

Is there a way to do this that won't be a security problem if $PKGDESCRIPTION includes special chars AND doesn't generate a blank arg?

like image 289
TomOnTime Avatar asked Dec 19 '22 07:12

TomOnTime


2 Answers

Using an array is the only sane way to do this:

options=( -a x86_64  -C "$OUTPUTDIR/installroot" )
[[ $PKGEPOCH ]]       && options+=( --epoch "$PGKEPOCH" )
[[ $PACKAGENAME ]]    && options+=( -n "$PACKAGENAME" )
[[ $PKGVERSION ]]     && options+=( --version "$PKGVERSION" )
[[ $PKGRELEASE ]]     && options+=( --iteration "$PKGRELEASE" )
[[ $PKGDESCRIPTION ]] && options+=( --description="$PKGDESCRIPTION" )

cd "$OUTPUTDIR" && fpm -s dir -t rpm "${options[@]}"

See also http://mywiki.wooledge.org/BashFAQ/050

like image 156
glenn jackman Avatar answered Jan 01 '23 23:01

glenn jackman


If PKGDESCRIPTION is the only argument that needs this conditional treatment, you can use an "alternate value" expansion:

[...] && fpm -s dir -t rpm \
    [...] \
    ${PKGDESCRIPTION:+ --description="${PKGDESCRIPTION}"} \
    .

Explanation: the :+ means this will expand to nothing at all unless PKGDESCRIPTION is set to a non-null value; if it is set to something non-null, it expands to --description="${PKGDESCRIPTION}", and the double-quotes make it ignore special characters in PKGDESCRIPTION's value. Note that the space in :+ -- isn't needed, but does no harm and makes it at least slightly easier to read.

BTW, if more than one argument needs this treatment, I'd go with @glenn jackman's approach.

like image 39
Gordon Davisson Avatar answered Jan 01 '23 23:01

Gordon Davisson