如何从文件传递命令行参数

时间:2011-07-05 15:20:42

标签: linux pipe command-line-arguments cat argv

我有一个从argv读取命令行参数的C程序。是否可以将管道重定向到文件的内容作为命令行参数到我的程序?假设我有一个包含此内容的文件arguments.dat

0 0.2 302 0

我希望通过以下方式调用我的程序:

./myprogram 0 0.2 302 0

我尝试了以下内容:

cat arguments.dat | ./myprogram

没有成功。

3 个答案:

答案 0 :(得分:11)

xargs是您的答案:

cat arguments.dat | xargs ./myprogram

或者更容易:

xargs -a arguments.dat ./myprogram

查看手册以了解自定义xargs的多种方法。例如,您可以逐行而不是按字读取,并且可以在更复杂的替换中使用参数。

答案 1 :(得分:5)

对于大多数shell,您可以将文件的内容插入到$(<filename)的命令行中:

./myprogram $(<arguments.dat)

如果您的shell不支持,那么其中一种旧方法可以使用:

./myprogram $(cat arguments.dat)
./myprogram `cat arguments.dat`   # need this one with csh/tcsh

(您确实知道命令行参数和文件输入之间的区别,对吗?为什么您希望将命令行参数传递到程序中?)

答案 2 :(得分:2)

如果您不希望吵架悄无声息

...也就是说,以下答案适用于将./myprogram --first-argument "first value"悄悄更改为./myprogram --first-argument; ./myprogram "first value"的情况。

如果您的参数是一对一行的文字

也就是说,如果您输入的内容如下:

--first-argument
first value
--second-argument
second value

这就是说要运行:

./myprogram --first-argument "first value" --second-argument "second value"

...然后您应该使用(对于bash 4.0或更高版本):

readarray -t args <arguments.dat
./myprogram "${args[@]}"

...或(对于bash 3.x也是):

args=( )
while IFS= read -r arg; do
  args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"

如果您的论点带有引号或转义符以区分它们

也就是说,如果您的文件包含类似内容(请注意,换行符和未加引号的空格在此处的行为相同):

--first-argument "first value"
--second-argument "second value"

...您的意思是要运行:

./myprogram --first-argument "first value" --second-argument "second value"

...那么您应该使用:

args=( )
while IFS= read -r -d '' arg; do
  args+=( "$arg" )
done < <(xargs printf '%s\0' <arguments.dat)

如果您控制参数格式

使用NUL分隔的值。也就是说,按如下方式创建文件:

printf '%s\0' "argument one" "argument two" >arguments.dat

...并解析如下:

args=( )
while IFS= read -r -d '' arg; do
  args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"

这将与所有可能的参数值一起使用,甚至包括带有文字换行符,文字引号,文字反斜杠或其他不可打印字符的参数值。 (由于命令行由NUL终止的字符串组成,因此在UNIX命令行中不可能使用文字 ;因此,NUL是唯一可以安全地用于明确区分字符串中的参数的字符)


如果需要跨调用拆分参数

如果期望的结果(当文件中的参数比传递给程序的调用多的参数时)是程序的多个不同的调用,且每个子接收一个参数的子集,则此小节是有意义的。这是一类案例,其中xargs是完成工作的正确工具。

如果在GNU平台上,则可能要运行xargs -a arguments.dat而不是重定向stdin;但是,BSD xargs(与MacOS一样)不支持此功能,因此此处未进行演示。

如果您的参数是一对一行的文字

使用GNU xargs(大多数Linux平台):

xargs -d $'\n' ./myprogram <arguments.dat

使用BSD xargs(MacOS,FreeBSD / OpenBSD /等):

xargs -0 ./myprogram < <(tr '\n' '\0' <arguments.dat)

如果您的论点带有引号或转义符以区分它们

xargs ./myprogram <arguments.dat

如果您生成了NUL分隔的输入

xargs -0 ./myprogram <arguments.dat