$30 off During Our Annual Pro Sale. View Details »

Workshop: Write Your Own Shell in Rust

Workshop: Write Your Own Shell in Rust

One of the things developers use every day is a shell. It comes in many flavors, like bash, fish or zsh. Depending on your background, writing your own shell from scratch might either sound intimidating or pointless. We like to believe that it can be a fun way to gain more hands-on Rust experience. If you want to play with concepts like I/O, error handling, and syscalls, we invite you to participate in this workshop. Who knows, it could also be an opportunity to start your first mid-size Rust project!

Matthias Endler

October 19, 2018
Tweet

More Decks by Matthias Endler

Other Decks in Programming

Transcript

  1. Write your own shell in Rust!
    Santiago Pastorino • Matthias Endler Rust Belt Rust Workshop 2018
    Special Guest: Alex Crichton

    View Slide

  2. About us
    Santiago Pastorino
    ● WyeWorks co-founder
    ● Ruby on Rails core team alumni
    ● Started with Rust in 2017
    ● Member of Rust compiler NLL WG
    ● Rust Latam conference organizer
    ● Rust Montevideo Meetup organizer
    Matthias Endler
    ● Started with Rust in 2015
    ● Member of the Rust Cologne Meetup
    ● Runs Hello Rust YouTube channel

    View Slide

  3. About the Workshop
    Goals
    ● Learn some Rust
    ● Intermediate concepts
    ● Work on your first Rust project
    Structure
    ● 6 hours total
    ● split up into five blocks
    ● roughly one hour per block

    View Slide

  4. Schedule

    View Slide

  5. Executing a Single
    Shell Command
    Block 2
    Executing
    Multiple
    Commands
    Block 3
    Implementing
    Shell-Builtins
    Block 4
    Implementing
    Pipes
    Block 5
    Bring Your Own
    Features ✨
    Block 1
    Setup Rust

    View Slide

  6. Block 0 - Check your (nightly) Rust installation
    Main objective
    ● Install nightly Rust using rustup or
    any other way.
    ● Run `rustc -V` to see if you’re
    golden.

    View Slide

  7. Block 1 - Executing a Single Shell Command
    Main objectives
    ● Write a shell which can run a single
    command on a separate process.
    ● Hint: Look for APIs in the standard
    library to do that.
    ● Print the output to stdout.
    Bonus track
    ● Write some unit tests to make sure
    that the shell works.
    ● Make the code as idiomatic as
    possible.

    View Slide

  8. Block 1 - Pseudo Code
    fn main() {
    loop {
    // Read line from standard input
    // “Parse” line into executable command
    // Execute the command in a separate process
    // Show output
    }
    }

    View Slide

  9. Block 1 - Repository
    https://gitlab.com/mre_/rush
    mre_

    View Slide

  10. Block 2 - Executing Multiple Commands
    Main objectives
    ● Try to run two or more commands
    separated by ; in sequence.
    ● Print all output in sequence to
    stdout.
    Bonus track
    ● Implement && and ||
    ● Write an integration test.
    Share solutions here: http://tiny.cc/rustlang2
    Repository: https://gitlab.com/mre_/rush

    View Slide

  11. Block 2 - Executing Multiple Commands (Examples)
    > echo 1; echo 2
    1
    2
    > true && echo "output"
    output
    > false && echo "output"
    >
    > true || echo "output"
    > false || echo "output"
    output
    >
    Main objectives Bonus track
    Share solutions here: http://tiny.cc/rustlang2
    Repository: https://gitlab.com/mre_/rush
    tiny.cc/rust-slides

    View Slide

  12. Block 3 - Implementing Shell-Builtins
    Main objectives
    ● Implement the `cd` shell builtin.
    ● Implement the `exit` shell builtin.
    Bonus track
    ● Implement `exec` builtin

    View Slide

  13. Block 3 - Implementing Shell-Builtins (Examples)
    > pwd
    /dir1
    > cd /dir2
    > pwd
    /dir2
    > exit
    (Shell gets closed)
    > exec fish
    Welcome to fish, the friendly
    interactive shell
    Main objectives Bonus track
    Share solutions here: http://tiny.cc/rustlang2
    Repository: https://gitlab.com/mre_/rush

    View Slide

  14. Block 4 - Implementing Pipes
    Main objectives
    ● Implement pipes, which are a way
    to feed the output of one command
    into another one.
    Syntax:
    command1|command2
    Bonus track
    ● Support multiple pipes:
    c1 | c2 | c3
    ● Add redirection:
    c1 > output.txt
    ● Think about ways to make
    command representation more
    idiomatic.

    View Slide

  15. Block 4 - Implementing Pipes (Examples)
    > echo foo | grep -c foo
    1
    Main objectives Bonus track
    > ps auxwww | grep fred | more
    > echo 1 > test.txt

    View Slide

  16. Block 5 - Bring Your Own Features!
    Main objectives
    ● It’s all free-style from here.
    What will you do next?
    ○ Readline support
    ○ Control signals
    ○ Command completion
    ○ use a grammar for parsing
    ○ Implement more shell-builtins
    ○ Surprise us!
    Bonus track
    ● Get ✨ inspired ✨ by looking at
    existing shells, e.g.
    ○ ion (Rust)
    ○ elvish (Go)
    ○ “the other rush” (Rust)

    View Slide