如何从文件传递命令行参数
我有一个从 argv 读取命令行参数的 C 程序。是否可以创建一个管道将文件内容作为命令行参数重定向到我的程序?假设我有一个包含以下内容的文件 arguments.dat
:
0 0.2 302 0
我希望使用以下方式调用我的程序:
./myprogram 0 0.2 302 0
我尝试了以下操作:
cat arguments.dat | ./myprogram
没有成功。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
xargs
就是您的答案:或者更简单:
查看手册以了解自定义
xargs
的多种方法。例如,您可以逐行阅读而不是逐字阅读,并且可以在更复杂的替换中使用参数。xargs
is your answer:Or easier:
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.对于大多数 shell,您可以使用
$( 将文件的内容插入命令行:
如果您的 shell 不支持,则可以使用一种较旧的方法
:(您确实知道命令行参数和文件输入之间的区别,对吧?为什么您希望将命令行参数通过管道传输到程序中?)
With most shells, you can insert the contents of a file into a command line with
$(<filename)
:If your shell doesn't support that, then one of the older ways will work:
(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?)
如果您不希望参数被默默地分割
...也就是说:以下答案适用于
./myprogram --first-argument "first value" 默默地更改为
./myprogram --first-argument; ./myprogram“第一个值”
。如果你的参数是一对一行的文字
也就是说,如果你的输入看起来像:
并且你的意思是运行:
...那么你应该使用(对于 bash 4.0 或更高版本):
...或者(对于 bash 3.x 也是如此):
如果您的参数提供了引号或转义以区分它们
也就是说,如果您的文件包含类似的内容(请注意,换行符和未加引号的空格在此处的行为相同):
...并且您的意思是运行:
...那么你应该使用:
如果您可以控制参数格式
使用 NUL 分隔值。也就是说,按如下方式创建文件:
...并按如下方式解析它:
这将适用于所有可能的参数值,甚至是带有文字换行符、文字引号、文字反斜杠或其他不可打印字符的参数值。 (文字 NUL 在 UNIX 命令行中不可能,因为命令行由 NUL 结尾的字符串组成;因此,NUL 是唯一可以完全安全地用于明确分隔字符串中的参数的字符) 。
如果需要在调用之间拆分参数,
如果所需结果(文件中的参数多于可以传递给程序调用的参数)是程序的多个不同调用,每个调用接收参数子集,则本小节相关。在一系列案例中,
xargs
是完成这项工作的正确工具。如果在 GNU 平台上,您可能需要运行 xargs -a argument.dat 而不是重定向 stdin;但是,BSD xargs 不支持此功能(如在 MacOS 上),因此此处不进行演示。
如果您的参数是一对一行的文字
使用 GNU xargs(大多数 Linux 平台):
使用 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:
and you mean this to run:
...then you should use (with bash 4.0 or later):
...or (for bash 3.x as well):
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):
...and you mean this to run:
...then you should use:
If you control your argument format
Use NUL-delimited values. That is, create the file as so:
...and parse it as follows:
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):
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