当程序的结果默认情况下应打印到标准输出,以及何时更合适的方法是接受输出文件作为参数之一并写入它时,是否有任何经验法则?人们总是可以将标准输出重定向到文件。
我知道有不同的程序,例如,如果结果是多个文件而不是单个文件,则打印到标准输出是没有意义的。如果程序的输出具有临时性质,则接受输出文件作为参数也是没有意义的。
但是,产生最终应放置在单个文件中的输出的程序又如何呢?此类程序可以进一步分为从 stdin 接受输入的程序和从参数获取输入的程序。
答案1
一些实际例子:
将其输出发送到 stdout 的应用程序通常意味着该应用程序可以正常工作任何类型对于接收者来说,它只是发送也适用于管道或套接字的数据流。这是 Unix 管道的本质,所以如果如果有任何经验法则,那么这个可能是最好的候选者。
另一方面,-o <output-file-name>
如果应用程序更喜欢需要寻求其输出。
当然,您lseek(2)
也可以超过标准输出(如果它确实是可查找的),但这通常是意想不到的行为。
当然,同样的情况也适用于输入。
从文件重定向/到文件重定向需要 shell。专用选项参数允许不需要 shell。
从/到文件重定向可以轻松共享该文件的位置(如果可查找)或多个应用程序之间的管道/套接字连接,这在 shell 脚本编写中可能是一个有用的功能,例如:
{
echo hello world
head -c 10
seq 10 | awk '{print "amazing text-manipulation of", $0}'
dd bs=1024 count=1 seek=32
echo farewell
} < /dev/random > recipient-file
仅依靠-o recipient-file
选项(或-i /dev/random
)将不允许(如此容易)。
在某些情况下,上面的相反情况也可能成立:一个-o <output-file-name>
选项允许生成该应用程序的输出不是与其他应用程序共享时污染标准输出,例如:
strace -o prog.strace output-producer > prog.output
对于输入、拥有应用程序来说也是如此不是使用共享的标准输入。
unwanted-consumer -i /dev/null desired-consumer
仅依赖 stdin/stdout 将需要额外的 shell 层,如下所示:
strace > prog.strace sh -c 'output-producer > prog.output'
或对于标准输入:
unwanted-consumer 3<&0 < /dev/null sh -c 'desired-consumer <&3'
除了命令的紧凑性/简洁性以及完全需要 shell 之外,调用 shell 还涉及到稍微不同的环境,您可能需要针对output-producer
或进行调整desired-consumer
,从而增加总体负担。
答案2
如果您可以想象程序的输出用作另一个程序的输入,并且输出基本上是文本,那么默认为 stdout 可以让程序轻松用作管道的一部分。
另一方面,如果输出通常是二进制的,或者非常大(与给定的输入相比),那么默认情况下询问文件名是有意义的,并且除非明确询问,否则拒绝在终端上打印。
对于第一组,请考虑grep
、sort
、cut
等,它们作为输送另一个程序的管道的一部分以及提供由用户直接读取的输出同样有效。几乎每个人都知道它们打印到标准输出,并且如果需要的话,可以将输出重定向到文件。
对于第二个,请考虑例如convert
ImageMagick,它可以转换和处理图像文件。它在命令行上获取输入和输出文件名。在这里,图像文件很少用作管道的一部分,并且在实践中,人们永远不希望将 JPEG 或 PNG 转储到终端,因此在这里这样做是有意义的。
当采用文件名参数时,最好使用-
stdin 或 stdout,前提是您对此进行了记录。这是一个相当常见的习惯,并且使用户不必使用类似的东西/dev/stdin
。 (这在某些系统中可能会失败。)
做其他工具所做的事情是好的,因为它不会留下意外的空间。当然,除非您的用例足够不同,以至于复制其他用例没有意义。