如果都提供了标准输入或文件名,是否应该丢弃它们?

如果都提供了标准输入或文件名,是否应该丢弃它们?

grepsed如果您提供文件名参数,则忽略 stdin:

$ echo foo > test.txt
$ echo foobar | grep f test.txt 
foo
$ echo foobar | sed -e 's/foo/bar/' test.txt 
bar

这是既定的最佳实践吗?如果是这样,为什么?

答案1

程序知道文件是否在其命令行上指定。它无法知道 stdin 上是否有可用的输入(除了尝试读取它),并且如果有输入,程序也无法知道该输入是否是供其使用的。因此,唯一明智的选择是根据程序的调用方式(命令行参数、环境变量、配置文件等)制定明确的规则,来决定是否从 stdin 读取。

例如,典型的文本实用程序 ( catsortgrepawkperl -p、 …) 如果未提供文件,则从 stdin 读取;如果有,则从指定文件读取。解释器遵循类似的约定,例如,sh不带参数从标准输入读取命令,同时sh script_file_name从指定文件读取命令(如果需要,则让脚本读取 stdin)。还有一个常见的约定,如果-出现在预期输入文件名的位置,则程序将从 stdin 读取。

考虑一个 shell 片段,例如

somecommand | while read line; do
  process "$line"
done

您需要知道是否process从标准输入读取。不存在“测试是否提供 stdin”这样的事情:它在那里,但调用程序的用户知道他是否希望读取 stdin。

答案2

我找到的答案就是它的设计方式。如果您想从标准输入和文件中读取数据,请使用echo foobar | grep f - test.txt.从man grep

 grep  searches the named input FILEs (or standard input if no files are
 named, or if a single hyphen-minus (-) is given as file name) for lines
 containing  a  match to the given PATTERN.  By default, grep prints the
 matching lines.

相关内容