web-dev-qa-db-fra.com

Comment envoyer une sortie à stderr?

On l'utilise pour envoyer la sortie à stdout:

println!("some output")

Je pense qu'il n'y a pas de macro correspondante pour faire de même pour stderr.

39
Tshepang

Après Rust 1.19

Depuis Rust 1.19, vous pouvez utiliser les macros eprint et eprintln :

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

Cela a été initialement proposé dans RFC 1896 .

Avant Rust 1.19

Vous pouvez voir le implémentation de println! pour me plonger dans son fonctionnement, mais c'était un peu écrasant lorsque je l'ai lu pour la première fois.

Vous pouvez formater des trucs en stderr en utilisant des macros similaires cependant:

use std::io::Write;

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

Cela vous donnera un unused result which must be used avertissement cependant, car l'impression vers IO peut échouer (ce n'est pas quelque chose auquel nous pensons habituellement lors de l'impression! Nous pouvons voir que les méthodes existantes simplement paniquer dans ce cas, nous pouvons donc mettre à jour notre code pour faire de même:

use std::io::Write;

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

C'est un peu trop, alors récapitulons-le dans une macro:

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)
}
69
Shepmaster

print! et println! sont des méthodes pratiques pour écrire sur la sortie standard. Il existe d'autres macros avec les mêmes fonctionnalités de formatage disponibles pour différentes tâches:

Pour écrire dans le flux d'erreur standard, vous pouvez utiliser par exemple writeln! comme ça:

use std::io::Write;

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

C'est fait ainsi:

use std::io::Write;

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

Vous pouvez le tester en envoyant la sortie du programme à /dev/null pour vous assurer que cela fonctionne (j'ignore l'avertissement):

$ 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

De même, on peut faire ce qui suit pour stdout:

use std::io::Write;

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

Je pense que cela signifie println! n'est qu'une commodité: il est plus court et permet également une mise en forme. À titre d'exemple de ce dernier, ce qui suit affiche 0x400:

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

Sans répondre à la question précise, il est peut-être intéressant de noter qu'il existe une caisse log qui spécifie une interface pour la journalisation à niveau que les autres caisses (par exemple env_logger) peut remplir.

La sortie de cette journalisation sera envoyée à stderr, et il y a des avantages supplémentaires pour les utilisateurs, comme la spécification du niveau de journalisation.

Voici à quoi pourrait ressembler un tel enregistreur:

#[macro_use]
extern crate log;
extern crate env_logger;

fn main() {
    env_logger::init().unwrap();
    error!("this is printed by default");
}

(Exemple adapté de http://burntsushi.net/rustdoc/env_logger/index.html#example )

3
Michael

Objectif

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

Remarques

Les autres réponses génèrent un avertissement d'importation inutilisé avec la dernière version nocturne, alors voici une macro moderne qui fonctionne Just TM.

Code

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),
        }
    )
}
0
user246672