如果我想传递程序数据文件,我如何区分它们是数据文件的事实,而不仅仅是文件名的字符串。基本上我想文件重定向,但使用命令行参数,所以我可以肯定输入是正确的。
我一直在使用:
./theapp < datafile1 < datafile2 arg1 arg2 arg3 > outputfile
但我想知道它看起来像这样:
./the app datafile1 datafile2 arg1 arg2 arg3 > outputfile
允许使用命令行参数。
答案 0 :(得分:3)
将两个文件组合成这样的标准输入有点困难。更好的是:
cat datafile1 datafile2 | ./theapp arg1 arg2 arg3 >outputfile
使用bash
(至少),第二个输入重定向会覆盖第一个,但不会对其进行扩充。您可以使用以下两个命令查看:
cat <realfile.txt </dev/null # no output.
cat </dev/null <realfile.txt # outputs realfile.txt.
使用重定向时,您的应用程序甚至不会看到 >outputfile
(例如)。它由shell进行评估,打开它并将其连接到您尝试运行的进程的标准输出。您的所有程序通常会看到:
./theapp arg1 arg2 arg3
与标准输入相同,它由shell处理。
上面第一个命令唯一可能的问题是它将两个文件组合成一个流,这样你的程序就不会知道第一个结束和第二个结束的位置(除非它能以某种方式从文件内容中推断出这一点) )。
如果你想处理多个文件并知道它们是哪个,那么做一些历史悠久的传统就是:
./theapp arg1 arg2 arg3 @datafile1 @datafile2 >outputfile
然后打开您的应用程序并自行处理文件。这比使shell更好地工作。
答案 1 :(得分:1)
从程序的角度来看,所有命令行参数都是字符串,您必须自己决定它们是否代表文件名。在Unix上只有两个字节不能出现在文件名中:0x00和0x2F(NUL
和/
)。 [我的意思是 bytes 。除了HFS +之外,Unix文件系统完全无视字符编码,当然,合理的人使用UTF-8。]
Shell重定向根本不会出现在argv
中。
但是有一个约定:将不以短划线开头的argv
的每个元素(当然除argv[0]
)作为要处理的文件的名称,按顺序处理出现。你不必做任何不引用的操作;只需将它们原样传递给fopen
(或open
)即可。如果字符串"-"
显示为argv
的元素,则在该点处理标准输入直到用尽,然后继续循环argv
。如果字符"--"
出现在argv
中,请将该点后的所有内容视为文件名,无论它是否以短划线开头。 (包括后续出现"-"
或"--"
)。
根据您使用的语言,可能会有一个方便的库模块甚至语言原语来处理这些内容。例如,在Perl中,您只需编写
for (<>) {
... do stuff with $_ ...
}
你可以免费获得我在“有一个会议......”段落中所说的一切。 (但你说C,所以,嗯,你必须自己完成大部分工作。我不知道普通C的参数处理库值得在磁盘上占用空间。:-()