🐚 Yash (Yet Another SHell) — Enhanced Cheatsheet & Snippets
Yash is a POSIX-compliant shell (version 2.60, September 2025) with extra features for usability. (magicant.github.io) It strives to adhere strictly to POSIX.1-2024 (with a few documented exceptions) while providing interactive niceties. (magicant.github.io)
🚀 Invocation & Initialization
- Invocation syntax:
yash [options] [script [args…]](magicant.github.io) Important options:
-c 'cmd': run the command string-s: read commands from standard input-i/+i: force interactive / non-interactive mode-l: treat shell as login shell- (Some options related to skipping rc files, debugging, etc.)
- Note: the
-o nologoption is not supported (it is silently ignored). (GitHub)
Init files
- If started as a login shell, Yash reads
$XDG_CONFIG_HOME/yash/profileor fallback~/.yash_profile. (GitHub) - For interactive use, after that it reads
$XDG_CONFIG_HOME/yash/rcor~/.yashrc. (GitHub) - In those rc/profile files, you can set environment variables, aliases, prompt, key bindings, and command-not-found handler. (GitHub)
🔤 Syntax, Expansions & Word Processing
Yash implements the full shell grammar (tokens, quoting, pipes, lists, compound commands) as described in the manual. (magicant.github.io)
Some highlights:
- Dollar-single-quotes:
\$'…'is supported, letting you embed special characters literally. (magicant.github.io) - Aliases: Global alias support is built in (you can alias a word globally, not just first word). (GitHub)
- Arrays: Yash supports indexed arrays as an extension. (GitHub)
- Brace expansion and extended globbing are supported (beyond minimal POSIX). (GitHub)
- Arithmetic expansion is richer: supports fractional numbers,
++,--, assignments etc. (GitHub) - Pathname expansion includes extensions; results are sorted by locale collation order. (GitHub)
- Word splitting, tilde expansion, parameter expansion, command substitution all follow standard shell semantics. (magicant.github.io)
🔂 Control Flow & Functions
if,while,until,for,caseall behave per POSIX. (magicant.github.io)- Arithmetic
for ((…))loops are supported. (magicant.github.io) - Function definitions: standard shell style (
name () { …; }) are supported. (magicant.github.io) - Local variables within functions:
localis available. (magicant.github.io)
📦 Built-in Commands & Utilities
Yash has a rich set of built-ins (some are extensions). Here are key ones to know: (from manual list) (magicant.github.io)
- Execution / control:
exec,eval,.,command,exit,return,break,continue - Variable & parameter:
set,shift,export,readonly,unset,typeset,array(extension) - Aliases etc:
alias,unalias - Job control:
jobs,fg,bg,disown,wait,kill - Directory stack:
cd,pwd,pushd,popd,dirs - I/O & formatting:
echo,printf,read - Others:
getopts,trap,umask,ulimit, etc.
Of note: array is an extension (not in strict POSIX) for array operations. (magicant.github.io)
🔁 Redirection & I/O Features
Yash supports an extended suite of redirection capabilities:
- Standard redirections:
>,>>,<,<<(here documents) - Socket redirection: redirect to/from Unix domain sockets etc. (magicant.github.io)
- Pipeline redirection: more control over pipe endpoints
- Process redirection: e.g. redirecting via processes
- Duplication / closing of file descriptors:
n>&m,n<&m,n>&-etc. - Here-strings, here-documents, and advanced combinations.
- Note: sorting of pathname expansion is based on locale collation; if the locale ordering is non-total, order may be unstable. (GitHub)
💡 Interactive Features: Prompts, Line Editing, Completion, Prediction
One of Yash’s strengths is its interactive mode. Some highlights:
Editing modes & key bindings
- Supports Vi mode and Emacs mode for line editing. (Switchable via
set -o vi/set -o emacs) (DeepWiki) - Key bindings are customizable with
bindkey. (DeepWiki) - You can remap keys in specific modes (insert, command, etc.). (DeepWiki)
Command History
- Stored in memory, optionally saved to a file (via
HISTFILE) - Use up/down keys (or Vi keys) to move through history
Ctrl-r/Ctrl-sfor reverse/forward search- Variables:
HISTFILE,HISTSIZE,HISTRMDUPcontrol history behavior. (DeepWiki)
Completion & Custom Completion
- Press Tab to complete commands, filenames, variables, etc. (DeepWiki)
- Context-aware completion: depending on where completion is triggered (command position, argument, redirection target, variable context) (DeepWiki)
- The
completebuilt-in lets you define custom completion logic. (magicant.github.io)
Command Prediction
- With
-o le-predict, Yash can show predicted completions (based on historical usage) as dimmed text while you type. (DeepWiki) - Internally uses a trie built from command history to suggest the most probable continuation. (DeepWiki)
🎨 Fun Snippets & Tricks
Here are a few playful or useful snippets to highlight Yash’s features:
1. Fractional arithmetic & loop
# loop in steps of 0.5
for (( x = 0.0; x < 2.0; x += 0.5 )); do
printf "x = %.1f\n" "$x"
done
This works because Yash supports fractional arithmetic.
2. Brace expansion dance
echo file{1..3}.txt
# expands to: file1.txt file2.txt file3.txt
echo {a,b,c}{X,Y}
# aX aY bX bY cX cY
You can combine braces and patterns smartly.
3. Redirect to a socket (pseudo-example)
# Suppose /tmp/mysock is a Unix domain socket
echo "hello" > /tmp/mysock
# or read from a socket:
cat < /tmp/mysock
(Assuming a service is listening on that socket)
4. Simple co-process echo filter
coproc f { awk '/foo/' ; }
printf "foo\nbar\nfoo\nbaz\n" >&"${f[1]}"
while read line <&"${f[0]}"; do
echo "Matched: $line"
done
exec {f[0]}<&-
exec {f[1]}>&-
Filters lines containing foo using a co-process.
5. Smart prompt with execution status
In your ~/.yashrc, you might do:
PS1='${?} > '
# After each command, $? is substituted, so prompt shows last exit code
Or more pro:
precmd() {
# This runs before each prompt, you can add custom logic
: # dummy
}
PROMPT_COMMAND=precmd
⚠️ Limitations, Warnings & Notes
- Not all POSIX edge cases are fully supported (some documented limitations). (GitHub)
$LINENOmay not count correctly after complex expansions or line continuations. (GitHub)- Non-ASCII / wide character locales: Some limitations in how Yash handles bytes vs wide characters; string operations are done with wide chars internally. (GitHub)
- Internal assumptions: some signal and file permission flags are assumed fixed values (e.g. SIGHUP=1, SIGINT=2, etc.) which might not hold in exotic platforms. (GitHub)
✅ TL;DR “Why Use Yash?”
- You want a shell that tries harder to be POSIX-correct
- But you don’t want to sacrifice interactive convenience (completion, prediction, editing)
- You like having access to advanced I/O, arrays, redirection features not always present in minimalist shells
- It gives you a balance: strict behavior + useful extras