3 min read

Unix shell

A console application with much of the same functionality as a simple Unix shell.

Introduction

This project is really two projects grouped together, one in C and one in Rust. Both projects do the same thing, i.e. they are both Unix shells. The C project is called flush and the Rust project is called crabshell. The C project is the original project, and the Rust project is a rewrite of the C project in order to learn more about Rust.

Features

The application supports executables in your PATH (e.g. ls, cd, etc...) using execvp and interprocess communication (IPC).

It also supports I/O redirection (i.e. < and >) of stdin and stdout using dup2.

Additionally, it supports background tasks of commands ending in &, with an overview using a custom implementation of the jobs command.

Lastly, it supports pipelines using inter-process communication, pipe, dup2, and exec.

Below are some of the commands that are supported:

# Execute some system call ls -l echo "Hello, world!" sleep 2 # Change directory cd .. cd ~ # IO redirection ls -l > out.txt head -1 < README.md head -1 < README.md > out.txt # Start a background task ls -l > out.txt & sleep 10 & # Get an overview of all background tasks jobs # Pipelines ls -l | grep flush | wc -w ls -l | grep flush > out.txt # Terminate the program using CTRL + D

Differences between the developer experience of C and Rust

Memory safety and management

C is a low-level language that does not have a garbage collector or other automatic memory management features. This means that it is the responsibility of the programmer to manually manage memory, which can be error-prone and lead to difficult-to-debug issues such as buffer overflows and segmentation faults. In contrast, Rust has a number of features that help ensure memory safety, such as static borrowing and ownership, which can make it easier to write correct and efficient code.

Syntax and expressiveness

C has a relatively simple and minimalistic syntax, which can make it easy to learn and understand. However, this simplicity can also make it harder to express complex concepts or abstractions in C. Rust, on the other hand, has a more expressive syntax that includes features such as pattern matching and trait-based generics, which can make it easier to write code that is both readable and expressive.

Tooling and ecosystem

C has a long history and a large and mature ecosystem, with a wide range of tools and libraries available. Rust is a relatively newer language, but it has a growing and active community, and its ecosystem is expanding quickly, with a number of high-quality libraries and tools available.

Additionally, the Cargo package manager for Rust is a powerful tool that can make it easier to build, test, and publish Rust projects.

Error handling

C does not have a built-in mechanism for handling errors, which means that it is up to the programmer to decide how to handle errors. This can make it difficult to write code that is both correct and efficient. Rust, on the other hand, has a number of features that can make it easier to write correct and efficient code, including the Result type, which can be used to represent the possibility of an error, and the ? operator, which can be used to propagate errors.

Read more

Read more about flush and crabshell by clicking their respective links.