我有一个从 argv 读取命令行参数的 C 程序。是否可以制作管道将文件的内容作为命令行参数重定向到我的程序?假设我有一个arguments.dat
包含以下内容的文件:
0 0.2 302 0
我希望我的程序被调用:
./myprogram 0 0.2 302 0
我尝试了以下方法:
cat arguments.dat | ./myprogram
没有成功。
我有一个从 argv 读取命令行参数的 C 程序。是否可以制作管道将文件的内容作为命令行参数重定向到我的程序?假设我有一个arguments.dat
包含以下内容的文件:
0 0.2 302 0
我希望我的程序被调用:
./myprogram 0 0.2 302 0
我尝试了以下方法:
cat arguments.dat | ./myprogram
没有成功。
xargs
是你的答案:
cat arguments.dat | xargs ./myprogram
或者更简单:
xargs -a arguments.dat ./myprogram
查看手册以了解自定义的多种方法xargs
。例如,您可以逐行而不是逐字阅读,并且可以在更复杂的替换中使用参数。
对于大多数 shell,您可以使用以下命令将文件的内容插入命令行$(<filename)
:
./myprogram $(<arguments.dat)
如果您的外壳不支持该功能,那么其中一种较旧的方法将起作用:
./myprogram $(cat arguments.dat)
./myprogram `cat arguments.dat` # need this one with csh/tcsh
(您确实知道命令行参数和文件输入之间的区别,对吧?为什么希望将命令行参数通过管道传递到程序中?)
...也就是说:以下答案适用于不能./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 结尾的字符串组成;因此,NUL 是唯一可以完全安全地用于明确分隔字符串中的参数的字符)。
如果所需的结果(当文件中的参数多于可以传递给程序调用的参数时)是程序的多个不同调用,每个调用都接收参数的子集,则本小节是相关的。这是一系列案例,其中xargs
适合这项工作的工具。
如果在 GNU 平台上,您可能希望运行xargs -a arguments.dat
而不是重定向标准输入;但是,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