如何在Bash中正确定义含带空格文件名的命令行开关变量?
在Bash中正确定义包含带空格/特殊字符参数的命令行开关变量
想要定义一个变量来存储后续要运行的程序的命令行开关,其中一个开关需要接收可能包含空格或特殊字符的文件名参数,该如何正确实现?
示例代码:
#! /bin/bash FILE="/home/user/Excludes (1).txt" SWITCHES="--verbose --exclude $FILE" # 不管是直接写$FILE还是用\"$FILE\"都不行 someprogram $SWITCHES
以下是在Bash中尝试用字符串存储带空格参数的实际测试:
$ cat > "foo bar" me "foo bar" $ FOOBAR="foo bar" $ SWITCHES="-n $FOOBAR" $ cat $SWITCHES cat: foo: No such file or directory cat: bar: No such file or directory $ cat "$SWITCHES" cat: invalid option -- ' ' Try 'cat --help' for more information. $ SWITCHES="-n \"$FOOBAR\"" $ cat $SWITCHES cat: '"foo': No such file or directory cat: 'bar"': No such file or directory $ cat "$SWITCHES" cat: invalid option -- ' ' Try 'cat --help' for more information.
正确解决方案:使用Bash数组
用字符串存储开关和参数的方式本质上就有问题,因为Bash会在展开字符串时按空白符分割内容,无法保留带空格参数的完整性。正确的做法是用数组来存储每个独立的开关或参数:
1. 针对最初的示例修改
#! /bin/bash FILE="/home/user/Excludes (1).txt" # 用数组定义每个独立的项,带空格的参数用引号包裹 SWITCHES=(--verbose --exclude "$FILE") # 调用程序时用"${SWITCHES[@]}"展开数组,必须加引号 someprogram "${SWITCHES[@]}"
2. 针对cat测试示例修改
$ cat > "foo bar" me "foo bar" $ FOOBAR="foo bar" # 数组存储每个参数,带空格的项用引号包裹 SWITCHES=(-n "$FOOBAR") # 用数组展开方式调用命令 $ cat "${SWITCHES[@]}" me "foo bar"
为什么数组能解决问题?
- 数组的每个元素会被当作一个独立的参数,不会被Bash按空白符分割。
"${SWITCHES[@]}"这种展开方式会严格保留每个元素的原始内容,包括空格、括号等特殊字符,完美传递给目标程序。
内容的提问来源于stack exchange,提问作者Diagon
相关产品推荐
相关产品推荐

