book icon indicating copy to clipboard operation
book copied to clipboard

Book: Output for machines

Open killercup opened this issue 7 years ago โ€ข 9 comments

Add an in-depth chapter that talks about how to

  • [x] detect if our output is piped into another program (or file)
  • [x] format output for other programs
  • [ ] work with output that is piped into us

killercup avatar Nov 18 '18 21:11 killercup

Ideally, this will also mention https://github.com/killercup/convey once it becomes more stable!

killercup avatar Nov 18 '18 21:11 killercup

Would contributions for the "work with output that is piped into us" section be welcome? I'm working on learning that now and would be happy to contribute to the book.

brettchalupa avatar Sep 29 '22 12:09 brettchalupa

Sure! I'd recommend discussing the direction you want to take that here before committing too much time to the full write up so we can make sure we are all on the same page.

epage avatar Sep 29 '22 14:09 epage

Here's what I'm thinking... I also acknowledge I could be wildly off-base with this and that it might not be idiomatic or okay. ๐Ÿ˜„

How to deal with input piped into us

Rust programs can read data passed in via stdin, whether that's through piping or text entered while the program is running. Rust's standard library provides us with std::io::stdin that can read the lines passed in.

Here's a program that counts the words in all of the lines of what's passed in via stdin:

use std::io::stdin;

fn main() {
    let mut total_word_count = 0;

    for line in stdin().lines() {
        let line = line.unwrap();
        if !line.trim().is_empty() {
            total_word_count += line.split(' ').count();
        }
    }

    println!("Total words from stdin: {}", total_word_count)
}

If you run that program with text piped in, it'll output the word count:

$ echo "hi there friend\!" | cargo run --
Total words from stdin: 3

Something that may seem strange is that if you run the program with just cargo run--, nothing is displayed but you can enter text. This approach to reading stdin is a blocking behavior. If you enter data and press Ctrl+D (sends an End of File (EOF) signal to stdin), it'll output the word count. Nifty!

$ cargo run --
Hello there.
My name is Brett!
^D
Total words from stdin: 6

(edited to remove copy-paste remnants from a vim plugin, whoops!)

brettchalupa avatar Sep 29 '22 21:09 brettchalupa

I'd recommend checking out clig for what it says on reading from standard in and incorporate how to accomplish that.

Something that may seem strange is that if you run the program with just cargo run--, nothing is displayed but you can enter text.

I'd reframe this to "This also works interactively..."

epage avatar Sep 29 '22 21:09 epage

@epage thanks for the link to clig, that's a really helpful resource.

Just to break down what I'm understanding from it.

Display help and exit w/ no args

If your command is expecting to have something piped to it and stdin is an interactive terminal, display help immediately and quit. This means it doesnโ€™t just hang, like cat. Alternatively, you could print a log message to stderr.

Use the - arg to specify reading from stdin

If input or output is a file, support - to read from stdin or write to stdout. This lets the output of another command be the input of your command and vice versa, without using a temporary file. (with tar example) $ curl https://example.com/something.tar.gz | tar xvf -

Interactively word change

Sounds good ๐Ÿ‘


Does that capture it all for the edits? If it seems worth contributing, I'll gladly move all of this into a PR.

brettchalupa avatar Oct 02 '22 01:10 brettchalupa

We probably don't want to just quote those but show the user how to accomplish them

epage avatar Oct 03 '22 22:10 epage

@epage I was just sharing the quotes to make sure I'm understanding your feedback. I'll rework the source above and write about them in the contribution. ๐Ÿ‘ Am I good to head off into PR land with the write up?

brettchalupa avatar Oct 04 '22 11:10 brettchalupa

Yes, sounds good

epage avatar Oct 04 '22 13:10 epage