为什么scala将版本放在stderr上



我必须这样做:

scala -version 2>&1 | sed 's/.*version ([0-9]*.[0-9]*).*/1/'

取而代之的是:

scala -version | sed 's/.*version ([0-9]*.[0-9]*).*/1/'

所以我想知道为什么scala -version(有时可能…)把它的结果放在stderr上?

实际上,在Unix中,stderr不用于错误,仅用于

它更像是stdin和stdout用于默认管道流(cmd1 | cmd2 | cmd3),sdterr是命令创建者认为不应该进入该默认管道的所有内容,而是应该显示给构建它的用户。它包括错误,但有时也包括有关进度、配置、诊断等的信息。

让我们看看这个例子:

echo "2 + 2 * 2" | scala | grep "res"

这将把scala视为将源作为输入并在输出上打印评估结果的东西。但它仍然会在stderr上打印一些东西,当你运行它时,你会看到

Type in expressions for evaluation. Or try :help.
Jul 08, 2022 9:32:44 AM org.jline.utils.Log logr
WARNING: Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
scala> val res0: Int = 6

乍一看,它是多余的,但当你仔细观察时,它会"告诉"一些有趣的事情,比如WARNING: Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information),这在你调试脚本时很好,而不是进入你只希望看到执行结果的流。

如果在scala之后添加-version,会发生什么情况?

> echo "2 + 2 * 2" | scala -version | grep "res"
Scala code runner version 2.13.8 -- Copyright 2002-2021, LAMP/EPFL and Lightbend, Inc.

脚本仍然在运行——它是shell,所以无论它是否有意义,你都可以把很多东西粘在一起,所以这是意料之中的事。但这个脚本并没有做任何合理的事情——并没有来自scala -version的代码处理输出,如果版本登陆stdin,您会看到空的结果,而不知道发生了什么。但由于它已登录stderr,您可以看到发生了什么,并可以修复脚本。

如果您真的想处理scala -version输出,那么正如您所注意到的,它只需要一个2>&1

还有其他需要考虑的事情,比如评论中提到的:与java -version的操作一致,不承诺将此类信息打印到stdin。此外,它可能是以这种方式实现内部一致的:scala可能只使用stdin进行代码输入,使用stdout执行代码,其他任何内容都连接到stderr上的某个全局记录器打印。最后,虽然有一些约定应该和不应该进入stderr,但这些都不是一成不变的,所以不应该带有预定义的期望。作者会做他们觉得最务实的事情。

最新更新