Skip to main content
This tutorial will walk you through Nash’s core features with practical examples. You’ll learn how to use the interactive REPL, run commands, work with files, and leverage Nash’s security features.

Prerequisites

Make sure you have installed Nash before proceeding.

Start the Interactive REPL

1

Launch Nash

Open your terminal and start Nash in interactive mode:
nash
You’ll see the welcome banner:
Nash — Not A Shell  │  logged in as user  │  type help or Ctrl-D to exit

user@nash:/home/user$
The prompt shows your username, hostname (nash), and current directory. It looks like a real shell!
2

Explore your environment

Check where you are and what’s available:
user@nash:/home/user$ pwd
/home/user

user@nash:/home/user$ ls
Desktop/  Documents/  Downloads/  welcome.txt

user@nash:/home/user$ ls -la
total 4
drwxr-xr-x  Desktop/
drwxr-xr-x  Documents/
drwxr-xr-x  Downloads/
-rw-r--r--  welcome.txt
Everything you see exists only in memory — your real home directory is untouched.
3

View available commands

Nash includes 28 built-in commands. Get help:
user@nash:/home/user$ help
Or check if a specific command exists:
user@nash:/home/user$ which grep
grep: nash builtin

user@nash:/home/user$ which bash
bash: not found
Nash only has built-in commands. It cannot execute system binaries like /bin/bash or /usr/bin/python.

Working with Files and Directories

1

Create a project directory

Let’s create a workspace:
user@nash:/home/user$ mkdir -p projects/demo
user@nash:/home/user$ cd projects/demo
user@nash:/home/user/projects/demo$ pwd
/home/user/projects/demo
The -p flag creates parent directories automatically, just like regular mkdir.
2

Create and edit files

Write some content to files:
user@nash:/home/user/projects/demo$ echo "Hello from Nash!" > greeting.txt
user@nash:/home/user/projects/demo$ cat greeting.txt
Hello from Nash!

user@nash:/home/user/projects/demo$ echo "Second line" >> greeting.txt
user@nash:/home/user/projects/demo$ cat greeting.txt
Hello from Nash!
Second line
  • > overwrites the file
  • >> appends to the file
3

Copy and move files

Organize your files:
user@nash:/home/user/projects/demo$ cp greeting.txt backup.txt
user@nash:/home/user/projects/demo$ ls
backup.txt  greeting.txt

user@nash:/home/user/projects/demo$ mkdir archive
user@nash:/home/user/projects/demo$ mv backup.txt archive/
user@nash:/home/user/projects/demo$ tree
.
├── archive/
   └── backup.txt
└── greeting.txt

Using Pipes and Text Processing

1

Create sample data

Generate some test data:
user@nash:/home/user/projects/demo$ cat > fruits.txt
apple
banana
apple
cherry
banana
date
apple
^D
Press Ctrl-D to finish input when using cat without a filename.
2

Filter with grep

Search for patterns:
user@nash:/home/user/projects/demo$ grep apple fruits.txt
apple
apple
apple

user@nash:/home/user/projects/demo$ grep -v apple fruits.txt
banana
cherry
banana
date
The -v flag inverts the match (show non-matching lines).
3

Sort and count unique items

Process data with pipes:
user@nash:/home/user/projects/demo$ cat fruits.txt | sort | uniq
apple
banana
cherry
date

user@nash:/home/user/projects/demo$ cat fruits.txt | sort | uniq -c
      3 apple
      2 banana
      1 cherry
      1 date
4

Use sed for transformation

Replace text with sed:
user@nash:/home/user/projects/demo$ cat fruits.txt | sed 's/apple/orange/g'
orange
banana
orange
cherry
banana
date
orange
The s/old/new/g pattern replaces all occurrences.

Command Chaining and Logic

1

Chain commands with && and ||

Execute commands conditionally:
user@nash:/home/user/projects/demo$ mkdir output && echo "Success!" > output/status.txt
user@nash:/home/user/projects/demo$ cat output/status.txt
Success!

user@nash:/home/user/projects/demo$ test -f missing.txt || echo "File not found"
File not found

user@nash:/home/user/projects/demo$ test -f greeting.txt && echo "File exists"
File exists
  • && runs the second command only if the first succeeds
  • || runs the second command only if the first fails
2

Use command substitution

Embed command output in other commands:
user@nash:/home/user/projects/demo$ echo "Current directory: $(pwd)"
Current directory: /home/user/projects/demo

user@nash:/home/user/projects/demo$ echo "File count: $(ls | wc -l)"
File count: 4

user@nash:/home/user/projects/demo$ touch file_$(date).txt
# Creates a file with the current date
3

Use subshells for isolation

