DEV Community

Cover image for Shell knowledge to get you through the day
Ben Selby
Ben Selby

Posted on • Originally published at benmatselby.dev

Shell knowledge to get you through the day

Following 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
 ...
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 -itype dhagen
dhagen is a shell function from /Users/ben/.oh-my-zsh/custom/docker.zsh
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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, so sudo !! runs the previous command as sudo.
  • {1..5} represents numbers 1 to 5. So we can run for 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

Top comments (0)