ARAVINDA VISHWANATHAPURA

isatty in Rust

Dec 16, 2014
1 minute read.
rust cli

How to find a command line program is piped from another program or that program was running directly with arguments? For example, wc command can be run as both ways.

# Create a file /tmp/hello.txt
echo "Hello World" > /tmp/hello.txt
# wc can be used as both ways,
cat /tmp/hello.txt | wc
# or
wc /tmp/hello.txt

In Python, it is very easy to identify how a command is run

import sys

if sys.stdin.isatty():
    filename = sys.argv[1]
    # do something with file, open the file and process it
else:
    # use for `line in sys.stdin` to read line by line
    data = sys.stdin.read()
    # do something with data

How to do this in Rust?

It is very easy in Rust too, see…​

use std::io;

fn main(){
    if io::stdio::stdin_raw().isatty(){
        println!("Not pipe");
    }
    else{
        let mut reader = io::stdin();
        loop{
            match reader.read_line() {
                Ok(txt) => println!("Read: {}", txt),
                Err(_e) => break
            }
        }
    }
}

To handle all the errors except EOF,

let mut reader = io::stdin();
loop{
    match reader.read_line() {
        Ok(txt) => println!("Read: {}", txt),
        Err(e) => match e.kind{
            io::EndOfFile => break,
            _ => {
                    panic!("ERROR: {}", e);
            }
        }
    }
}

We can now create pipe aware applications easily in Rust, let me know if you find this useful.

btw, Rust 1.0 is coming, see here

(Code examples here were built with "rustc 0.13.0-nightly (126db549b 2014-12-15 00:07:35 +0000)")

About Aravinda Vishwanathapura

Co-Founder & CTO at Kadalu Technologies, Creator of Sanka, Creator of Chitra, GlusterFS core team member, Maintainer of Kadalu Storage
Contact: Linkedin | Twitter | Facebook | Github | mail@aravindavk.in