Subshells keep environment changes contained:
user@nash:/home/user/projects/demo$ pwd
/home/user/projects/demo

user@nash:/home/user/projects/demo$ (cd /tmp && pwd)
/tmp

user@nash:/home/user/projects/demo$ pwd
/home/user/projects/demo
The cd inside () doesn’t affect the outer shell.

Working with Host Directories

1

Exit Nash and create a test directory

Press Ctrl-D to exit Nash, then create a directory on your real filesystem:
mkdir ~/nash-demo
echo "This is a real file" > ~/nash-demo/real.txt
2

Mount the directory in Nash

Start Nash with a bind mount:
nash --bind ~/nash-demo:/data
The --bind flag (or -B) mounts a host directory into the VFS at the specified path.
3

Access mounted files

Navigate to the mounted directory:
user@nash:/home/user$ cd /data
user@nash:/data$ ls
real.txt

user@nash:/data$ cat real.txt
This is a real file

user@nash:/data$ echo "Added from Nash" >> real.txt
user@nash:/data$ cat real.txt
This is a real file
Added from Nash
Exit Nash and verify the file was modified:
user@nash:/data$ exit
$ cat ~/nash-demo/real.txt
This is a real file
Added from Nash
Write access to mounted directories modifies real files! Use --bind-ro for read-only access.
4

Use read-only mounts

Mount directories as read-only for safety:
nash --bind-ro ~/nash-demo:/data
user@nash:/home/user$ cd /data
user@nash:/data$ cat real.txt
This is a real file
Added from Nash

user@nash:/data$ echo "Try to modify" >> real.txt
nash: filesystem is read-only: /data/real.txt

Running Shell Scripts

1

Create a shell script

Exit Nash and create a script file:
cat > process-data.sh << 'EOF'
#!/usr/bin/env nash

# Create a report directory
mkdir -p reports

# Generate sample data
echo "Processing data..."
echo "apple" > data.txt
echo "banana" >> data.txt
echo "cherry" >> data.txt
echo "apple" >> data.txt

# Process and create report
cat data.txt | sort | uniq -c > reports/summary.txt

echo "Report generated:"
cat reports/summary.txt
EOF

chmod +x process-data.sh
2

Execute the script

Run the script with Nash:
nash process-data.sh
Output:
Processing data...
Report generated:
      2 apple
      1 banana
      1 cherry
All files created by the script exist only in Nash’s VFS. Your real filesystem is not affected unless you use --bind.
3

Run with host directory access

Mount a directory to save output:
mkdir ~/output
nash --bind ~/output:/reports process-data.sh
Now the report is saved to your real ~/output/summary.txt file.

Advanced Features

Process JSON Data

Nash includes a built-in jq implementation:
user@nash:/home/user$ echo '{"name":"Nash","version":"0.1.0","features":["vfs","sandbox"]}' > info.json

user@nash:/home/user$ cat info.json | jq .name
"Nash"

user@nash:/home/user$ cat info.json | jq .features
["vfs","sandbox"]

user@nash:/home/user$ cat info.json | jq 'keys'
["features","name","version"]

Use Shell Variables

user@nash:/home/user$ export PROJECT_NAME="MyApp"
user@nash:/home/user$ echo "Working on $PROJECT_NAME"
Working on MyApp

user@nash:/home/user$ env | grep PROJECT
PROJECT_NAME=MyApp

Set Shell Options

Run scripts with debugging:
nash -x script.sh          # Print each command before executing
nash -e script.sh          # Exit immediately on error
nash -u script.sh          # Error on unset variables

Run Multiple Users

Create different user environments:
nash -U alice              # Logged in as alice, home at /home/alice
nash -U bob -C /projects   # Logged in as bob, starting in /projects

Tips and Tricks

Navigation shortcuts:
  • cd — go to home directory
  • cd - — go to previous directory
  • cd ~ — go to home directory
Combine multiple mounts:
nash -B ./src:/src -B ./data:/data --bind-ro ./config:/config -C /src
This mounts three directories and starts in /src.
Use environment variables for configuration:
nash -E DEBUG=true -E API_URL=http://localhost:8080 script.sh

What’s Next?

You now know the basics of Nash! Here are some next steps:

CLI Reference

Learn about all available command-line flags and options

Built-in Commands

Explore the full list of 28 built-in commands

Shell Syntax

Deep dive into pipes, redirections, and advanced syntax

Security Model

Understand how Nash provides sandboxing guarantees

Getting Help

  • Type help in the Nash REPL for command reference
  • Use which <command> to check if a command is available
  • Press Ctrl-D or type exit to quit Nash
  • Visit the GitHub repository for issues and discussions

Build docs developers (and LLMs) love