
ZSH Aliases - thorstenhans
https://thorsten-hans.com/5-types-of-zsh-aliases
======
JoshTriplett
> I do a lot of conference speaking; if you are presenting at conferences or
> meetups too, you should start your presentation by quickly explaining the
> aliases you will use throughout the talk to onboard your audience.

If you're giving a presentation, please give the actual commands people need
to type, even if that's a little more typing for you. There are tools to help
you auto-type each line of a demo, if needed. Reduce the amount of confusion
and translation people need to go through to understand your presentation.

Similarly, turn off any fonts that create symbolic ligatures, so people know
what symbols to actually type.

Avoid _anything_ unnecessary that increases the distance needed for
understanding between you and your audience.

~~~
jabirali
I think Fish shell "abbreviations" [1] are more suitable for interactive demos
than standard Bash/Zsh aliases. Basically, instead of e.g. `gc` _meaning_ `git
commit` (alias), `gc` can be _expanded_ to `git commit` (abbr), so you can
save typing but still show the actual command.

Modern versions of Fish has both abbreviations and aliases. Personally, I
prefer aliases for providing default arguments to commands (e.g. turning on
colorized output), but prefer abbreviations for timesavers like the `gc`
above.

[1]:
[https://fishshell.com/docs/current/cmds/abbr.html](https://fishshell.com/docs/current/cmds/abbr.html)

~~~
zuhsetaqi
Is there a way to get such expansion functionality for zsh? I would always use
it, not only when demonstrating something but don’t want to switch to Fish
only for that feature.

------
smhmd
For suffix aliases, you can bulk them

    
    
      alias -s {ape,avi,flv,m4a,mkv,mov,mp3,mp4,mpeg,mpg,ogg,ogm,wav,webm}=mpv
    

as opposed to defining them one at a time.

~~~
chrisfinazzo
I can't believe I got all the way through @scriptingosx's book on Zsh and the
suffix aliases just went right over my head.

(Self, you idiot)

cd'ing into a directory on the fly without even thinking about paths and just
opening files by name is powerful juju

Together With AUTOCD, this feels like it shouldn't be possible...but it is.

------
Rairden
I use these suffix aliases to open programs occasionally.

    
    
        alias -g G='| grep'
        alias -g R='| rg'
        alias -g L='| less'
        alias -g V='| vim -'
        alias -g S='| subl'
    

And if I want Zsh to auto-expand it out to type the full command (after
pressing space), add this to end of your .zshrc:

    
    
        globalias() {
            if [[ $LBUFFER =~ '[A-Z0-9]+$' ]]; then
                zle _expand_alias
                zle expand-word
            fi
            zle self-insert
        }
        zle -N globalias
        bindkey " " globalias # space key to expand globalalias
    
    

Identical examples:

    
    
        grep -rw --exclude-dir={test,build} 'throw' L
        grep -rw --exclude-dir={test,build} 'throw' | less

------
rgrau
suffix aliases do not even have to refer to a real existing file. They are an
alias. That's what I use to clone git repos I copypaste:

    
    
      alias -s git="git clone"

~~~
chrisweekly
wat? doesn't this prevent you from doing anything else w git?

~~~
skoskie
No, this really only addresses the situation where the URL ends with (suffix)
“git”.

The only time I use the full URL is the initial cloning, and the remote name
thereafter. But if you use the full URL in another scenario, yes, this may
interfere.

------
donatj
The "navigation aliases" IMHO are better handled as ENV vars.

The example

    
    
        alias dev="cd ~/dev/"
        alias personal="cd ~/dev/thorstenhans"
        alias business="cd ~/dev/thinktecture"
    

Becomes

    
    
        export dev=~/dev
        export personal=~/dev/thorstenhans
        export business=~/dev/thinktecture
    

And now thanks to the way ZSH handles directories, you can still simply change
directory with

    
    
        $ ~dev
        $ ~personal
        $ ~business
    

and it'll work as before but it also allows you to treat it as a fully
qualified directory in other commands which I find exceedingly useful

    
    
        $ tree ~dev
        $ cat ~personal/index.html
        $ rm -rf ~business/secret-documents

~~~
eikenberry
You can directly create named directories with `hash -d`. Eg.

    
    
        hash -d dev=~/dev
        hash -d personal=~/dev/thorstenhans
        ...
    

Nothing else is needed.

~~~
donatj
I'd argue environmental variables have the strong advantage in that you can
use them in cases that won't otherwise expand, namely programs that take a
path parameter immediately following an equals, e.g.

    
    
        $ docker run --workdir=$dev foo
    

in these cases `--workdir=~dev` is not expanded and fails as docker does not
understand your alias.

~~~
eikenberry
True and I often have both. I like my exported environment variables to be all
caps and my directory aliases to be lowercase. This keeps their uses separate.

------
williamdclt
I use global aliases a lot, especially for pipes I use often. my main ones:

\- alias -g G="| grep " (`cat test.txt G some_words`) \- alias -g CC="| pbcopy
" (`cat test.txt CC`) \- alias -g "?"="| fzf " (`ls -l ?`) \- alias -g X="|
xargs " (`ls -l X rm`), probably my favorite (makes xargs kinda look like a
pipe) \- alias -g Y="| yank "

