Terminal tips
The terminal can seem scary at first but after getting used to it there will usually come a tipping point where you find it more convenient than GUI for many tasks. For example: following an online tutorial showing a series of GUI screenshots saying "click-here, check this, edit this" etc is more arduous compared to following a terminal-only tutorial where you just copy some commands into a prompt or paste into a config file.
Also see Headless Server section of this doc for advanced usage.
Ctrl + Alt + T
to open a new terminal.Ctrl + W
to close.- You can also switch from your Desktop Environment GUI to a plain TTY terminal by pressing
Ctrl + Alt + F3
(Ctrl + Alt + F2
in Gnome orCtrl + Alt + F1
in KDE to return to GUI), useful if your GUI goes haywire. - Your desktop Linux distro will come with some form of GUI terminal app such as Gnome Terminal or Konsole (you can install other terminal apps like Tilix or Terminator with better features like tiling). The terminal app runs a Shell program inside it on startup (default usually
/bin/bash
). For headless installations like Ubuntu Server, you can ONLY use the terminal as there is no GUI. - A Shell is a command interpreter; it provides a prompt to enter text commands and display text output from the command/programs. Various commands are either built into the Shell or names of executable programs or scripts that run as children of the Shell (often located in a
bin
folder listed in yourPATH
variable).- The common type of shell is
/bin/bash
. - Many advanced users like
zsh
. - The most primitive type of shell is
/bin/sh
. - The most user-friendly shell is
fish
, my favourite. Suggest checking it out after learning the basics in your default terminal.
- The common type of shell is
- A shell script is a text file containing a list of commands to execute by a particular shell interpreter. Depending on the shell, you can include if statements and possibly even loops and functions like a primitive programming language. Bash shell script is default and has a
.sh
file extension. Fish uses.fish
extension. The first line of any script is called the shebang line, and tells your OS which shell or interpreter should be used to run it. Example shebang lines:#!/bin/bash
- bash script#!/usr/bin/python
- Python script
- Most shells will run some initialization shell script by default on startup.
- The whole desktop environment GUI shell will run
~/.profile
upon login. - Bash runs
~/.bashrc
on startup. - You can add your global configuration and environment variables in these files.
- The whole desktop environment GUI shell will run
- You can pipe output of one command into another once using
|
symbol. For examplecat readme.txt
would show the contents of readme.txt file in the terminal, however you can instead pipe the contents into theless
tool to allow scrolling through a large filecat readme.txt | less
- You can also pipe to and from files using:
{command} > filename.txt
to pipe output of command into a file (overwrite).{command} >> filename.txt
to pipe output of command into a file (append).{command} < filename.txt
to pipe file contents into a command.
Basic commands
Must-know commands. Get to know these by heart:
Command | Description |
---|---|
tldr {command} | Not essential but recommend to help you learn more quickly, so I mention this first. Type sudo apt install tldr if you dont have it. Shows quick practical information about any command. A potentially more powerful alternative that I now use instead of tldr is cht.sh ⭐ |
man {command} | Show manual page for the command, with long instructions on how to use it |
pwd | Print working directory |
ls | List contents of directory (add -a to show hidden, -l to show details). A much improved alternative is exa. exa -al@ shows all files and details. |
cd {dir} | Change directory |
rm {file} | Delete file (add -rf for directory and contents) DANGEROUS COMMAND - deletes without confirmation, and no recycle bin!! Add -i for a confirmation or replace with a command that moves files to a .trash folder instead. Another good option is trash-cli ⭐ (pip install trash-cli ) |
cp {source-file} {dest-file} | Copy file or directory to another location. Multiple source files can be specified. (add -r to include directories). Use rsync for large numbers of files and to monitor progress and in some cases much faster speeds. |
mv {source-file} {dest-file} | Move file or directory to another location (note: hidden files excluded by * operator, run shopt -s dotglob to change this option) |
mv {old-name} {new-name} | Rename a file or directory |
mkdir {dir} | Create a new directory |
clear | Clear terminal output. Shortcut: Ctrl + L |
exit | Close the terminal |
Advanced commands
Learn these gradually. Use a web-search man
or tldr
for help when needed:
Command | Description |
---|---|
apropos {search-term} | Useful for finding commands. Searches through all manual pages, for commands related to search-term. |
alias | Shows all current aliases. Used to assign a long command to run a short one to reduce typing e.g. alias c=clear Add to your .basrc to persist. |
echo | Print some text to terminal. Also print contents of variables e.g. echo $PATH |
rsync | Synchronize a source directory to destination, can be used as a cp replacement for large/many files and also works with remote servers. Add -ah --progress to show progress while copying |
less | Display text from a file or stream in scrollable terminal. more is another option but only allows one way scrolling and may be slow due to loading a whole file at once |
cat | Concatenate/show text from a file or stream |
ifconfig | Show IP address, MAC and other network settings |
wget | Download a file from URL |
curl | Send/Receive data via URLs (e.g. using POST or GET) |
ln | Create symbolic link |
find | Find files e.g: find ~/ -iname *.desktop Also run a command on each search result add:-exec cp "{}" /home/shantanu/tosend \; |
locate | Find files quickly by searching file index database. In case some recent files are missing, you can manually update database sudo updatedb |
sed | Find and replace in text |
awk | Split text into fields and filter by keywords |
cut | Select and display fields from text |
grep | Regular expression (and pipe | operator). Can also be used for "Find in Files" operation, i.e. to recursively find all text files containing a given string e.g. grep -rIH 'TEXT_TO_FIND' (I = ignores binary files) |
which | Find location of an executable on path |
df | List mounted volumes ans usage, use -h to make it more readable. |
mount /umount | Mount or unmount a volume, such as a USB drive. Type fdisk -l or lsblk to list available block devices for mounting. Type findmnt or mount to show currently mounted devices. |
chmod | Change file attributes and permissions (executable, readonly etc) |
chown | Change file ownership |
watch | Run a process every 2 seconds (configurable) and monitor its output/errors. |
ps | List processes. -A to list all running processes. |
top or htop | Real-time process and performance viewer/manager |
kill or pkill | Kill or send other signals to processes |
tail | Display the last 10 lines of a text file, monitor it and display any changes - perfect for monitoring a log file. e.g. tail -f /var/log/app/status.log |
More Terminal Inspiration: Terminal all-time greats
Initialisation scripts
When a terminal is launched, there are various scripts that run automatically on startup and can be different depending on the type of session (e.g. Bash, Zsh or Fish etc), and whether login shell (where you enter user/password) or non-login shell (e.g. launching a terminal window after already logged in as a user).
You can add things like:
- Environment variables e.g.
export MYHOME="$HOME/Documents/myhome"
- Add executables to PATH e.g.
export PATH="$PATH:/path/to/apps/bin"
- Command aliases e.g.
alias c=clear
- Set default settings, e.g. colors and format for the prompt
- Autorun programs e.g. show current weather or a cool message/picture on startup
Which script file you add them to depends on whether you want the change to be specific to a user, specific to a session type, or system wide for any session.
User-specific
-
Login shell:
~/.profile
- default for all sessions~/.bash_login
- if it exists, replaces and overrides above for bash sessions~/.bash_profile
- if it exists, replaces and overrides all above for bash sessions
-
Non-login shell:
~/.bashrc
- specific to bash session~/.config/fish/config.fish
- specific to fish session
System-wide
- Login shell:
/etc/profile
- for all sessions - Non-login shell:
/etc/bash.bashrc
- specific to bash session/etc/fish/config.fish
- specific to fish session
Copy and Paste in terminal windows:
Option 1: Using the desktop-environment clipboard
- Copy: Select text by dragging mouse over text or double click to select word. The press
Ctrl+Shift+C
to copy. Alternatively,Ctrl+RightClick
brings up a context menu in many terminals that allows copying. - Paste: Paste into the terminal by pressing
Ctrl+Shift+V
. Alternatively,Ctrl+RightClick
brings up a context menu in many terminals that allows pasting.
Option 2: use the terminals own separate internal clipboard:
- Copy: Select text by dragging mouse over text or double click to select word. When you let go of the mouse button, the selected text is copied to the internal clipboard.
- Paste: Move cursor to destination and click the Middle mouse button to paste.
Option 3: using commands
- use
xclip
andxsel
commands to pipe text to and from either the terminal or system keyboards.
Generic Hotkeys
Unless specified, these should work on most shells like Bash and Fish. Consult the docs for your shell for more.
Key | Operation |
---|---|
Ctrl+L | Clear the screen |
Ctrl+C | Clear the currently entered command, or terminate currently running application |
Ctrl+K | Clear the currently entered command from cursor to end of line |
Ctrl+U | Clear the currently entered command from cursor to beginning |
Ctrl+W | Delete the current word under cursor until beginning of word |
Alt+D | Delete the current word under cursor until end of word |
Alt+L | (FISH ONLY) List files in current directory |
Move hidden files by default (in a bash shell with mv
)
When you first use mv
to move or rename folders containing files, you may notice it skips hidden files (i.e. names starting with .
), which is a concern! You can change this default setting using shopt
to edit shell options:
- Set (enable) show/move hidden files⭐:
shopt -s dotglob nullglob
- Un-set (disable) show/move hidden files:
shopt -u dotglob nullglob
Super user (sudo)
Commands are normally run as the current logged in user.
For super-user permissions run with sudo
before the command.
OR to switch the current terminal session to root: sudo -s
(limit this use, for security)
(note su
command doesn’t work in Ubuntu by default as root login is disabled)
User terminal is denoted by a $
and root/super-user terminal is denoted by #
When you run a sudo command, sometimes you want to keep the current users environment variables (e.g. settings from .bashrc
or vim config). To do this, use sudo -E
. For example, this is especially useful if you heavily customized your vim text editor for your current user and you want to be able to use the same customizations when editing as root.
WARNING: Dont be tempted to do everything as a super user or root! This is NOT like a Windows user with admin priviledges. When you run as root/sudo you are literally running programs and creating files as a different user and when you switch back you may not be able to access them! You may also break the system or have security problems when over-using root access. Stick to your regular user and only use root when needed.
Start a {command} in the terminal and allow it to continue in background after closing
{command} &
disown
GZ (gunzip) or extract a file
Zip a file or dir into archive.tar.gz (multiple files and dirs can be specified)
tar -czf archive.tar.gz {file-to-zip}
Unzip archive.tar.gz into (optional) destination dir
tar -xzf archive.tar.gz -C {dest-dir}
Add v
flag for verbose mode (list all files processed)
ZIP archiving and UNZIP extraction
sudo apt install zip unzip
zip singlefile.zip original_file
zip -r directory.zip original_dir
unzip {zipfile} -d {destination-directory}
Foreground and background app in terminal
Press Ctrl + Z
in console will set current app to background (stopped)
To go back to it, type fg
To allow the stopped background app to continue in the background, type bg
You can list child process of current shell using ($$
means current shell process):
pgrep -P $$
Then disown
them to allow running after closing the shell session
Nano: Simple default text editor in terminal
Use nano {filename}
for a simple file editor or vim
(or a fork like neovim
) if you want a lot more power and efficiency (but a steep learning curve).
Nano keyboard shortcuts: Can seem unconventional due to restrictions of key combos in terminal If you don’t like them, you may be able to use Select/Copy/Paste of your terminal instead, see Copy and Paste section above.
Shortcut | Function |
---|---|
Alt + U | Undo (shown as M-U in the terminal UI) |
Alt + E | Redo (shown as M-E) |
Ctrl + W | Search |
Alt + W | Search again |
Ctrl + X | Exit (it will ask to save, press y) |
Shift + {arrow} | Select text |
Alt + 6 | Copy |
Ctrl + K | Cut |
Ctrl + U | Paste |
Esc + 3 | Comment out selected block (default with #) |
Recommended settings:
Edit settings: sudo nano /etc/nanorc
Uncomment the following to enable line numbers, mouse, wordwrap and auto-indent:
set mouse
set linenumbers
set softwrap
set autoindent
Micro: The Best intuitive text editor in terminal
If you want a great text editor which is easy to use and powerful, and you don't want to learn Vim go with micro ⭐. If you want to know why it is so "intuitive", basically keyboard shortcuts like ctrl+Q
ctrl+C
ctrl+V
ctrl+X
ctrl+F
ctrl+A
etc all do what you expect them to do, with zero learning curve. Here is the download link (can also be installed via apt package manager, but the snap or repo releases are more up to date. Personally I used brew
to install it).
Set micro as default console editor (type which micro to get PATH_TO_MICRO):
sudo update-alternatives --install /usr/bin/editor editor PATH_TO_MICRO 50
sudo update-alternatives --config editor
sudo update-alternatives --install /usr/bin/sensible-editor sensible-editor PATH_TO_MICRO 50
sudo update-alternatives --config sensible-editor
You should also set the EDITOR=micro
environment variable if you want certain shell commands to use it as default.
Copy/Paste with SSH session to host clipboard:
Unlike Vim and Nano, Micro captures the mouse in the terminal, even when using SSH. Therefore to copy and paste text to/from a terminal SSH session host using mouse, you need to hold shift
and mouse select, then ctrl + shift + C
or shift + right click
to copy to host clipboard.
If you want to copy and paste multi-line selected text when in SSH from one file to another, do this within the same micro session, just use ctrl + c
to copy to internal micro clipboard then press ctrl + o
to open the second file and ctrl + v
to paste it.
Vim: Powerful text editor in terminal
Vim is good to learn if you want to do a lot of editing of text files, config or code, however it has a steep learning curve and is completely unusable without at least knowing some basic, such as the modes listed below.
It is a text editor with roots in the 70s, and is designed to be ultra-efficient by avoiding use of the mouse, and ultra-extensible with plugins for myriad useful functionality (see section below for essential starter plugins). It achieves this through reusing keys depending on what mode the editor is in (much easier to visualize the current mode with plugins like airline).
I prefer the neovim fork, as it's been refactored to unlock future potential. A key difference with neovim is the config file is located ~/.config/nvim/init.vim
instead of ~/.vimrc
. Another fork to check out is SpaceVim, which takes a distro-like apprach to Vim with plugins as layers depending on the type of project you are working on.
If you like neovim, try neovim-qt, a GUI wrapper which adds a few features such as drag and drop a file to open, a file tree browser, and basic mouse support (cursor, selecting/resizing sub windows and scrolling). Another upcoming GUI with VS Code style functionality using neovim, is Onivim 2.
Basic modes of Vim include:
-
Normal (DEFAULT mode at start, enter commands, navigate text quickly)
HitESC
to return to this mode any time. To get you started, some easy commands:- Search: Hit
/
and type to search text, pressenter
thenn
orN
to navigate back and forth results. - Undo:
u
Redo:Ctrl + r
- Delete (aka Cut) lines:
x
- delete current character3x
- delete 3 charactersdw
- delete current word (tryW
for WORDs)dd
- delete current line5dd
- delete five linesd$
- delete to end of lined0
- delete to beginning of line:1,.d
- delete to beginning of file:.,$d
- delete to end of file
- Switch between different panels:
Ctrl + w, w
- Search: Hit
-
Command (global commands e.g
w {name}
= save,q
= quit,e {name}
= open)
Hit:
from Normal mode to activate. -
Insert (usual text entry mode, Type text as you would expect)
Hiti
from Normal mode to activate. -
Visual Hit
v
(orV
for line-wise) from Normal mode. Allows visually selecting text with arrow keys.y
- yank (copy) selection3yy
- yank (copy) 3 lines2yw
- yank (copy) 2 words (tryW
for WORDs)p
- paste after cursorP
- paste before cursorf}
- select until next occurance of}
on current line (can be any character)F<
- select until previous occurance of<
on current line (can be any character)
-
Here is a good quick starter tutorial.
-
Some good default setup config.
-
VS Code users coming to Vim
- Intro for VS Code users
- Use NeoVim embedded in VS Code (performance can be slow)
- Make Vim into an IDE like VS Code
-
Cheat sheet within Vim plugin (see bellow to install). Highly recommended to help you learn quickly.
- Type
\
then?
to show it,q
to hide
- Type
Recommended Settings:
For Neovim, suggest adding this line to sync Vim clipboard register to system clipboard when using yank and paste:
set clipboard+=unnamedplus
Vim Plugins:
FIRST suggest to install a plugin manager such as vim-plug Add add a few good plugins to your vim config file like:
Plug 'tpope/vim-sensible'
Plug 'vim-airline/vim-airline'
Plug 'preservim/nerdtree'
Plug 'vim-airline/vim-airline-themes'
Plug 'preservim/nerdtree'
Plug 'tpope/vim-fugitive'
Plug 'scrooloose/syntastic'
Plug 'ctrlpvim/ctrlp.vim'
Plug 'lifepillar/vim-cheat40'
Plug 'ycm-core/YouCompleteMe'
# YCM: Run 'python3 install.py --all' in plugin dir (.local/share/nvim/plugged/youcompleteme/) to complete installation or update.
#YCM: If using neovim, also run 'pip install --upgrade pynvim' to enable Python support
Remember to run :PlugInstall
within Vim to complete installation after adding any plugins to.
Update plugins - :PlugUpdate
Update vim-plug itself - :PlugUpgrade
Delete a plugin - Remove it from your vim config then run :PlugClean
More:
- A list of AWESOME plugins for Vim
- A guy explaining his advanced customizations
- Setting up advanced fast auto complete (YouCompleteMe plugin and language server, remember to complete installation run
python3 install.py --all
in the plugins installed directory - normally~/.local/share/nvim/plugged/youcompleteme/
)
Open working directory in a GUI file browser window
xdg-open .
This also opens any file or folder using the default app.
Environment variables and path
To add to EVs and path, you can edit a number of files depending on requirements:
https://superuser.com/questions/789448/choosing-between-bashrc-profile-bash-profile-etc
Note that if you modify .profile
, this will only be reloaded AFTER logging in again, so you must either restart the PC or run source ~/.profile
to load it immediately. If you modify .bashrc
, you just need to restart the terminal session or source
it.
Note for Fish shell > v3.2, you can use fish_add_path
to permanently add to the path. e.g. fish_add_path /usr/local/go/bin
Cool Terminals
Alternatives to the built in terminal app (e.g. Gnome Terminal or Konsole). To change your default terminal:
sudo update-alternatives --config x-terminal-emulator
- Tilix - GPU accelerated, tiling terminal, search, pwd manager, optional ‘Quake’ mode.⭐
- hyper - Modern extensible Electron based terminal
- Alacritty - GPU accelerated, claims to be the fastest, but many question that
- cool-retro-term - Cool looking retro CRT style terminal
- Yakuake - ‘Quake’ style drop down terminal for KDE using Konsole
Cool Shells
- The popular posix compliant shell alternative to Bash: Zsh
- A UX-focused shell (my daily driver): Fish (Friendly Interactive SHell)⭐
- Type
fish_config
to launch web config GUI or edit the files (config.fish
) in~/.config/fish/
- Oh My Fish package and theme manager (
omf theme
to find themes) - Explore what fish can do online without installing.
- Oh My Fish package and theme manager (
- Type
- A UX-focused shell (my daily driver): Fish (Friendly Interactive SHell)⭐
Cool terminal addons
-
Check out this guide for a ready-to-go beautification or install various options as per below.
-
Sensible defaults for bash
-
A beautiful UX-focused shell prompt: Starship can be added to Bash, Fish, Zsh or many others ⭐