如何安全地引用可选标志?

时间:2015-02-03 23:39:47

标签: bash

如果设置了$FOO,我想运行:

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

如果未设置$FOO,我根本不想包含该标志。

如果--description=(空),程序将失败。

但是,有时描述包括引号和其他特殊字符,所以我不想这样做:

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
  .

如果我在$D附近加上引号,那么它就变成了一个额外的(空白)arg。

如果$PKGDESCRIPTION包含特殊字符并且不生成空白的arg,是否有办法执行此操作不会出现安全问题?

2 个答案:

答案 0 :(得分:9)

使用数组是唯一理智的方法:

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[@]}"

另见http://mywiki.wooledge.org/BashFAQ/050

答案 1 :(得分:2)

如果PKGDESCRIPTION是唯一需要此条件处理的参数,则可以使用“备用值”扩展:

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

说明::+表示除非将PKGDESCRIPTION设置为非空值,否则它将扩展为空;如果将其设置为非null值,则会扩展为--description="${PKGDESCRIPTION}",而双引号会使其忽略PKGDESCRIPTION值中的特殊字符。请注意,:+ --中的空格不是必需的,但不会造成任何伤害,并且至少可以让它更容易阅读。

顺便说一下,如果不止一个论点需要这种处理,我会选择@glenn jackman的方法。