如何将输出发送到stderr

时间:2014-12-21 10:11:37

标签: rust stdio

使用它将输出发送到stdout:

println!("some output")

我认为没有相应的宏可以为stderr做同样的事情。

5 个答案:

答案 0 :(得分:65)

Rust 1.19

之后

从Rust 1.19开始,您可以使用eprinteprintln宏:

fn main() {
    eprintln!("This is going to standard error!, {}", "awesome");
}

这最初是在RFC 1896中提出的。

在Rust 1.19之前

你可以看到implementation of println!深入了解它是如何工作的,但是当我第一次看到它时,它有点压倒性。

您可以使用类似的宏格式化东西到stderr:

use std::io::Write;

let name = "world";
writeln!(&mut std::io::stderr(), "Hello {}!", name);

这会给你一个unused result which must be used警告,因为打印到IO 可能会失败(这不是我们打印时通常会考虑的事情!)。在这种情况下,我们可以看到现有的方法simply panic,因此我们可以更新我们的代码来执行相同的操作:

use std::io::Write;

let name = "world";
let r = writeln!(&mut std::io::stderr(), "Hello {}!", name);
r.expect("failed printing to stderr");

这有点多,所以让我们把它换回宏:

use std::io::Write;

macro_rules! println_stderr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

fn main() {
    let name = "world";
    println_stderr!("Hello {}!", name)
}

答案 1 :(得分:19)

print!println!是写入标准输出的便捷方法。还有其他宏具有相同的格式化功能可用于不同的任务:

要写入标准错误流,您可以使用例如writeln!喜欢这样:

use std::io::Write;

fn main() {
    let mut stderr = std::io::stderr();
    writeln!(&mut stderr, "Error!").unwrap();
}

答案 2 :(得分:3)

它已经这样做了:

use std::io::Write;

fn main() {
    std::io::stderr().write(b"some output\n");
}

您可以通过将程序输出发送到/dev/null来测试它,以确保它有效(我忽略警告):

$ rustc foo.rs && ./foo > /dev/null
foo.rs:4:5: 4:42 warning: unused result which must be used, #[warn(unused_must_use)] on by default
foo.rs:4     io::stderr().write(b"some output\n");
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
some output

同样,可以为stdout执行以下操作:

use std::io::Write;

fn main() {
    std::io::stdout().write(b"some output\n");
}

我认为这意味着println!只是一种便利:它更短,也允许一些格式化。作为后者的示例,以下显示0x400

println!("0x{:x}", 1024u)

答案 3 :(得分:3)

虽然没有回答准确的问题,但可能感兴趣的是有一个stderr箱子,它指定了其他箱子(例如#[macro_use] extern crate log; extern crate env_logger; fn main() { env_logger::init().unwrap(); error!("this is printed by default"); } )可以实现的水平测井的界面。

此类日志记录的输出将发送到import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.stream.Collectors; public class CollapseConsecutiveCharsDemo { public static String collapse(final String term) { final StringBuilder buffer = new StringBuilder(); if (!term.isEmpty()) { char prev = term.charAt(0); buffer.append(prev); for (int i = 1; i < term.length(); i += 1) { final char curr = term.charAt(i); if (curr != prev) { buffer.append(curr); prev = curr; } } } return buffer.toString(); } public static void main(final String... documents) { final Map<String, Set<String>> termVariations = new TreeMap<>(); for (final String document : documents) { final Scanner scanner = new Scanner(document.toLowerCase()); while (scanner.hasNext()) { final String expandedTerm = scanner.next(); final String collapsedTerm = collapse(expandedTerm); Set<String> variations = termVariations.get(collapsedTerm); if (null == variations) { variations = new TreeSet<String>(); termVariations.put(collapsedTerm, variations); } variations.add(expandedTerm); } } for (final Map.Entry<String, Set<String>> entry : termVariations.entrySet()) { final String term = entry.getKey(); final Set<String> variations = entry.getValue(); System.out.printf("variations(\"%s\") = {%s}%n", term, variations.stream() .map((variation) -> String.format("\"%s\"", variation)) .collect(Collectors.joining(", "))); } } } ,并为用户提供其他好处,例如指定日志级别。

这就是使用这种记录器的方式:

% java CollapseConsecutiveCharsDemo "We had an awwweesssommmeeee dinner at sea resort" "We had an awesomeeee dinner at sea resort" "We had an awwesooomee dinner at sea resort"
variations("an") = {"an"}
variations("at") = {"at"}
variations("awesome") = {"awesomeeee", "awwesooomee", "awwweesssommmeeee"}
variations("diner") = {"dinner"}
variations("had") = {"had"}
variations("resort") = {"resort"}
variations("sea") = {"sea"}
variations("we") = {"we"}

(示例改编自http://burntsushi.net/rustdoc/env_logger/index.html#example

答案 4 :(得分:0)

目标

stderr!("Code {}: Danger, Will Robinson!  Danger!", 42);

注释

其他答案会产生一个未使用的导入警告,并且每晚发布一次,所以这里是Just Works TM的现代宏。

代码

macro_rules! stderr {
    ($($arg:tt)*) => (
        use std::io::Write;
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr (file handle closed?): {}", x),
        }
    )
}