我有一个读取命令行参数的C程序,它从argv中读取参数。是否可以创建一个管道将文件的内容重定向为我的程序的命令行参数?假设我有一个名为arguments.dat
的文件,其内容如下:
0 0.2 302 0
我希望我的程序能够被以下方式调用:
./myprogram 0 0.2 302 0
我尝试了以下内容:
cat arguments.dat | ./myprogram
没有成功。
我有一个读取命令行参数的C程序,它从argv中读取参数。是否可以创建一个管道将文件的内容重定向为我的程序的命令行参数?假设我有一个名为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
"第一个参数" "第二个参数"
,那么将会把"第一个
作为第一个参数,参数"
作为第二个参数,"第二个
作为第三个参数。如果它包含*.txt
,它将被替换为文本文件列表,而不是保持它的字面意义。如果文件包含"*.txt"
,则引号将作为字符串的文字部分传递(如果用户没有使用nullglob
或failglob
使前者被视为失败的glob...好吧,如果没有任何以双引号字符开头和结尾的名称的文件,则失败)。 - Charles Duffy...也就是说:以下答案适用于不能将./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)
printf '%s\0' "argument one" "argument two" >arguments.dat
...并按如下方式解析:
args=( )
while IFS= read -r -d '' arg; do
args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"
即使参数值包含了字面换行、字面引号、字面反斜线或其他不可打印的字符,这个方法也可以处理所有可能的参数值。(在UNIX命令行中不可能使用字面NULs,因为命令行由以NUL结尾的字符串组成;因此,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
xargs
将会在多次运行./myprogram
时,在调用之间分割参数。 - Charles Duffyxargs
有许多高级操作方式,可以让你引用参数并逐行读取等等。 - Kerrek SBls -1
我会用xargs -d \n
...但是为什么不发表一个答案呢?那肯定会成为一个合适的答案。 - Kerrek SB