Zsh – the sheet

Basics

Let’s start with some basic concepts.

Zsh is probably Bash++

Zsh has many of the essential features of bash, ksh, or tcsh, so common syntaxes such as conditional statements, expansions, or assignments will work pretty much…


This content originally appeared on DEV Community and was authored by DEV Community

Basics

Let's start with some basic concepts.

Zsh is probably Bash++

Zsh has many of the essential features of bash, ksh, or tcsh, so common syntaxes such as conditional statements, expansions, or assignments will work pretty much the same.

Zsh brings cool additional features you might find helpful, though.

Zsh stands for "Z-Shell" and is meant for Unix systems. It's an interactive shell that wraps commands you use on the terminal.

But Zsh is neither bash nor sh

Even if Zsh is highly compatible with Bash and sh, we'll see there are some notable differences. As a result, the following might work:

zsh myscript
sh myscript.zsh
./myscript.sh

But it's a bit misleading and you can even get unexpected errors in the worst-case scenario because the default behavior is not the same.

Installing Zsh

If Zsh is already available on your system, you can check if zsh is your current shell with:

echo $0
  • If it says "zsh", you are ready to go
  • If it's another shell, you can simply type zsh to switch prompt quickly
  • If you want to set Zsh as the default shell, type chsh -s /bin/zsh

If Zsh is not yet on your system, it's pretty straightforward to install.

Best framework

You can install Oh my zsh, a wonderful framework that eases configuration and provides tons of customizations (e.g., themes, plugins, aliases, etc).

The agnostic way

You can run the following in the terminal:

sudo apt update && apt install zsh && chsh -s /bin/zsh

The above command install the package and set it as the default shell. If you get an error with /bin/zsh, you can use $(which zsh) alternatively to locate Zsh on the system.

Depending on your Linux distribution, you have to replace sudo apt with the appropriate command. For example, your will use yum -y install for CentOS and pacman -S zsh in Arch Linux.

Configuration files

Zsh uses configuration files (like Bash):

.zshenv  # env vars
.zprofile # external commands
.zshrc # global settings and customizations such as autocompletion, case sensitivity, aliases, etc
.zlogin # commands on shell login
.zlogout # commands on shell exit

The Shebang

It's the #! at the top of bash files. "Bang" is for the exclamation point "!":

#!/usr/bin/zsh

It's essential not to forget it, as if you use #!/usr/bin/bash, then the bash interpreter will be used when running ./myscript, regardless of the default shell.

Executing scripts

zsh myscript.zsh

Alternatively, you can make your script executable and run it:

chmod +x myscript.zsh && ./myscript.zsh

Zsh can autocorrect

Zsh is smart enough to detect small typos and suggest corrections for commands:

zsh: correct 'MISPELLED_COMMAND' to 'COMMAND' [nyae]?

Note that it also works for folder names and files.

It's pretty cool but you might get annoyed in some cases. You can disable autocorrection like that:

nocorrect MY_CUSTOM_COMMAND

You don't have to use cd

You might already know this trick, but in case you don't, the change directory command is not necessary to browse directories with Zsh. The following command will get you to the desired path:

/Users/ella/Desktop/

It's pretty convenient to quicky move to a nested directory, for example, by drag and droping the folder inside the terminal and typing enter.

It's possible thanks to the autocd option.

You can use keyboard shortcuts in the terminal

Like in Bash, you can use shortcuts in the terminal to gain time and energy. For example, Ctrl + U can delete from the cursor to the start of the line, and Ctrl + L will clear the terminal.

Best documentations

Scripting

You can use most tricks you learned in Bash and the syntax is the same. There are additional features and important differences, though.

zsh arrays are 1-indexed

It's a major difference with Bash. Arrays do not start at 0 but 1, which might be way less confusing and thus, more intuitive for most users:

