为什么Scala将版本放在stderr上
我必须这样做:
scala -version 2>& 1 | sed's/s/.*版\([0-9]*\。[0-9]*\)。*/\ 1/'
而不是:
scala -version | sed's/s/.*版本\([0-9]*\。[0-9]*\)
。代码>(有时也许...)将其结果放在stderr
上?
I have to do this:
scala -version 2>&1 | sed 's/.*version \([0-9]*\.[0-9]*\).*/\1/'
Instead of this:
scala -version | sed 's/.*version \([0-9]*\.[0-9]*\).*/\1/'
so I am wondering why does scala -version
(sometimes maybe ...) put its result on stderr
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上,在Unix stderr中不用于错误 。
它更像是stdin和stdout用于默认管道流(
cmd1 | cmd2 | cmd3
),而sdterr是命令创建者认为不应该进入此默认管道的所有内容,而应显示为给构建它的用户。它包括错误,但有时还包括有关进度,配置,诊断等的信息。让我们看看其中的一些示例:
这将把Scala视为将源作为输入的东西,并打印出输出评估的结果。但是它仍然在stderr上打印一些东西,当您运行它时,您会
乍一看它是多余的Dumb Terminal(启用调试记录以获取更多信息),很高兴看到您要调试脚本,而不是进入只能看到执行结果的流。
如果您在
scala
之后添加-version
会发生什么?脚本仍然运行 - 它是外壳,因此无论是否有意义,您都可以将很多东西粘合在一起,因此可以预期。但是该脚本没有任何合理的操作 - 没有
scala -version
的代码处理输出,如果版本降落在stdin上,您会看到空的结果,不知道发生了什么。但是,由于它降落在stderr上,您会看到发生了什么,并且可以修复脚本。而且,如果您实际上想处理
scala -version
输出,那么您注意到的是一个2>& amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp;》。
还有其他要考虑的内容,如评论中提到的内容:与
Java -version
的一致性一致,没有保证将此类信息打印给STDIN。同样,可能已经使它在内部保持一致:scala
可能会专门使用stdin进行代码输入和stdout进行代码执行,并且其他任何内容都与STDERR上的某些全局记录器打印有关。最后,尽管有一些惯例应该和不应该进入stderr,但都不应该放石头,因此您不应带来预定的期望。作者将做 找到最务实的事情。Actually, in Unix stderr is not used for errors only.
It's more like stdin and stdout are using for the default piping streams (
cmd1 | cmd2 | cmd3
) and sdterr is everything that the command creators thought that should not go into this default pipeline, and instead should be shown to the user who build it. It includes errors, but sometimes also information about progress, configuration, diagnostics, etc.Let's see some example of that:
This would treat scala as something that takes source as input and prints the results of evaluation on output. But it still prints some stuff on stderr, and when you run it you'll see
On a first glance it is redundant but when you look closely it tells some interesting things like
WARNING: Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
which is nice to see as you are debugging your script, and not go into the stream where you are only expecting to see the results of the execution.What would happen if you added
-version
afterscala
?Script still runs - it's shell so you can glue a lot of things together whether it makes sense or not, so it's expected. But this script doesn't do anything reasonable - there is no code processing output from
scala -version
and if version landed on stdin you'd see empty result, not knowing what happened. But since it landed on stderr you see what happened, and can fix the script.And if you actually wanted to process
scala -version
output, it's just one2>&1
away as you noticed.There are also other things to consider like mentioned in comments: consistency with what
java -version
does, no promise to print such information to stdin. Also, it might have been made this way to be internally consistent:scala
might use stdin for code input and stdout for code execution exclusively, and anything else is wired to some global logger printing on stderr. Finally, while there are some conventions what should and should not go into stderr, none of that is set in stone, so you should not come with predefined expectations. Authors will do what they find the most pragmatic.