Shell scripts,
in plain English.
aish reads a script line by line. Each line is a natural-language instruction. Claude drives bash to make it happen — with variables, loops, conditionals, and everything you'd expect.
curl -fsSL https://www.ai-sh.net/install.sh | sh
What a script looks like
#!/usr/bin/env aish ask "Which host?" as $host shell ssh ${host} systemctl is-active nginx from the previous output, save "up" or "down" as $state if ${state} == "down": restart nginx on ${host} and confirm it's serving print "${host}: recovered" else: print "${host}: healthy" end
? Which host? web1 $host = web1 [line 4 shell] $ ssh web1 systemctl is-active nginx inactive from the previous output, save "up" or "down" as $state $ echo "down" $state = down Captured state = down (nginx is inactive). -- if ${state} == "down" → true -- restart nginx on web1 and confirm it's serving $ ssh web1 sudo systemctl start nginx && ... nginx restarted, HTTP 200 from /. web1: recovered
#!/usr/bin/env aish shell du -sh ~/Downloads/* | sort -hr | head -3 from the previous output, save the biggest file's path as $target and size as $size ask "Delete ${target} (${size})?" as $ok if ${ok} == "yes": shell rm -rf "${target}" print "deleted ${target}" else: print "kept" end
[line 3 shell] $ du -sh ~/Downloads/* | sort -hr | head -3 4.2G /Users/you/Downloads/old-backup.tar.gz 1.8G /Users/you/Downloads/dataset.zip 420M /Users/you/Downloads/screencast.mov from the previous output, save the biggest file's path... $target = /Users/you/Downloads/old-backup.tar.gz $size = 4.2G Saved target and size from the top row. ? Delete /Users/you/Downloads/old-backup.tar.gz (4.2G)? yes $ok = yes -- if ${ok} == "yes" → true -- [line 10 shell] $ rm -rf "/Users/you/Downloads/old-backup.tar.gz" deleted /Users/you/Downloads/old-backup.tar.gz
#!/usr/bin/env aish # ./hosts.aish --var hosts=web1,web2,web3 for $h in ${hosts}: ssh ${h} and get /var disk use percentage as number, save as $pct if ${pct} > 85: print "${h}: WARNING ${pct}%" else: print "${h}: ok (${pct}%)" end end
-- for $h = web1 -- $ ssh web1 "df /var | awk 'NR==2 {gsub(/%/,\"\"); print $5}'" 68 $pct = 68 -- if ${pct} > 85 → false -- web1: ok (68%) -- for $h = web2 -- $ ssh web2 "..." 92 $pct = 92 -- if ${pct} > 85 → true -- web2: WARNING 92% -- for $h = web3 -- $ ssh web3 "..." 41 $pct = 41 -- if ${pct} > 85 → false -- web3: ok (41%)
#!/usr/bin/env aish run lsblk and find the drive that is 10.9T, save as $drive mount ${drive} at /mnt/media and verify it's writable print "mounted ${drive} at /mnt/media"
run lsblk and find the drive that is 10.9T, save as $drive $ lsblk -o NAME,SIZE,TYPE | grep disk sda 2T disk sdb 10.9T disk ← match $drive = /dev/sdb Saved $drive = /dev/sdb (the 10.9T disk). mount ${drive} at /mnt/media and verify it's writable $ mkdir -p /mnt/media && mount /dev/sdb /mnt/media $ touch /mnt/media/.wtest && rm /mnt/media/.wtest Mounted and writable. mounted /dev/sdb at /mnt/media
$ aish aish repl — Ctrl-D or 'exit' to quit aish> how many processes am I running? $ ps -A | wc -l You're running 412 processes. aish> which three are using the most memory? $ ps -A -o pid,comm,%mem --sort=-%mem | head -4 Top three by memory: WindowServer (6.4%), Google Chrome Helper (4.1%), Code Helper (3.0%). aish> kill the google chrome helper that's using the most memory $ ps -A -o pid,comm,%mem --sort=-%mem | grep "Chrome Helper" | head -1 47218 Google Chrome Helper 4.1 $ kill 47218 Killed PID 47218. aish> exit
Natural-language shell. Type what you want; Claude figures out the command, runs it, and reads the output.
Context persists. Line 2 knew which process to kill because line 1 had already pulled the top-memory list.
Variables carry over. Anything you capture via set_var or ask is still there on your next line.
Multi-line blocks buffer. Open a for or if; the prompt indents until end closes it.
What's in the box
Bash tool
Claude picks the right shell command to run for each instruction, reads the output, and chains follow-ups.
Variables
Preset with --var, capture with set_var, or write ask "prompt" as $x. Runtime vars are also exported into bash.
Control flow
for, if/else, and end — decided by the runtime, not the LLM. Deterministic branching over discovered lists.
Shell + print
shell "<cmd>" runs a fixed command and injects the output into context. print writes straight to your terminal — zero LLM cost.
Interactive REPL
Run aish with no args for a natural-language shell. Same tools, same variables, same context.
Shebang scripts
#!/usr/bin/env aish + chmod +x. Your .aish files run like any other executable.
Direct downloads
Or use the install script above. Binaries are static Go builds — no runtime dependencies.
Try it in ten seconds
curl -fsSL https://www.ai-sh.net/install.sh | sh
Requires an Anthropic API key. Store it in an aish.json file next to the binary — e.g. /usr/local/bin/aish.json on macOS/Linux, or C:\Program Files\aish\aish.json on Windows. The ANTHROPIC_API_KEY env var works too.