I wrote this slide deck. It was a presentation I made for a monthly "tech lunch" my team has.
I made it after a couple of weeks of messing with zsh. It was for an audience of 4 other people who knew less about zsh than me. I can't believe someone posted it to HN!
That explains the "this slide deck is getting traffic" email I got from Slideshare this morning.
Many people like me are new to whole Unix system and need trainings like this. I did not even know that I can upgrade my bash via homebrew.
I don't dare to switch to zsh yet. I'm afraid if it messes up all my bash_profile, rvm stuff and Vim configs. I have a bad memory with fish_fish
It was just a bit of a shock when I clicked the link. Since the link title was slightly different than what I named my slides, I just thought, "oh hey, another zsh comparison, let's see what this guy/gal said"...
Almost every other "Switch from bash to zsh, it has this awesome killer feature" article I've seen has raved about a feature that's available in Bash & has been for years.
I'm starting at a new job in a month or so, I shall try & use it as an opportunity to switch to zsh since I won't have any can't-live-without bash shortcuts in place at that point.
(Last time I tried switch to zsh, it took OMZ to get it useable, but it also made it too slow to live with. Hopefully starting with a clean slate will do the trick)
As for "Oh My Zsh," I've never seen any reason to use it, as zsh works fine without any add-ons.
| As for "Oh My Zsh," I've never seen any reason
| to use it, as zsh works fine without any add-ons.
I'll second this. I've never found a need to use "Oh My Zsh," and I've been using zsh for a few years.Yeah, I feel the same way. Most people seem to act like bash doesn't have tab completion or customizable prompts or something. This is actually the first time I've seen actual useful features of zsh that bash actually does not have (path expansion for instance). But I actually have my own little workaround scripts for those types of things that I'm used to so I don't feel a huge compelling reason to switch. The multiple shell history thing is a pretty good reason though. Maybe I'll switch eventually.
The directory listing shares the same problem. Once you have a list, it's just as easy to type the path then it's to cycle through the list (not that zsh stops this), it's just another interactive feature.
Then there is path-completion, which removes the / on the end of tab-completed paths. Since rsync treats a directory with / different to that without one, this feature annoys me to no end when using zsh.
I understand that all these are options, and could easily be configured. I just wonder how other people feel about them. Does anyone actively use these features? Do you find they can occasionally get in the way?
Also annoying when I start a command with sh, hit tab to command complete it with a .sh script in the current dir, and the command completion shows not just the .sh script but a bunch of shell commands as well. Pretty sure 'sh' should filter all those out and return only 'example.sh'. I don't recall this happening on bash.
Love all the plugins and things like oh-my-zsh, though.
Don't get me wrong though, bash does have its bad points.
vimdiff <(ls /bin) <(ls /usr/bin) [ It is an example. In real world, I use this feature for comparing outputs of one version of program with another one ]
And this will create two pipes, where output of each ls will go. Unfortunately, vimdiff sometimes needs to do second pass on the files, so this command won't work properly when outputs are large.
But in zsh you can write
vimdiff =(ls /bin) =(ls /usr/bin)
and this will create temporary normal files, instead of just pipes, and vimdiff will work fine.
local green="$(tput setaf 2)"
local reset="$(tput sgr0)"
export PS1="\[$green\]>>\[$reset\] "
And a multiline prompt, let alone one with right-justified elements, is pretty gruesome to me.The first slides about availability on Macintoshes don't resonate, because I'm going to have MacPorts on any dev box and use that to install the latest. It's more likely I ssh to a server that has Bash 4 and no Zsh than anything else, so it also makes sense to know bash and have a good .bashrc ready to scp up there if I'm going to be doing a lot of work on the server.
zsh spellcheck is very annoying, thankfully it can be disabled. This is my preferred spellcheck solution ;^) https://github.com/mtoyoda/sl
All that being said, zsh is a really cool piece of software. It's one of those things I've always wanted to really stretch to its limits, but I've never been able to hang with it for more than a few months, which I doubt is enough time to really become accustomed to the workflows zsh allows (like the /u/b/... expansion example in the slides).
local green="$(tput setaf 2)"
local reset="$(tput sgr0)"
export PS1="\[$green\]>>\[$reset\] "
Could be this in zsh: export PS1="%{%F{green}%}>>%{%f%} "
- %{%} replace \[\]
- %F{color} sets the foreground colour
- %f resets the foreground colourI would go with something like:
export PS1="%{%(?.%F{green}.%F{red})%}>>%{%f%} "
It will be green if the last command exiting successfully, otherwise it will be red.There's also better history support (from my zsh config):
# History
# ~~~~~~~
HISTSIZE=1000
SAVEHIST=1000
HISTFILE=$HOME/.zsh_history
setopt SHARE_HISTORY # Share history across sessions
setopt HIST_IGNORE_SPACE # commands starting w/ a space don't go into history
# SHARE_HISTORY seems to imply both of these, at least that's how the manpage
# reads, so let's comment them out for now.
#
# setopt INC_APPEND_HISTORY # Incrementally append history to file
# setopt EXTENDED_HISTORY # Save the timestamp and duration of commands to history fileRegarding the claim about Knuth's program being long, it is worth considering that (1) his program was primarily a demonstration of literate programming style, which contains considerable embedded documentation (2) the program needed to build significant basic infrastructure to support itself, including IO, sorting, case equivalence (including a table with each upper-case and lower-case letter), etc.
Doug's criticism and comparison of Knuth's solution vs. his own is insightful worth reading.
I don't use Plan 9, code in D or write LuaTeX, but I do use Emacs and wear a monocle. The last two are not a coincidence as the first (arguably more adequate substitute for God), invariably leads to the latter, most excellent eye wear.
And a note to my Mac friends : "Using csh is like trying to type with your feets[sic] (if you're used to zsh or ksh)."
In fact I find zsh much easier for beginners and people who don't master the arcane intricacies of *nix.
I always have fun to see junior guys trying their way around such systems.
You should use different software or customizations when it's a good trade-off, not because everyone else is or isn't doing it.
I don't think it's that much of a problem. My local machine is zsh, my linux servers run bash, my solaris hosts csh. Where ever I am, I just adjust to the local environment.
shopt -s globstar
rm **/*.swpFor example:
setopt extglob
cd *(<tab>
~~ massive spam of possible glob qualifiers ~~
and it works for variable expansion modifiers as well: print ${(<tab>
~~ completion candidates for parameter flags ~~
print ${<tab>
~~ complete any currently set variable in the current env~~
Another thing I like is the array types for things like $PATH that are historically colon-separated, typically
lower-case versions of the var name for the interesting 'magic' ones. vared path
vs vared PATH
to see the difference. print -l $path # much easier to readTry it. It's better.
I was happy enough sticking to bash as it's the default shell everywhere, but since someone switched me to Zsh (using oh-my-zsh) I probably rely on the features too much to ever go back. I also hear https://github.com/sorin-ionescu/prezto is a nicer, cleaner fork of oh-my-zsh but I haven't so found the overwhelming desire to go through the switching pains.
"Watch out, Netscape Navigator 4.0!" and so on.
What's "better" about it?
2) An effort to clean up and orthogonalize shell syntax. The potential portability means I usually still make bash scripts when I'm sharing for others, but for my own stuff it's great.
3) Suggested completions. I start typing a command and if it's one I've used before in that directory it appears in faint gray letters on my command line and I just have to press ctrl-f to bring it up that way.
4) Probably a consequence of (1), but it feels very fast to me compared to when I used zsh. The author also talks about using threads and minimizing disk access to speed it up, but I don't really know how it compares to zsh on that level.
I do not know if it has all I love in zsh (things like (.) or (om^/) or * or !$), but I would not trade zsh's completion for gaining 10% on startup time.
FreeBSD
DWM
dmenuAs a simple example, in bash if you use tab completion and there are multiple options, pressing tab again just reminds you that there are multiple options accompanied by a passive aggressive beep (it used to be this way at least). zsh lets you cycle through the possible completions.
This should fix it in bash: bind '"\t":menu-complete'
cd site1 site2
if you just add this line to your ~/.bashrc: function cd() { if [ $# -eq 2 ]; then builtin cd ${PWD/$1/$2}; else builtin cd $1; fi }^site1^site2
"git co br<tab>"
It finishes with:
"git co origin/branch"
Whereas what I want is:
"git co branch"
because I have git set up to automatically create a local branch and set it up to push to the remote when I do that. Just a small annoyance. Overall I find ZSH has cool features that don't actually work that well, or at least they don't do all that much for me. Spell checking, for example, is rarely that useful since it tends to show up for commands that work fine. It really needs an option to say "never correct this" but it doesn't.
That said I still use it, don't see any reason not too. I mean, Powerline for ZSH looks gooood. Just not sure it's that much better than other shells.
When I used bash, whenever I needed to uncompress a tarball I downloaded, I would type in the full, ~50 character filename. Only through zsh did I find out about tab autocomplete, and when I had to use bash on a friend's Mac, to my surprise, autocomplete worked.
I still use zsh, though.
[1] And sometimes they use it as a 'cheat.' virtualenvwrapper (on Ubuntu, and I assume Debain) is dropped into /etc/bash_completion.d/ instead of somewhere in $PATH. Meaning that it's auto-sourced for bash users, but zsh users need to know where it is, and source it. It seems stupid to put it in the bash_completion directory. Sure it has some completion stuff in it, but the bulk (and purpose) of the file is to setup a bunch of wrapper shell functions. It's like they didn't have a formal place to put it so they just jammed it somewhere.
Tab auto completion takes a second or two (even for files).
Combined with the git plugin I have enabled (which does "git status" on every prompt in a git folder) it's almost unbearable to work with.
I've looked into it a couple of times, there are some people with the same issues on oh-my-zsh's github, but I could never really solve it.
Would any pro zsh user know what my issue could be? I'm seriously considering going back to bash, I use it at work and it reminds me how fast the terminal can be.
The only recourse I think is to go back to a clean zsh and build your own .zshrc. There are other leaner zsh "frameworks"[1] I have read of, but i intend going back to stock zsh soon.
1) - see zshuery and zsh-m on github.
Clean the history file.
How is this a worry?
The topline in your bash script is '#!/bin/bash'
Which tells the system 'run this with bash'.
Example, I _think_ / (recursive globbing) works by default in zsh but not in bash. If you have / in a bash script without setting the right options then your script won't work and you will have no idea why until you've wasted a lot of time debugging.
scp someuser@someserver:<tab>
… will ssh into the server, fetch the file list and offer it for completion locally (granted you have set up public key authentication)Luckily enough, I don't have to work over servers which may or may not have zsh, so i don't need to worry about that. Whenever I have to use a PC with bash (or any other *sh), I can easily get the same result, with a slightly-worse user experience.
Also, as a nice tip, zsh will complete "kill" and "killall". So that I don't have to fire up htop every time I want to kill a process.
Fish (that I don't use regularly), however, has useful features.
for realm in ~/Library/Caches/temporaryitems ~/* ~/Desktop/* ~/Documents/* ~/Documents/Prj/* ~/Library/* ~/Library/Scripts/* ~/Library/
do
for folder in $realm
do
if [ -d ${folder} ]
then
* CDPATH="$CDPATH":"$folder"
fi
done
done
As for completions of git and such, that relies totally upon where you got your completion from.
There gotta be better arguments than this, and I am really sure there is.I am on Mac OsX, and I downloaded and installed bash 4.2, and I have never experienced any problems with that.
^site1^site2
and get the same result.
The idea, I believe, is when your browsing around multiple versions of the same directory structure. The 'cd site1 site2' allows you to jump directly to the equivalent directory in the other structure.
The equivalent in bash would be something like: cd `pwd | sed 's/tmp1/tmp2/'`
My own http://imgur.com/6LCS1cj
Some examples: https://github.com/search?q=TIMEFMT+extension%3Azshrc&ty...
export REPORTTIME=1Oh, wait. Right. Lost in pronunciation. :P
Example: $ rm * .gch dir/* .gch
<tab>
$ rm file1.gch file2.gch file3.gch file4.gch dir/file5.gch
I really enjoy it when I'm removing something sensitive and just want to make sure.
export a=0
cat $file | while read line
do
a=$(expr $a + 1)
done
Bash will fork the while loop as a separate process, inheriting (copying) its own environment, and the variable will only update locally, not in the parent process.This comment however reminds me of some behaviour of bash 2.03 or earlier, where this behaviour was flawed, if you suddenly changed execution path during a recursion in a shell script. Sorry I can't describe it better, and that bash version, that was before 2.03 is long gone now!
Let's say you are about to finish a really long command and realize you should have done one other command first.
ESC + Q clears the current line, lets you enter a command, and then inserts the cleared line again on the next prompt. You have to try it to realize how cool it is.
Esc-Q sounds easier, though.
ESC+. does not work for me with zsh.
zsh 4.3.11 (i386-apple-darwin12.0)
Maybe it's the version.
ESC+Q also doesn't clear the line.
At the same time, the OP links slide deck fails for me at the cd /u/lo/b part. It simply doesn't work.
BSD has the almquist shell as it's /bin/sh and tcsh as it's /bin/csh. Various commercial vendors licensed the korn shell from bell labs. The korn shell is public domain and open for 13 years now. The default sh on most UNIX boxes are either ash or a hard link to ksh which emulates the POSIX definition of sh. zsh and bash also provide the option to hard or soft link so depending on your distro you may have /bin/sh linked to bash.
Debian at one point repackaged the BSD almquist shell as their system sh calling it dash mainly for speed and stability. I believe they removed it as their programmers apparently couldn't program system level scripts without their non portable bashisms or maybe just one of the NIH moments where everything must live under a single mono-cultural license and identity.