Moving from bash to zsh [closed]

Solution 1:

As you say, zsh is similar in many respects to bash. It has some features you won't find in bash, and it can be extended in powerful ways. Don't think of moving as a kind of revolution, but rather as a series of evolutionary steps that help you in your daily work. Here are some hints from my .zshrc. Although you say you prefer single pieces of advice, this post is a longish list. Still it is a good idea to go through the points one by one. Just add the interesting bits to your ~/.zshrc and reload with source ~/.zshrc. A final tip: learn the keystrokes of zsh's default ("Emacs") keyboard shortcuts: ^A ^E ^W Alt-F Alt-B Alt-P ^L ^R. You can replace Alt by two separate keystrokes: Alt-P is equivalent to ESC P.


This gives you more extensive tab completion.

autoload -U compinit
compinit

Tab completion from both ends.

setopt completeinword

Tab completion should be case-insensitive.

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'

Better completion for killall.

zstyle ':completion:*:killall:*' command 'ps -u $USER -o cmd'

Changes the definition of "word", e.g. with ^W.

autoload select-word-style
select-word-style shell

Colors for ls.

if [[ -x "`whence -p dircolors`" ]]; then
  eval `dircolors`
  alias ls='ls -F --color=auto'
else
  alias ls='ls -F'
fi

Shortcuts for ls.

alias ll='ls -l'
alias la='ls -a'

One history for all open shells; store 10,000 entries. This makes this into a useful memory aid to find the commands you used last time for ./configure etc. Use Alt-P (find command that starts like this) and ^R (search in history) liberally.

HISTFILE=~/.zhistory
HISTSIZE=SAVEHIST=10000
setopt sharehistory
setopt extendedhistory

Enables all sorts of extended globbing, such as ls **/*.txt (find all text files), ls -d *(D) (show all files including those starting with "."). To find out more, go to man zshexpn, section "FILENAME GENERATION".

# superglobs
setopt extendedglob
unsetopt caseglob

This is useful to remember commands in your history without executing them.

setopt interactivecomments # pound sign in interactive prompt

Type ".." instead of "cd ..", "/usr/include" instead of "cd /usr/include".

setopt auto_cd

Nice prompt.

PS1='[%T] %n@%m:%~# '

Display CPU usage stats for commands taking more than 10 seconds

REPORTTIME=10

Some commands you use extensively in Ubuntu.

alias 'a=sudo aptitude'
alias 'ai=sudo aptitude install'
alias 'ar=sudo aptitude remove'
alias 'au=sudo aptitude update'
alias 'ag=sudo aptitude safe-upgrade'
alias 'as=apt-cache search'
alias 'aw=apt-cache show'

Lists packages sorted by their size - useful when deciding which packages are taking up you disk space.

function apt-list-packages {
  dpkg-query -W --showformat='${Installed-Size} ${Package} ${Status}\n' | grep -v deinstall | sort -n | awk '{print $1" "$2}'
}

Solution 2:

I would recommend the book From bash to Z Shell. It has all the advice you need for switching your shell. It explains the differences of both shells and makes it easy for a new zsher.

Solution 3:

Here is my .zshrc and that is the most importaint thing! zsh have a lot of options you can use, so look at some of all the examples around the net or read the documentation at the Zsh homepage.

My .zshrc doesn't contain any really cool things other than a timestamp in the righthand side of the command line.

Btw, remember to try tab-compleation every where a few examples here:

mplayer -a[tab]

will show somthing like this:

mplayer -a
 -ac                 -- force usage of a specific audio codec
 -af                 -- activate audio filters
 -afm                -- force usage of a specific audio codec family
 -alang              -- select the DVD audio language
 -ao                 -- specify audio driver
 -aop                -- specify audio output filter

And if you use passwordless ssh-keys or ssh-agent you might find it usefull to tabcomplete remote files:

scp apollo:/home/user/[tab]
Desktop/ Documents/ Downloads/ Music/ Pictures/ Public/ Templates/ Videos/

After getting the list you can then press tab more times to cycle through the different possibilities.

But be warned, this shell will make you lazy and make you feel that a standard shell is stupid and annoying!

Solution 4:

A couple of specifically useful extended globs:

  1. rmdir *(/^F) - delete all non-empty directories under the current directory

  2. grep traceback /srv/log/**/*(.m-2) - look for this regex in files modified in the last two days

  3. chmod g+w **/*(U^I) - make any files owned by me and not group-writable be group-writable

Yes, of course you can write this with find but this is easier to dash off. It does have two drawbacks, to be fair, both to do with them all being expanded onto the command line: if it matches many thousands of files the command line will get too long and this will fail, and secondly all of the files are found before the file starts to run.

(You'll need setopt extendedglob if that's not already on)