Zsh

File matching

  • Zsh has a powerful solution to match files recursively: ls /txt, which returns all txt files in all subdirectories
  • If you want Zsh to follow symbolic links, then you can use /, but watch out for infinite loops
  • Zsh also knows [], which matches any of the enclosed characters For example, [cho] matches all files with extension c, h or o With [^] or [!] Zsh matches all characters that aren't enclosed
  • Glob qualifiers are another nice addition to Zsh: it has the ability to select types of files by using some flags in parentheses at the end of the globbing pattern For example, to list only the directories in the current directory, use: print (/)
  • You can use () for regular files only, (/) for directories, () for executable files, (@) for symlinks, (=) for sockets, (p) for named pipes, (%) for device files, (%b) for block files and (%c) for character files
  • In the same way, you can test for file permissions: ®, (w) and (x) for files that are readable, writeable and executable by the owner, (R), (W) and (X) for those with world permissions (A), (I) and (E) for group permissions For example, to find all executable files inside the current directory tree, try: ls /(x)
  • If you'd prefer to use the symbolic arguments that the chmod command knows, then you can do this too: print (f:gu+rw,o-rwx:)
  • Another useful glob qualifier tests for the user or group that owns a file To test for your own user or group, just use (U) or (G), respectively For other users, you have to add the user or group ID to (u) or (g) So with (u0) you search for all files owned by root and with (u1001) for all files owned by the user with ID 1001 You can also use names if you enclose them with colons: (u:koan:) selects files owned by the user koan
  • Zsh can also pick out files by modification or access time with (m) or (a), respectively You can search for exact times, or periods before (-) or after (+) your chosen point This is given in days by default, but can also be measured in months, (M), weeks, (w), hours, (h), minutes, (m) or seconds, (s)
  • For example, here's how you search for all the files you accessed within the last week: print /(aw-1)
  • Or you can search for files you modified during the last hour: print /(m0)
  • File size glob qualifiers work in the same way: (L) refers to the file size, which is measured in bytes by default, but can also be measured in kilobytes (k), megabytes (m), or 512?byte blocks (p) This makes it easy to look for all files in the current directory that are larger than a megabyte: print (Lm+1)
  • These glob qualifiers can also be combined at will The results may be lengthy, but if you know the basic qualifiers you can make sense of them For instance, (u0WLk+10m0) are files owned by root, world-writable, more than 10k in size
  • modified during the last hour You can use ^ before a qualifier to negate it or , for or See the man page for even more glob qualifiers, including how to sort the output in different ways

Global aliases

  • What if you want an alias for commands that aren't the first word on the command line? Zsh has also thought about this: it calls these global aliases You can define them using the -g option to the alias command, as in this example: alias -g L=“|less”
  • Now you can easily page through the output of another command by adding L to it - for example with dmesg L
  • You can also create aliases for directories, although it doesn't work using the alias command Aliases that are already defined by the shell are ~, which expands to the user's home directory ~user for the home directory of each user With hash, you can define your own names for arbitrary directories For example: hash -d down=~/Desktop/Downloads
  • Now you can go into this directory from everywhere by using the command cd ~down
  • While it isn't really an alias, another option that makes working with directories simpler is AUTO_CD. If you've set it with setopt AUTO_CD in your zshrc, and you type something with no arguments that isn't a command, then Zsh checks whether it's a directory. If it is, then it changes to the directory. So, if you type Documents, it's as if you've typed cd Documents. Changing to the parent directory now becomes even simpler: just use .. instead of cd …

Working with commands

  • Command buffer stack – halfway through typing a complex command on a crappy old terminal and suddenly realise you need to do some other stuff first? Just hit M-q … your command gets pushed onto the stack to be automatically popped off next time you hit enter.
  • Print text straight into the buffer for immediate editing (print -z)
  • short for loops, ex: for i (*.c) echo $i
  • PATH substitution (“ls -l =zsh” is the same as “ls -l /path/to/zsh” or “ls -l `which zsh`”)
  • process substitution (vi =(cmd) edits the output of cmd)
  • null command shorthands:
    • ”< file” is same as “more <file”
    • ”> file” is same as “cat > file”
    • ”» file” is same as “cat »file”
  • the “vared” builtin – allows you to line edit a variable (e.g. “vared path”).
  • automatic file stream teeing (ls > foo >bar puts output in two places)
  • which -a cmd lists all occurences of “cmd” in the path

Modules

dynamically loadable binary modules

  • an FTP client which runs in the shell, with function suite
  • math functions
  • builtin interface to the `stat' system command
  • builtin versions of standard commands (mv, ln, etc) for emergencies
  • special parameters to access internal state of hash tables etc
  • special associative array to access contents of files directly
  • profiler for shell functions
  • a pseudo-terminal handler, for purposes like `expect'
  • builtins for interaction with termcap
  • terminfo

OSX interaction

cdf - change the terminal pwd to match that of the frontmost finder window

Links