They compose well, too.

\- Pick some file to delete from `git status`: `git status Y X rm`

~~~
joeraut
Which "yank" package are you using? I came across one [0], which copies the
file selected to the clipboard instead of outputting it to stdout. I managed
to get it to print to stdout, though:

    
    
      alias -g Y="| yank -- cat "
    

[0] [https://github.com/mptre/yank](https://github.com/mptre/yank)

~~~
williamdclt
that's the one, from the readme: "If stdout is not a terminal the selected
field will be written to stdout and exit without invoking the yank command"

Could be clearer, basically it means that if it's part of a pipe, it's going
to print to stdout instead of copying to the clipboard

------
oefrha
> Use alias to edit and reload .zshrc

> source $HOME/.zshrc

.zshrc isn't the only startup file, if you place everything there you're
likely doing it wrong and should split things like some environment settings
to $ZDOTDIR/.zshenv.

Better way to reload startup changes:

    
    
      alias reload='exec zsh -l'

~~~
e_proxus
I have this reminder in every `~/.z*` file:

    
    
      # Load Order    Interactive  Interactive  Script
      # Startup       Only login   Always
      # ------------- -----------  -----------  ------
      #  /etc/zshenv       1            1         1
      #    ~/.zshenv       2            2         2
      # /etc/zprofile      3
      #   ~/.zprofile      4
      # /etc/zshrc         5            3
      #   ~/.zshrc         6            4
      # /etc/zlogin        7
      #   ~/.zlogin        8
      #
      # Shutdown
      # ------------- -----------  -----------  ------
      #   ~/.zlogout       9
      # /etc/zlogout      10
      #
      # Note: ZSH seems to read ~/.profile as well, if ~/.zshrc is not present.

~~~
masklinn
> ~/.zshenv

Technically it's $ZDOTDIR/…

Also note from the official documentation:

> `.zprofile' is meant as an alternative to `.zlogin' for ksh fans; the two
> are not intended to be used together

------
franciscop
Okay this is pretty cool, I can set up so `.js` files are opened automatically
with Node.js:

    
    
        $ alias -s js=node
        $ echo "console.log('Hello world')" > demo.js
        $ demo.js
        Hello world

~~~
georgyo
This seems like a good way to accidently run abitrary code downloaded from the
internet.

I can see opening up in an editor as useful shortcut. But actually executing
code without an executable bit seems a bit more dangerous.

~~~
trashburger
Worse, imagine if someone set their shell as the suffix alias for .sh, just to
save time on their curl shell pipes... Oh the horror. Suffix aliases should
come with a big caveat.

~~~
Spivak
Don't worry. I got you.

    
    
        alias -s sh='_c(){ curl -sk $1 | sudo bash };_c'
    

Wait. Improved.

    
    
        alias -s sh='_c(){ [[ -f $1 ]] && sudo bash $1 || curl -sk $1 | sudo bash };_c'

------
jchook
If you "override" a command in your PATH with an alias, you can access the
original command with a leading backslash.

For example, I use:

``` alias open=xdg-open ```

To call the real open command, I can use \open.

~~~
class4behavior
That's a POSIX rule. Quoting any part of a word affects the entire word and
thus preventing expansion. You can also write open''

------
stared
Speaking of ZSH: it is the thing I miss the most in Windows (especially with
ohmyzsh, and its plugins zsh-autosuggestions and zsh-syntax-highlighting).

I know that there is oh-my-posh, but it lacks such plugins. Do you know any
workaround?

~~~
diarrhea
This can get you a part of the way, extracted from my PowerShell profile:

    
    
        ##
        # PSReadLine, see https://github.com/PowerShell/PSReadLine
        ##
    
        ## behaviour of Tab key autocomplete
        Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
        ## From docs:
        ## With these bindings, up arrow/down arrow will work like PowerShell/cmd if the
        ## current command line is blank. If you've entered some text though, it will
        ## search the history for commands that start with the currently entered text.
        ##
        ## Like zsh completion.
        Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
        Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
    

These will allow you to autocomplete previous commands from the tidpids you
already types, so it no longer searches linearly through the history. I also
use:

    
    
        Import-Module posh-git
        Import-Module oh-my-posh
        Set-Theme Agnoster

~~~
PhilippGille
Do you happen to have your PowerShell profile in a GitHub Gist or so?

~~~
diarrhea
No, but mostly because it is not much longer than the above! Only got started
using PowerShell more seriously (thanks to Windows Terminal and WSL) a couple
of months ago.

Here is the other content:

    
    
      # For Agnoster theme, "user@host" will be hidden if user==DefaultUser
      $DefaultUser = "<YOUR USERNAME>"
    
      function vim ($File){
          bash -c "vim $File"
      }
    
      New-Alias pi ipython
    
      # git diff output uses less; it will be buggy without utf8
      $env:LESSCHARSET='UTF-8'
    
      # console output, e.g, when writing git diff output to file using pipe: | Out-File
      [Console]::OutputEncoding = [System.Text.Encoding]::UTF8

------
roylez
My personal favourite

alias -g NF='./*(oc[1])'

This points to the newest file/dir in my current dir, and it is very easy for
me to untar a downloaded file and then cd into it without caring about the
name of the file/dir.

tar xf NF; cd NF

~~~
drewp
'C-x m' pulls the newest file for me:

mv ~/Downloads/[C-x m] /tmp

or even within files that match what I've typed already:

tail /logs/pho[C-x m]

------
lawry
Also worthwhile investing some time in the completion system if you are
writing aliases to save time. I've done it for serverless invoke/deploy/logs
and they've been so useful!

What I'm talking about is typing 'sls logs <tab>' and having tab completion
for the deployed functions when typed in the root of the repo containing the
serverless.yml file.

[https://github.com/larrybolt/zsh-
aliases/blob/master/serverl...](https://github.com/larrybolt/zsh-
aliases/blob/master/serverless.zsh)

------
thecupisblue
I love ZSH + Oh My ZSH. And I didn't even have a choice.

At my first company, the onboarding script included switching to ZSH+OMZ. I
knew it changed the shell, but thought it was just theming - not much. A year
later, switched companies, didn't install it. Don't know how I lived without
it. It is such an amazing productivity update to shell life I consider it a
must on every machine.

------
cxam
If you're working with Python projects and Virtualenv then this is a great
alias to have (assuming you call it _venv_ ):

    
    
      alias venv=". venv/bin/activate"
    

Just cd to a project root and _venv_ :)

