从反引号(命令替换)中传递多个参数

3
假设我有一个文件params.txt,其内容如下:
--option "option 1" --option "option 2"

我希望能够使用params.txt文件中的内容作为命令行参数传递给myProg程序:
./myProg $(cat params.txt)

或者

./myProg `cat params.txt`

但是似乎这种方法行不通:它将多个单词的参数视为多个参数,而不是单引号包含的参数。有没有一种方法可以使用命令替换(或其他我不知道的bash功能)从params.txt中提取参数并获取结果?

./myProg --option "option 1" --option "option 2"

作为执行的命令是什么?


“params.txt” 是由人类还是软件编写的? - Charles Duffy
如果数据来自软件,最好的选择是将其设为 NUL 分隔符,而不是 shell 引用。 - Charles Duffy
谢谢。这是人工编写的。如果它是以NUL为分隔符,那么在bash中是否有一种简单的使用方法?编辑:刚看到你答案的更新。谢谢! - Alex Lew
1个回答

2
如果你信任的人编写了 params.txt,你可以使用 eval 来执行它:
eval "./myProg $(<params.txt)"

安全地从脚本编写一个可以通过eval的流应该像下面这样:
printf '%q ' --option "option 1" --option "option 2" >params.txt

更好的存储参数且不会产生使用eval带来的严重安全风险的方法是使用NUL分隔的流。
# write params file
printf '%s\0' --option "option 1" --option "option 2" >params

...然后,去消费那个...
# read params file into array
params=( )
while IFS= read -r -d '' param; do
  params+=( "$param" )
done <params

# use that array to call your program
./myProg "${params[@]}"

请注意,后一种形式不支持命令替换,但如果您正在读取比cat更有趣的命令输出(最好用简单的重定向代替),则可以与进程替换一起使用。因此:
# this does not work: depends on NULs being stored in a shell variable
while IFS= read -r -d '' param; do params+=( "$param" ); done <<<"$(...command here...)"

# this works
while IFS= read -r -d '' param; do params+=( "$param" ); done < <(...command here...)

请注意,进程替换是 POSIX sh 中没有的功能;请确保您的 shebang 指定了支持此功能的 shell(例如 #!/bin/bash)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接