首页 > 解决方案 > Bash 将字符串解析为一个参数而不是两个

问题描述

我有一个 bash 脚本和这个 bash 脚本处理的 -e 标志。我想决定是否需要动态使用这个 -e 标志。代码看起来像这样:

if [...] then;
export EXPIRATION_FLAG="-e 1m";
else
export EXPIRATION_FLAG=""
fi
./my_script.sh $EXPIRATION_FLAG

问题是 bash 将此字符串解析为一个参数,而不是 2 个单独的参数。因此,如果 echo $1 我得到“-e 1m”,如果 echo $2 我得到“”,而不是 $1“-e”和 $2“1m”

脚本本身:

#!/bin/bash

set -x

echo $1
echo $2

while getopts e: OPT
do
    case $OPT in
        e) expirationPeriod=$OPTARG ;;
        *) printUsage ;;
    esac
done
shift `expr $OPTIND - 1`

if [ -n "$expirationPeriod" ] ; then
  echo $expirationPeriod
fi

任何想法如何解决这个问题?

标签: bashshscript

解决方案


./my_script.sh $EXPIRATION_FLAG

这在 POSIX-y shell 中,不带引号,应该调用分词并且./my_script.sh应该得到两个参数。

$ foo() { printf "<%s> <%s>\n" "$1" "$2"; }
$ flags='-e 1m'
$ foo $flags
<-e> <1m>

当然,如果您引用它,或者您的IFS不包含空格,则不会发生这种情况:

$ foo "$flags"
<-e 1m> <>
$ IFS=
$ foo $flags
<-e 1m> <>

检查您是否没有更改IFS调用 shell 中的全局变量。请注意,某些 shellIFS从环境继承(Bash 没有,但以防万一您实际上使用的是 Dash)。

Zsh 默认情况下也不会拆分,您必须要求它这样做:

% foo() { printf "<%s> <%s>\n" "$1" "$2"; }
% flags='-e 1m'
% foo $flags
<-e 1m> <>
% foo $=flags
<-e> <1m>

在任何情况下,您可能应该使用数组来存储多个这样的参数,而不是依赖于分词,请参见例如 我们如何运行存储在变量中的命令?在 unix.SE 上。


推荐阅读