我有一个从argv读取命令行参数的C程序。是否可以将管道重定向到文件的内容作为命令行参数到我的程序?假设我有一个包含此内容的文件arguments.dat
:
0 0.2 302 0
我希望通过以下方式调用我的程序:
./myprogram 0 0.2 302 0
我尝试了以下内容:
cat arguments.dat | ./myprogram
没有成功。
答案 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
xargs -0 ./myprogram <arguments.dat