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

发布于 2024-11-18 22:39:50 字数 309 浏览 5 评论 0 原文

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

0 0.2 302 0

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

./myprogram 0 0.2 302 0

我尝试了以下操作:

cat arguments.dat | ./myprogram

没有成功。

I have a C program that reads command line arguments from argv. Is it possible to make a pipe to redirect the contents of a file as command line arguments to my program? Suppose I have a file arguments.dat with this content:

0 0.2 302 0

And I want my program to be called with:

./myprogram 0 0.2 302 0

I tried the following:

cat arguments.dat | ./myprogram

without success.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风吹短裙飘 2024-11-25 22:39:50

xargs 就是您的答案:

cat arguments.dat | xargs ./myprogram

或者更简单:

xargs -a arguments.dat ./myprogram

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

xargs is your answer:

cat arguments.dat | xargs ./myprogram

Or easier:

xargs -a arguments.dat ./myprogram

Check the manual for the many ways to customize xargs. For example, you can read line-by-line rather than by word, and you can use the arguments in more complex replacements.

一城柳絮吹成雪 2024-11-25 22:39:50

对于大多数 shell,您可以使用 $( 将文件的内容插入命令行:

./myprogram $(<arguments.dat)

如果您的 shell 不支持,则可以使用一种较旧的方法

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

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

With most shells, you can insert the contents of a file into a command line with $(<filename):

./myprogram $(<arguments.dat)

If your shell doesn't support that, then one of the older ways will work:

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

(You do know the difference between command line arguments and file input, right? Why would you expect to pipe command line arguments into a program?)

捶死心动 2024-11-25 22:39:50

如果您不希望参数被默默地分割

...也就是说:以下答案适用于 ./myprogram --first-argument "first value" 默默地更改为 ./myprogram --first-argument; ./myprogram“第一个值”

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

也就是说,如果你的输入看起来像:

--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 argument.dat 而不是重定向 stdin;但是,BSD xargs 不支持此功能(如在 MacOS 上),因此此处不进行演示。

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

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

xargs -d 

使用 BSD xargs(MacOS、FreeBSD/OpenBSD/etc):

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

如果您的参数带有引号或转义以区分它们

xargs ./myprogram <arguments.dat

如果您已经生成 NUL 分隔的输入

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

使用 BSD xargs(MacOS、FreeBSD/OpenBSD/etc):


如果您的参数带有引号或转义以区分它们


如果您已经生成 NUL 分隔的输入


If You Don't Want Arguments To Be Silently Split

...which is to say: The below answers apply to cases where it wouldn't be acceptable for ./myprogram --first-argument "first value" to be silently changed into ./myprogram --first-argument; ./myprogram "first value".

If your arguments are one-to-a-line literals

That is, if your input looks like:

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

and you mean this to run:

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

...then you should use (with bash 4.0 or later):

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

...or (for bash 3.x as well):

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

If your arguments are provided with quotes or escaping to distinguish them

That is, if your file contains something like (note that newlines and unquoted spaces behave identically here):

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

...and you mean this to run:

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

...then you should use:

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

If you control your argument format

Use NUL-delimited values. That is, create the file as so:

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

...and parse it as follows:

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

This will work with all possible argument values, even ones with literal newlines, literal quotes, literal backslashes, or other nonprintable characters. (Literal NULs are not possible in UNIX command lines, since command lines are composed of NUL-terminated strings; thus, NUL is the only character which is completely safe to use to unambiguously separate arguments in a string).


If Splitting Arguments Across Invocations Is Desired

This subsection is relevant if the desired result (when there are more arguments in your file than can be passed to an invocation of your program) is multiple distinct invocations of the program, each one receiving a subset of arguments. This is a family of cases where xargs is the right tool for the job.

If on a GNU platform, you may want to run xargs -a arguments.dat instead of redirecting stdin; however, this isn't supported with BSD xargs (as on MacOS), and so is not demonstrated here.

If your arguments are one-to-a-line literals

With GNU xargs (most Linux platforms):

xargs -d 

With BSD xargs (MacOS, FreeBSD/OpenBSD/etc):

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

If your arguments are provided with quotes or escaping to distinguish them

xargs ./myprogram <arguments.dat

If you've generated NUL-delimited inputs

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

With BSD xargs (MacOS, FreeBSD/OpenBSD/etc):


If your arguments are provided with quotes or escaping to distinguish them


If you've generated NUL-delimited inputs



    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文