Shell knowledge to get you through the day
Mar 28, 2021 · 6 min readFollowing on from the Docker knowledge to get you through the day, and Git commands to get you through the day posts, this will cover Shell commands. Once again, it aims to get you through the day.
First of all, it’s worth noting that there are many shells: bash, sh, zsh etc. For a comprehensive list of shells, and their comparison, head over to Wikipedia.
Basic commands
Let’s cover off some basics that will hopefully get you on your way.
man
is the manual application. Use this to find information about all the other commands, and options. e.g. man ls
will give you the manual page for the ls
command.
For extra points, you can define an environment variable that changes how you view the manual. e.g.
MANPAGER=cat man ls
This will output the entire manual to the screen, without any interaction. My MANPAGER
is set to less -X
. With your new knowledge of the man
command, find out what -X
means for less
.
ls
lists files in a given directory. ls -lGh
is a favourite of mine which lists all the files in the current directory, enables colourised output, and provides human readable file sizes! There are many options to ls
, so I recommend you read the output from man ls
and find what output suits your needs.
Whilst we are talking about listing files, I always like to remind folks about git ls-files
which lists all the files in a git repo. Sorry to slip in a git
command there.
df
and du
are two disk related commands that I use quite often.
df
displays information about free disk space. I recommend running it with df -h
so the output is a little more human readable.
du
comes in really handy when you want summary information about folder/file sizes. The -d
flag allows you to define the depth of the summary. For example to find the total size of your node_modules
folder:
❯ du -d 0 -h node_modules
198M node_modules
If you want to know the size of all the packages, individually, in node_modules
, then you can run
❯ du -d 1 -h node_modules
16K node_modules/write
12K node_modules/callsites
16K node_modules/is-extendable
...
vim
, less
, tail
, and cat
allow you to view file content. Each of these commands take a file as a parameter. vim
is too big to cover here, so try running vimtutor
to see if that helps you learn vim.
tail
is handy when coupled with the -f
flag, to “follow” the output of a file, e.g. a log file tail -f /path/to/file
.
cat
simply outputs all the content to the terminal, with no paging.
less
allows you to page through content with ctrl+f
and crtl+b
.
The following commands help with process management: ps
, kill
, pgrep
, top
or htop
.
ps aux
will output all the processes, for any user, running on the machine. You can drop the x
if you want to get processes running for any user with a controlling terminal, i.e. you ran the command from a terminal. Another way to get process information is pgrep
which takes a command parameter. For example we can run pgrep -l vim
which will output the process IDs (PID) of all running vim
commands.
The output from ps
and pgrep
then can be used to stop a proces. For example kill [pid]
will kill the process with the same [pid]
.
top
, and the more functional sister command htop
, will show you statistical information about running commands. This covers memory, CPU, how long it’s been running etc.
Understanding where things are installed is really handy, and there are a few commands that can help.
which
will explain where the command you pass in as a parameter is being run. So which go
will show you the version of go being used when you run go
.
where
will show you all the versions of the command you pass in. So I have two versions of bash right now.
❯ where bash
/opt/homebrew/bin/bash
/bin/bash
❯ which bash
/opt/homebrew/bin/bash
So I have two versions of bash
, but the one I would use is the homebrew
version, as shown by the output of which
.
type
helps explain what kind of “thing” the command is. Some examples are shown below.
❯ type bash
bash is /opt/homebrew/bin/bash
❯ type envg
envg is an alias for env | grep -i
❯ type dhagen
dhagen is a shell function from /Users/ben/.oh-my-zsh/custom/docker.zsh
The order of precedence for determining which commands to run, is defined by the $PATH
environment variable. Run echo $PATH
to understand the ordering, with the first path taking priority.
sed
is really useful for automating changes to files/content.
date | sed "s| |-|g"
Sun-28-Mar-2021-21:22:58-BST
This takes the output of date
(an arbitrary example) and replaces spaces for hyphens.
Remember the time when you ran that command, but cannot quite remember it? Well history
has your back. By running this command, it will output all the commands you have ran previously.
Two tips:
- Add a space before running a command, and it won’t be stored in your history file. Handy if you are entering a password, for example.
ctrl+r
will reverse look up your history.
Some little tidbits I find useful:
echo $?
will get you the exit code of the last command executed.!$
will get the last parameter of the previous command.!!
will get the entire last command, sosudo !!
runs the previous command assudo
.{1..5}
represents numbers 1 to 5. So we can runfor x in {1..5}; do echo $x; done
.
Pipes
Pipes allow you to chain commands together. It allows you to take the output from one command and pipe it into the next command.
env | sort
will sort all your environment variables, so it’s easier to find what you’re looking for. You could even create this as an alias.
history | grep [command]
will find a command in your history (commands you have run before).
These are just arbitrary examples, but you can keep chaining commands together, to deliver the output you want.
Environment variables
Environment variables help you configure your system and applications. You can set them in the following way:
export MY_ENV_VAR=boo
It’s customary to capitalise the name of the environment, but it’s not mandatory. To remove an environment variable you can run unset MY_ENV_VAR
.
You can set environment variables to be loaded when you start your shell/terminal, if you add the export
statements to something like ~/.bashrc
, ~/.bash_profile
, ~/.zshrc
etc.
Aliases
Aliases are great. They can be used to provide a shorter command so you are more efficient. A great community project for aliases, is oh-my-zsh.
Just like environment variables, we can set, unset, and store them in a config file.
alias week='date +%V'
will get you the week number if you run week
. To get rid of this alias, you can run unalias week
.
I hope this provides some useful knowledge to get you through your day in the terminal.
See also
- Docker knowledge to get you through the day
- Git commands to get you through the day
- 101 Bash Commands and Tips for Beginners to Experts
- ohmyzsh - “A delightful community-driven (with 1800+ contributors) framework for managing your zsh configuration.”
- fzf - A command line fuzzy finder. You can hook this into
crtl-r
which I highly recommend.