CLI Basics for Noobs
Me desperately explaining what a CLI is.
What is CLI?
There are generally two types of programs out there:
- GUI - graphical user interface - think of MS Word or Firefox.
- CLI - command line user interface.
In a GUI you use your mouse or touchpad to click buttons move stuff and generally interact with the program. While you can often use tab to move between elements, it most often is a pain. CLI on the other hand are entirely text based! You do not need a mouse or rather you cannot use your mouse. Think of a CLI like a chat: Do stuff! Stuff done. Show directory! These are the files in the directory.
Terminal Emulator
To use a CLI you have to open a terminal emulator (short terminal). Terminal emulators are interchangeable between each other. It generally does not matter wether you use PowerShell, Kitty or WezTerm (my favorite).
A terminal always displays, what has transpired, and always gives the option to input more commands.
Shell
The shell on the other hand is not interchangeable. When using the PowerShell terminal emulator, the shell defaults to PowerShell (thanks microsoft!). On MacOS the default is Zsh and on Linux the default is Bash.
A shell is essentially the way you interact with the system or file system. The usage of shells is not universal! But shells like PowerShell have by default shortcuts emulating commands of shells like bash.
I am on Windows and thus use the PowerShell shell with the WezTerm terminal emulator:
(The icons and the style stem from Oh My Posh.)
Generally speaking, if you have a choice, default to fish on Linux and MacOS and to PowerShell on Windows.
CLI Programs
CLI programs are text based and their usage is almost always similar.
Here are some examples:
# execute the program `ubilerntui`
ubilerntui
# get the programs usage
ubilerntui --help
# get a shorter version of its usage
ubilerntui -h
# ask for its version
ubilerntui.exe --version
# ask for it's license
ubilerntui --license
# execute a subcommand
ubilerntui lade
# get the help of the subcommand
ubilerntui lade --helpThere is always the command or rather the main program you seek to execute (here ubilerntui).
To get the usage of the program, you almost always just execute it with the flag --help. If that did not work you might try -h, -help, /H, /HELP, /help, man ubilerntui. To get the help of the very often used command cp you can just type man cp into your terminal.
Options
An option is an argument to a program, that changes its behavior at runtime. An option always takes a value:
example-program --this-is-an-option this-is-a-valueAs you can see, between option and command / program there is a space! Between the option and its value is a space as well!
The order of arguments is important as well. The value of the option always comes immediately after the option!
Seldomly an option and its value are not separated by a space but rather by an equal sign --this-is-an-option=this-is-a-value.
If the value itself has spaces, the value needs to be enclosed in either " or ':
example-program --this-is-an-option "this is a value with spaces"If the value has either " or ', the opposite symbol escapes it:
example-program --my-name "Monkey D'Luffy" # that's okexample-program --my-name 'Monkey D"Luffy' # that's ok tooFlags
Flags are similar to options but take no value.
# flag is not set
example-program
# flag is set
example-program --prettyShorthands
Options and flags often have shorthands.
Shorthands have only one dash and very few characters:
# Often used shorthand for `--help` flag:
example-program -hSubcommands
Subcommands enable a program to act as if it was multiple programs.
example-program eat
example-program eat stuffSubcommands generally have their own usage and their own flags and option:
example-program eat --help
example-program eat stuff --helpArguments
Arguments are fixed inputs of a program. Arguments are not optional!
Imagine a program that takes an image and returns the same image with a kitten on it:
draw-kittenIt essentially needs two paths:
- The path of the original image.
- The path of the new image.
You could use options here:
draw-kitten --input original-image.png --output image-with-kitten.pngBut as this program has only one role: Read image and write image with kitten on it. It is much better for the end user to just give those two paths as arguments:
draw-kitten original-image.png image-with-kitten.pngThe usage of the program then might look like this:
draw-kitten --help
# Friendly program.
#
# Usage:
# draw-kitten <PATH-TO-INPUT-IMAGE> <PATH-TO-OUTPUT-IMAGE>
#
# Flags:
# --help prints this messageOrder
COMMAND [SUBCOMMANDS] [OPTIONS / FLAGS] [ARGUMENTS]Navigation
Following commands work for PowerShell, Bash, fish, Zsh.
Cheat Sheet
cd - Change Directory
# move into the folder ./path/to/else
# .. denotes the parent directory ;)
cd ./path/to/somewhere/../else# move to home dir
cd
# move to home dir; `~` == home dir
cd ~
# home dir is on Windows `C:\Users\yourUsername`# moves to the file system root
cd /
# Windows has multiple drives, thus `/` is always the root of the drive your on.
# In Unix (Linux, BSD, MacOS) there is only one root and all drives are part of it.There is a difference between relative paths and absolute paths:
- relative paths - Paths that start with
./. - absolute paths - Paths that start with a drive letter (
C:\) on windows and the root (/) on Unix.
Absolute paths are independent from the current directory of your terminal session:
# current position: C:/Users/Adam
cd /test
# current position: C:/testRelative paths are dependent on the current directory of your terminal session:
# current position: C:/Users/Adam
cd ./test
# current position: C:/Users/Adam/testAlso be aware that PowerShell accepts \ and / for paths while Unix (Linux, BSD, MacOS) only supports /.
mkdir - Make Directory
# create a new directory `new-dir-name` in the directory your currently in
mkdir new-dir-name# create a new directory `new-dir-name` in your home directory
mkdir ~/new-dir-namerm - Remove
# remove a file (permanent deletion!)
rm some-file# remove a dir (permanent deletion!)
rm some-dir# recursively delete a dir with PowerShell
rm -Recurse some-dir
# recursively delete a dir with Bash
rm -r some-dircp - Copy
# copy file_A
cp file_A file_A_copy
# now you have file_A and file_A_copy# copy a file into another dir
cp file_A ./some-dir
# now you have file_A and ./some-dir/file_A# copy a dir with Powershell
cp -Recurse dir-a dir-a-copy
# copy a dir with Bash
cp -r dir-a dir-a-copy
# you end up with the 2 dirs dir-a and dir-a-copymkdir dir-b
# copy dir-a into dir-b with Powershell
cp -Recurse dir-a dir-b
# copy dir-a into dir-b with Bash
cp -r dir-a dir-b
# you end up with dir-a and ./dir-b/dir-amv - Move
Move is very similar to copy.
# rename file_A into file_B
mv file_A file_B
# rename folder-a into folder-b
mv folder-a folder-b
# The behavior changes, if the second argument is an existing directory.
mkdir some-folder
# move file_A into some-folder
mv file_A some-folder
# move folder-a into some-folder
mv folder-a some-folder