~~~
maxioatic
I do something similar, although I use _venv_ to create a new virtual
environment and update pip and setuptools:

    
    
      alias venv='python3 -m venv venv && source venv/bin/activate && pip install --upgrade pip setuptools -q'
    

And then _ae_ and _de_ to activate/deactivate a venv:

    
    
      alias ae='source venv/bin/activate'
      alias de='deactivate'

------
wrboyce
The `cd ...` aliases are an interesting choice; I find it more practical to
use `autocd` in combination with named directories.

    
    
      setopt autocd
      hash -d dev=~/dev
    

Now I can just use `~dev` to `cd ~/dev` but I can also do `~dev/foo/bar/baz`
etc.

~~~
chrisfinazzo
Does this work backwards, too?

For example if I'm in "/Documents/Dotfiles", but want to go to
"/Documents/Blog". Doing the "../" dance is tedious as hell.

~~~
chrisfinazzo
Sigh, again, I should have looked this up...

% Documents/Dotfiles

[~/Documents/Dotfiles] % ../Blog

This does the trick.

------
CSSer
Brb. I’m going to add suffix aliases for all of my frequently used code file
extensions. I had no idea those are a thing.

Although I do wish I could pass a flag that didn’t open it, as sometimes I do
want to append or overwrite a file without the fuss of an editor.

~~~
drewp
I don't think you're going to have a problem. The alias only affects you
trying to "run" the file.

% foo.jpg

# launches image viewer

% cp foo.jpg bar.jpg

# unaffected

------
hiq
About suffix aliases, shouldn't one resort to file associations instead, and
use the corresponding command (possibly with an alias)? It seems weird to have
these settings stored in two places, and have inconsistent results when you
open from the terminal and from another application (like a file browser).

What's the benefit of suffix aliases compared with setting up the
associations? You only save two keystrokes if you have a single-letter alias
(for xdg-open on linux).

------
throwaway888abc
Nice article, on ZSH too (oh-my-zsh). Real productivity.