MyArray=(All In One)
echo ${#MyArray[2]} # displays 2 in zsh (number of chars of the second element) and 3 in bash (number of chars of the third element)

As a result, the total length is the same as the last index in Zsh.

N.B.: Note that you can modify that default behavior to have 0-indexed arrays, but it's not something I would recommand as a general rule.

Zsh is better at globbing

In Bash, you will likely interact with the filesystem using the find command. For example, to apply a command on all files, you might use:

find . -type f -print | xargs CUSTOM_COMMAND

In Zsh, you can use globbing:

CUSTOM_COMMAND **/*(.)

**/ is for recursion and the third wildcard * is to target all elements. (.) will match files.

All glob qualifiers

You can combine many Glob qualifiers like filters to only target the elements you need.

Qualifier Description
/ directory
F non-empty directory (empty: (/^F))
. plain file
@ symbolic link
* executable plain file
r/A/R readable by owner/group/world
w/I/W writable by owner/group/world
x/E/X executable by owner/group/world
s/S/t setuid/setgid/sticky bit
fspec has chmod style permissions spec
u:name: owned by user name
g:name: owned by group name
a[Mwhms][-+]n access time in given units (see below)
m[Mwhms][-+]n modification time in given units
L[kmp][-+]n size in given units (see below)
^ negate following qualifiers
- toggle following links (first one turns on)
N whole pattern expands to empty if no match
D leading dots may be matched
n sort numbers numerically
o[nLamd] order by given code (see below; may repeat)
O[nLamd] order by reverse of given code
[num] select num-th file in current order
[num1,num2] select num1-th to num2-th file

Source: obda.net

Common tricks

Be careful with qualifiers, as they are not magic. If you scan too large folders, you might get errors. Anyway, it eases common operations for sure.

List files only
ls **/*(.)
List directories only
ls **/*(/)
Find all files with specific extensions
ls **/*.md
Find files larger than 25 megabytes
ls **/*(.Lm+25)
List files that have been modified during the last two days
ls **/*(.md-2)
Change permissions for files owned by a specific user
chmod 644 **/*(u:ella:) # provided that ella exists ^^

Oh my zsh alternatives?

Dev often recommend using Oh my zsh because it's actively maintained and significantly more friendly to use and configure. It does not mean it's the only way to customize zsh at all.

You could, for example, open the .zshrc file and write specific lines to customize the prompt without any additional layer. The main caveat is it would be a bit more complicated, perhaps tedious, but many dev would likely stick with the native tools instead of installing frameworks:

# for all options @see https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html
PROMPT='%F{red}%1~%f %# '

# aliases
alias gs='git status'
alias gc='git commit'

I totally respect that approach. I'm not a big fan of alternative frameworks, though. Most tools I've tested are not reliable, to me, or lack documentation and concrete examples.

Too much dependencies can be a concern. Besides, you often end up installing and loading tons of plugins while using only a small percentage of all features and aliases.

Going further

You might need more customizations and bindings.

Get some inspiration in Kali Linux

It's worth diving into Kali Linux and its default .zshrc file. The pen-testing distribution makes interesting use of advanced features such as bindings and completions:

# ~/.zshrc file for zsh interactive shells.
# see /usr/share/doc/zsh/examples/zshrc for examples

setopt autocd              # change directory just by typing its name
#setopt correct            # auto correct mistakes
setopt interactivecomments # allow comments in interactive mode
setopt magicequalsubst     # enable filename expansion for arguments of the form ‘anything=expression’
setopt nonomatch           # hide error message if there is no match for the pattern
setopt notify              # report the status of background jobs immediately
setopt numericglobsort     # sort filenames numerically when it makes sense
setopt promptsubst         # enable command substitution in prompt

# enable completion features
autoload -Uz compinit
compinit -d ~/.cache/zcompdump
zstyle ':completion:*:*:*:*:*' menu select
zstyle ':completion:*' auto-description 'specify: %d'
zstyle ':completion:*' completer _expand _complete
zstyle ':completion:*' format 'Completing %d'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' list-colors ''
zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
zstyle ':completion:*' rehash true
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' use-compctl false
zstyle ':completion:*' verbose true
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'

# force zsh to show the complete history
alias history="history 0"

# configure `time` format
TIMEFMT=$'\nreal\t%E\nuser\t%U\nsys\t%S\ncpu\t%P'

Source: Kali Linux - .zshrc

Don't forget the source command

The source command is necessary if you want to execute scripts inside other scripts or apply modifictions on the current terminal. Every time you modify your .zshrc, run a source ~/.zshrc to load the updated configuration.

Alternatively, you may close the current terminal and open a new one.

Aliases

I love using aliases. I think that's a great way to improve productivity and remove the hassle of remembering and typing the same command lines over and over.

Of course, Zsh allows you to set them. You can directly put them in your .zshrc:

# 🥷🏻
alias erase="history -p"

Source from separate files

It's fine if you have only a few aliases but I recommend using separate files to keep things organized. I usually set global aliases and specific ones, for example, aliases I use on my free time and aliases for work.

There are several approaches to achieve that but the most straightforward is to source your additional files in the .zshrc:

source "~/.aliases_for_work"
source "~/.aliases_for_fun"

Suffix aliases

You can define aliases with the -s option:

alias -s {css,html}=vi

The above line will set vi as editor to open .css and .html files.

Global aliases

Zsh allows you to define global aliases that will be expanded everywhere:

alias -g vid='-v -i --d' # letters are arbitrary here

Then you can use vid directly in the terminal whether it's at the beginning, in the middle, or at the end of the command line.


This content originally appeared on DEV Community and was authored by DEV Community


Print Share Comment Cite Upload Translate Updates
APA

DEV Community | Sciencx (2022-03-16T19:12:32+00:00) Zsh – the sheet. Retrieved from https://www.scien.cx/2022/03/16/zsh-the-sheet/

MLA
" » Zsh – the sheet." DEV Community | Sciencx - Wednesday March 16, 2022, https://www.scien.cx/2022/03/16/zsh-the-sheet/
HARVARD
DEV Community | Sciencx Wednesday March 16, 2022 » Zsh – the sheet., viewed ,<https://www.scien.cx/2022/03/16/zsh-the-sheet/>
VANCOUVER
DEV Community | Sciencx - » Zsh – the sheet. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/16/zsh-the-sheet/
CHICAGO
" » Zsh – the sheet." DEV Community | Sciencx - Accessed . https://www.scien.cx/2022/03/16/zsh-the-sheet/
IEEE
" » Zsh – the sheet." DEV Community | Sciencx [Online]. Available: https://www.scien.cx/2022/03/16/zsh-the-sheet/. [Accessed: ]
rf:citation
» Zsh – the sheet | DEV Community | Sciencx | https://www.scien.cx/2022/03/16/zsh-the-sheet/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.