首页 > 解决方案 > 如何正确使用包含多个参数(可能包含空格)的 bash 变量

问题描述

如何将包含空格的变量传递给脚本,以便脚本正确处理它们?

我的最小示例:

测试.sh

#!/bin/bash
COUNTER=1
for i in "$@"; do echo "$COUNTER '$i'"; ((COUNTER++)); done

如果我直接使用一些参数(转义空间)调用脚本,它可以工作:

./test.sh 1 2 3\ 4 5

输出(如预期):

1 '1'
2 '2'
3 '3 4'
4 '5'

如果我将参数存储到变量中,则反斜杠不再被正确解释为转义字符。

TEST_ARGS="1 2 3\ 4 5"
./test.sh $TEST_ARGS

输出:

1 '1'
2 '2'
3 '3\'
4 '4'
5 '5'

我想得到和以前一样的输出。我怎样才能达到它?

TEST_ARGS="1 2 3\ 4 5"
# how to call ./test.sh here?

我更详细的用例是,我有一些脚本,它为我的其他工具/脚本准备所有标志。

prepare_flags.sh(非常简约):

#!/bin/bash
echo 'TEST_ARGS="1 2 3\ 4 5"'

在我的实际脚本中,我获取 prepare_flags.sh 脚本的输出以访问 TEST_ARGS:

source <( ./prepare_flags.sh )
./test.sh $TEST_ARGS # this fails
bash -c "./test.sh $TEST_ARGS" # this works

除了 bash -c 之外,还有其他解决方案吗?

标签: bashshell

解决方案


使用数组,而不是普通变量。

(此外,没有理由使用像exprBash 这样的古老外部工具;((++COUNTER))可以正常工作。(另外,最好避免使用大写变量名,因为这些(按照惯例)用于环境变量。))

test.sh

for ((i = 1; i <= $#; ++i)); do echo "${i} '${!i}'"; done

传递参数:

test_args=(1 2 '3 4' 5)
./test.sh "${test_args[@]}"

推荐阅读