BTW. Anyone is really using the colorscheme like in article ?

[https://thorsten-hans.com/assets/images/posts/2020/zsh-
alias...](https://thorsten-hans.com/assets/images/posts/2020/zsh-
aliases-1.png)

------
xmdx
I wish I would chain things in the navigation alias.

For example if I set the following alias:

    
    
        alias hello = '~/Docuemnts'
    

It would be nice if I could then execute hello/world to take me to
~/Documents/world but it requires hardcoding.

Guess I could play around with functions and arguments to solve this.

~~~
fratajcz
fish abbreviations kinda do this, for example if you define your alias above
as an abbrev and you type hello<space>, it replaces hello by ~/Documents in
your command line. You still have to press backspace to remove the space you
just inserted, but it's better than nothing.

Also, apparently you can add this to zsh with a plugin:
[https://github.com/momo-lab/zsh-abbrev-alias](https://github.com/momo-
lab/zsh-abbrev-alias)

~~~
lawry
fish-shell abbreviations are really cool, I do miss that in zsh, I'll probably
give that plugin a go. It also makes it for other people easier to see what's
going on when looking at the previous commands.

------
rcthompson
If you add a suffix alias, will zsh start offering to complete matching files
as though they were executable?

------
Bantros
Any benefits to switching to ZSH in Catalina? The prompt every time I open the
command line is annoying me

~~~
thamer
After avoiding it for a long time, I recently switched to ZSH with oh-my-zsh
and I really like it.

But if you're not ready to switch yet and still want to use bash for now, set
this to remove the deprecation warning:

export BASH_SILENCE_DEPRECATION_WARNING=1

~~~
Bantros
Ah thanks

------
xmdx
If you use oh-my-zsh, the kubectl and docker-compose plugin provide good
aliases for every command.

------
asib
My favourites:

    
    
        alias ls='exa -l'
        alias gits='git status'

~~~
skoskie
May I humbly recommend just including the git status in your LS command.

    
    
      alias ls="exa --color auto --all --group-directories-first --long --group --header --modified --sort=name --git --time-style=long-iso --classify"
    

That should give you a gorgeous directory list.

------
kbd
I feel a bit misled that two of the "five types of aliases" are functions and
regular aliases a second time.

Tldr: 1. aliases, 2. suffix aliases, 3. global aliases

~~~
thorstenhans
Well, first I thought about publishing 4 types (I see functions as a valid
kind of alias)

However, the os-specific aliases became more and more important to me due to
GitHub and VisualStudio Codespaces. Targeting different operating systems is
quite important to me.

But technically it's just a regular alias. (Which is also mentioned in the
corresponding paragraph)

~~~
asicsp
>This article will teach you how to create and use these four types of aliases

>You have seen four different types of ZSH aliases that will boost your
productivity

`four` in these two lines is typo or intentional? Because the title says `5
Types Of ...`

~~~
thorstenhans
thanks for the feedback. I've updated the corresponding parts

------
smhmd
You can, also, add flags to your program:

    
    
      alias -s txt='less -rE'

------
anarchyrucks
alias rm=trash

I have a habit of cleaning up the workspace in my machine. This alias saved me
a 1000 times already.

~~~
hiq
I prefer something like "alias sp=trash" (sp for suppress), and getting into
the habit of using this alias (for instance by doing alias rm="echo nope"), so
that if I use it on another machine by mistake, it just fails instead of using
/bin/rm (and I can then resort to trash or double-check that my rm command is
not faulty).

------
pvg
The actual link for this submission is

[https://thorsten-hans.com/5-types-of-zsh-aliases](https://thorsten-
hans.com/5-types-of-zsh-aliases)

if your ad blocker is barfing on whatever bitly-based tracking doodad was
submitted instead.

------
inatreecrown2
using aliases is a beginners mistake. they will one day break. just type in
the real thing.

also, if you use aliases for commands that you use a lot, it is better to
remember how to correctly type the command.

~~~
cyberpip
imagine not typing out the full/basic git commands the rest of your life and
all the time that'll save though

~~~
inatreecrown2
imagine loosing your aliases. just learn to type and enjoy life.

~~~
avindroth
Or you can spend less time typing and enjoy life

~~~
inatreecrown2
yes, but with a crutch

~~~
sylens
The worst case scenario is that I lose my .zshrc file and have to google
commands again

~~~
tenantless
Or, keep your dot files in a public/private Git repo and don't worry about
that either. Also makes setting up new machines/users a breeze.

~~~
avindroth
Yeah why would anyone not version control their dot files

