背景:
之前遇到一个问题,我需要在执行一个shell脚本的时候,在脚本中需要调用一个可执行文件。该可执行文件需要传参,传递参数如以下类型:
-o "-flag0 -flag1 -flag2" -f a.file
但是当传参传递给可执行文件的时候,可执行文件端拿到的传参已经没有引号了,参数如下:
-o -flag0 -flag1 -flag2 -f a.file
这样会导致在可执行文件端处理参数的时候,将 -o 后面的选项误以为只有 -flag0 一个,同时将 -flag1 和 -flag2 认为是新的选项,这样就会导致传递给可执行文件时出现一些辨认问题。如果在传递给可执行文件时,依然保留有引号,则可以将这三个选项认为是一个参数。
分析:
而在传参给脚本的时候,以 "$@" 形式抓取传递参数,在脚本端以 echo 形式打印查看的时候,发现均已没有引号。在可执行文件端打印传参,也未发现引号。
解决:
需要调用一个函数,对 "$@" 参数进行初次的处理,保留原来的引号,代码如下:
#!/bin/bash
function ProcessOrgArg(){
whitespace="[[:space:]]"
final_str=""
blank_str=" "
for i in "$@"
do
if [[ $i =~ $whitespace ]]
then
i="\"$i\""
fi
final_str=${final_str}${blank_str}${i}
done
}
最终需要将原先的传参 "$@" 替换成现在的 final_str 即可。
将这段在脚本中 echo 输出,得到的结果依然是不带引号的。但是这并不代表这段代码无用,实际上传递参数已经带引号了。在可执行文件中打印传参,可见如下输出:
不过由于 c 代码中的 argv 是以空格作为分界条件,参数的数量依然没有变化,只有参数的内容有些许变化,通过对可执行文件传参做一个引号判断,就可以将 "-flag0 -flag1 -flag2" 视为单一参数,而非三个参数了。
至此,问题得到圆满解决。