STDERR.puts与Ruby中的put有什么不同?

rub*_*bie 39 ruby stderr

我正在学习Programming Ruby 1.9中的语言,并且他们在本书的早期将STDERR.puts写入了一个代码块,而没有解释他们为什么使用它或者它与puts有什么不同.

我用谷歌搜索并解释了这个术语,但我从研究中得到的只是它涉及诊断.编程Ruby提供的代码中没有任何地方似乎存在错误异常处理的链接.

这是代码.

require_relative 'csv_reader'
reader = CsvReader.new
ARGV.each do |csv_file_name|
  STDERR.puts "Processing #{csv_file_name}"
  reader.read_in_csv_data(csv_file_name)
end
Run Code Online (Sandbox Code Playgroud)

我确实设法在某处读取STDERR.puts用于错误处理的约定,但我想我问它是否与puts有什么不同.

Pal*_*tim 68

默认情况下,puts写入STDOUT.通过指定STDERR.puts,您将输出发送到STDERR句柄.虽然实现行为是相同的,但使用STDERR而不是STDOUT肯定会影响程序的使用者,因为它们将按照惯例尝试从STDOUT捕获程序的输出.最佳做法是将调试信息,错误,警告,状态等记录到STDERR,并将实际程序输出记录到STDOUT.


Ste*_*eet 24

在基于*nix的系统中,当新进程启动时,默认情况下将有三个打开的​​文件句柄,如下所示

0 - STDIN
1 - STDOUT
2 - STDERR

这些数字,让我们称之为文件描述符对于您用来启动程序的unix shell很重要.STDIN是程序期望从中获取输入的地方(通常是键盘,除非你改变了它).STDOUT是您的程序将其输出写入的位置(通常是屏幕,除非您已更改它),而STDERR是它将写入错误的位置(除非您更改它,否则通常是屏幕).

上面的共同声明是"除非你改变它".如果你运行这样的命令

command > file.out
Run Code Online (Sandbox Code Playgroud)

然后输出(写入STDOUT的所有内容)将不会显示在屏幕上,它将出现在file.out中.如果您运行这样的命令

command 2> file.err
Run Code Online (Sandbox Code Playgroud)

然后您的输出将再次出现在屏幕上,但写入STDERR的任何错误都将出现在file.err中.事实上,command > file.out这真的是简写command 1>file.out.无论什么适用于>符号(重定向)也适用于| 管道的象征.这意味着如果您将程序作为过滤器运行,在STDIN上接收数据并写入STDOUT,那么其他程序可以从程序接收数据,但是它们不会接收写入STDERR的数据.(除非你问过它)

您可以像这样一起使用这两个命令.

command 1> file.out 2> file.err  # Generally you would leave out the 1
Run Code Online (Sandbox Code Playgroud)

在这种情况下,毫不奇怪,输出和错误将在2个单独的文件中.Bash也有重复文件描述符的概念.这是通过>&运算符完成的.以下命令将STDOUT和STDERR放在同一个文件中.

command > file.out 2>&1
Run Code Online (Sandbox Code Playgroud)

这个命令所说的是运行命令设置STDOUT以重定向到file.out然后复制(>&)文件描述符2(STDERR)以转到文件描述符1将要去的地方(file.out)

你需要在这里使用这些参数的顺序要小心一点.将上面的命令与这个命令进行比较.

command 2>&1 > file.out
Run Code Online (Sandbox Code Playgroud)

这有一个完全不同的结果.此命令说运行命令并将STDERR复制到STDOUT(此时终端),然后将STDOUT重定向到file.out.您的错误文本将保留在屏幕上.