Sane defaults, useful aliases, no dependencies and easy to expand upon. I made it mostly to give either a sensible default rc file to extend, or just a general high quality prompt.
I'm a big fan of zsh. It doesn't seem to be solely focused on just "doing what you mean", which some of these tweaks seem aimed at; it seems aimed more at correctness. e.g., it would allow you to pass * .txt into a command if * .txt doesn't match anything. Bash will just assume I mean literally '* .txt' so you get different behaviour depending on whether or not there's a wildcard match. zsh has taught me the good habit of always using \* when I don't explicitly want shell expansion.
edit: spaces add after asterisks to avoid formatting weirdness
Heh, fish shell contributors had a long discussion of failed wildcard expansions at https://github.com/fish-shell/fish-shell/issues/2394 . We all pretty much agreed that bash's passglob behavior is really bad.
zsh's default is much better. Though to be fair, bash-style passglob behavior can be enabled in zsh by setting NO_NOMATCH. zsh is still zsh, after all.
There's still plenty more wildcard nuttiness. A favorite is to execute a bare *: zsh will try to execute the first file, passing the other files as arguments!
will only match files, not directories, symlinks etc.
ls **/*.jpg(.L-3000000on[1,5]) **/*.png(N)
will match .jpg files in the current and all subdirectories, which are:
. files
L-3000000 with "length" (size) under 3MB
on ordering them numerically
[1,5] and only the first five
plus any .png files, if they exist (N = it won't fail if they don't).
I have some scripts with expressions this complicated, but day-to-day it's useful for finding empty files (L0) or excluding directories. "man zshexpn" and search "Glob Qualifiers".
2) Glob operators:
ls DSC<100-200>.JPG
matches files with names between DSC100.JPG to DSC200.JPG.
setopt extended_glob
ls *.java~*Test*
matches all .java files, except those matching Test*. Same man page, search "Glob Operators".
3) Lazy for-loops (single command doesn't require do-done), and taking two variables:
echo "A 1" > tempfile
for i j in $(<tempfile); echo $i $j
Interactively, shell history seems to be nicer, I use a couple of global aliases (alias -g L='| less'), and the completion system completes everything you can possibly think of, like usernames, hostnames, remote filenames, HTTP URLs, processes (for kill)...
There are http://www.commandlinefu.com and the like. I copy and paste stuff from the web into the shell occasionally, I'm sure everyone does. I do use fish, but it is annoying sometimes, it's missing the most basic stuff like backticks. So much so that I think I'm going to stop.
This is a non-issue. The `!#/bin/bash` at the top of scripts will tell the interpreter which shell to run. And any one liner I've found online for bash has also worked on zsh (for me), but even if it didn't: `bash -c ls`
Today I learned people actually write / use scripts without specifying the interpreter at the top of the script. This is like writing a Ruby script and expecting it to work when calling it with the Python interpreter.