Ubuntu下使用Bash变量传递含双引号参数执行C程序异常问题
Bash变量存储带空格的参数无法正确识别的问题解决
我来帮你搞定这个Bash参数传递的问题!先理清楚你的场景:你写了一个简单的C程序test_arg.c用来打印命令行参数,直接传递带双引号的参数时一切正常,但把参数存在Bash变量里再传递就出问题了。
先贴一下你的C代码(方便大家参考):
#include <stdio.h> void main(int argc, char **argv) { for(int i=0; i < argc; i++) { printf("arg[%d]:%s \n", i, argv[i]); } }
直接执行的正常结果你已经给出了:
ubuntu@ubuntu:~$ ./test_arg.out 1 2 3 "4 5 6" arg[0]:./test_arg.out arg[1]:1 arg[2]:2 arg[3]:3 arg[4]:4 5 6
问题重现
我猜你是这样用变量存储参数的:
# 错误的写法 params='1 2 3 "4 5 6"' ./test_arg.out $params
执行后会得到类似这样的错误输出:
arg[0]:./test_arg.out arg[1]:1 arg[2]:2 arg[3]:3 arg[4]:"4 arg[5]:5 arg[6]:6"
原因解释
这是因为Bash在处理未加引号的变量展开时,只会按照**空白字符(空格、制表符、换行)**进行单词分割,不会重新解析字符串里的双引号——也就是说,双引号会被当成普通的字符,而不是用来将4 5 6合并成一个参数的标记。
正确解决方案
在Bash中,要正确存储和传递包含空格的参数,应该使用数组,而不是普通字符串变量:
- 用数组定义参数:
# 正确的写法:用数组存储参数 params=(1 2 3 "4 5 6")
- 展开数组时,必须用
"${params[@]}"的形式(双引号不能少,@表示展开数组的所有元素,每个元素作为独立参数):
./test_arg.out "${params[@]}"
执行这个命令后,你会得到和直接传递参数完全一样的正确结果:
arg[0]:./test_arg.out arg[1]:1 arg[2]:2 arg[3]:3 arg[4]:4 5 6
补充说明
如果你是从某个字符串动态构造参数(比如从配置文件读取),也可以用read -a来将字符串解析成数组:
param_str='1 2 3 "4 5 6"' read -r -a params <<< "$param_str" ./test_arg.out "${params[@]}"
注意:尽量避免用eval来处理这种情况,因为如果参数里包含特殊字符(比如$、;),eval会执行这些命令,带来安全风险。
内容的提问来源于stack exchange,提问作者ABCDEFG
相关产品推荐
相关产品推荐

