101 Bash Commands

63 views

Posted: 28 Apr 2021 (12:45)
Last Edited: 29 Apr 2021 (09:18)

Hello World

@r___75

Until about a year ago, I worked almost exclusively within the macOS and Ubuntu operating systems. On both of those OSes, bash is my default shell. I've acquired a general understanding of how bash works over the past six or seven years and would like to give an overview of some of the more common / useful commands for those just getting started. If you think you know everything there is to know about bash, take a look below anyway -- I've included some tips and reminders of flags you may have forgotten about, which could make your work a bit easier.

The commands below are laid out in a more-or-less narrative style, so if you're just getting started with bash, you can work your way through from the beginning to the end. Things generally get less common and more difficult toward the end.


The Basics


First Commands, Navigating the Filesystem

Modern filesystems have directory (folder) trees, where a directory is either a root directory (with no parent directory) or is a subdirectory (contained within a single other directory, which we call its "parent"). Traversing backwards through the file tree (from child directory to parent directory) will always get you to the root directory. Some filesystems have multiple root directories (like Windows' drives: C:\A:\, etc.), but Unix and Unix-like systems only have a single root directory called \.


pwd / ls / cd

[ Back to Table of Contents ]

When working within a filesystem, the user is always working within some directory, which we call the current directory or the working directory. Print the user's working directory with pwd:

[ andrew@pc01 ~ ]$ pwd
/home/andrew


List the contents of this directory (files and/or child directories, etc.) with ls:

[ andrew@pc01 ~ ]$ ls
Git  TEST  jdoc  test  test.file


Bonus:
Show hidden ("dot") files with ls -a
Show file details with ls -l
Combine multiple flags like ls -l -a
You can sometimes chain flags like ls -la instead of ls -l -a

Change to a different directory with cd (change directory):

[ andrew@pc01 ~ ]$ cd TEST/

[ andrew@pc01 TEST ]$ pwd
/home/andrew/TEST

[ andrew@pc01 TEST ]$ cd A

[ andrew@pc01 A ]$ pwd
/home/andrew/TEST/A


cd .. is shorthand for "cd to the parent directory”:

[ andrew@pc01 A ]$ cd ..

[ andrew@pc01 TEST ]$ pwd
/home/andrew/TEST


cd ~ or just cd is shorthand for "cd to my home directory" (usually /home/username or something similar):

[ andrew@pc01 TEST ]$ cd

[ andrew@pc01 ~ ]$ pwd
/home/andrew


Bonus:
cd ~user means "cd to user's home directory
You can jump multiple directory levels with cd ../.., etc.
Go back to the most recent directory with cd -
. is shorthand for "this directory", so cd . won't do much of anything


; / && / &

[ Back to Table of Contents ]

The things we type into the command line are called commands, and they always execute some machine code stored somewhere on your computer. Sometimes this machine code is a built-in Linux command, sometimes it's an app, sometimes it's some code that you wrote yourself. Occasionally, we'll want to run one command right after another. To do that, we can use the ; (semicolon):

[ andrew@pc01 ~ ]$ ls; pwd
Git  TEST  jdoc  test  test.file
/home/andrew


Above, the semicolon means that I first (ls) list the contents of the working directory, and then I (pwd) print its location. Another useful tool for chaining commands is &&. With &&, the command to the right will not run if the command to the left fails. ; and && can both be used multiple times on the same line:

# whoops! I made a typo here!
[ andrew@pc01 ~ ]$ cd /Giit/Parser && pwd && ls && cd
-bash: cd: /Giit/Parser: No such file or directory

# the first command passes now, so the following commands are run
[ andrew@pc01 ~ ]$ cd Git/Parser/ && pwd && ls && cd
/home/andrew/Git/Parser
README.md  doc.sh  pom.xml  resource  run.sh  shell.sh  source  src  target


...but with ;, the second command will run even if the first one fails:

# pwd and ls still run, even though the cd command failed
[ andrew@pc01 ~ ]$ cd /Giit/Parser ; pwd ; ls
-bash: cd: /Giit/Parser: No such file or directory
/home/andrew
Git  TEST  jdoc  test  test.file


& looks similar to && but actually fulfils a completely different function. Normally, when you execute a long-running command, the command line will wait for that command to finish before it allows you to enter another one. Putting & after a command prevents this from happening, and lets you execute a new command while an older one is still going:

[ andrew@pc01 ~ ]$ cd Git/Parser && mvn package & cd
[1] 9263


Bonus: When we use & after a command to "hide" it, we say that the job (or the "process"; these terms are more or less interchangeable) is "backgrounded". To see what background jobs are currently running, use the jobs command:
[ andrew@pc01 ~ ]$ jobs
[1]+ Running cd Git/Parser/ && mvn package &


Getting Help


-h

[ Back to Table of Contents ]

Type -h or --help after almost any command to bring up a help menu for that command:

[ andrew@pc01 ~ ]$ du --help
Usage: du [OPTION]... [FILE]...
  or:  du [OPTION]... --files0-from=F
Summarize disk usage of the set of FILEs, recursively for directories.

Mandatory arguments to long options are mandatory for short options too.
  -0, --null            end each output line with NUL, not newline
  -a, --all             write counts for all files, not just directories
      --apparent-size   print apparent sizes, rather than disk usage; although
                          the apparent size is usually smaller, it may be
                          larger due to holes in ('sparse') files, internal
                          fragmentation, indirect blocks, and the like
  -B, --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                           '-BM' prints sizes in units of 1,048,576 bytes;
                           see SIZE format below
...



man

[ Back to Table of Contents ]

Type man before almost any command to bring up a manual for that command (quit man with q):

LS(1)                            User Commands                           LS(1)

NAME
       ls - list directory contents

SYNOPSIS
       ls [OPTION]... [FILE]...

DESCRIPTION
       List  information  about  the FILEs (the current directory by default).
       Sort entries alphabetically if none of -cftuvSUX nor --sort  is  speci-
       fied.

       Mandatory  arguments  to  long  options are mandatory for short options
       too.
...



Viewing and Editing Files


head / tail / cat / less

[ Back to Table of Contents ]

head outputs the first few lines of a file. The -n flag specifies the number of lines to show (the default is 10):

# prints the first three lines
[ andrew@pc01 ~ ]$ head -n 3 c
this
file
has


tail outputs the last few lines of a file. You can get the last n lines (like above), or you can get the end of the file beginning from the N-th line with tail -n +N:

# prints the end of the file, beginning with the 4th line
[ andrew@pc01 ~ ]$ tail -n +4 c
exactly
six
lines


cat concatenates a list of files and sends them to the standard output stream (usually the terminal). cat can be used with just a single file, or multiple files, and is often used to quickly view them. (Be warned: if you use cat in this way, you may be accused of a Useless Use of Cat (UUOC), but it's not that big of a deal, so don't worry too much about it.)

[ andrew@pc01 ~ ]$ cat a
file a

[ andrew@pc01 ~ ]$ cat a b
file a
file b


less is another tool for quickly viewing a file -- it opens up a vim-like read-only window. (Yes, there is a command called more, but less -- unintuitively -- offers a superset of the functionality of more and is recommended over it.) Learn more (or less?) about less and more at their man pages.


nano / nedit

[ Back to Table of Contents ]

nano is a minimalistic command-line text editor. It's a great editor for beginners or people who don't want to learn a million shortcuts. It was more than sufficient for me for the first few years of my coding career (I'm only now starting to look into more powerful editors, mainly because defining your own syntax highlighting in nano can be a bit of a pain.)

nedit is a small graphical editor, it opens up an X Window and allows point-and-click editing, drag-and-drop, syntax highlighting and more. I use nedit sometimes when I want to make small changes to a script and re-run it over and over.

Other common CLI (command-line interface) / GUI (graphical user interface) editors include emacsvivimgedit, Notepad++, Atom, and lots more. Some cool ones that I've played around with (and can endorse) include Micro, Light Table, and VS Code.

All modern editors offer basic conveniences like search and replace, syntax highlighting, and so on. vi(m) and emacs have more features than nano and nedit, but they have a much steeper learning curve. Try a few different editors out and find one that works for you!


Creating and Deleting Files and Directories


touch

[ Back to Table of Contents ]

touch was created to modify file timestamps, but it can also be used to quickly create an empty file. You can create a new file by opening it with a text editor, like nano:

[ andrew@pc01 ex ]$ ls

[ andrew@pc01 ex ]$ nano a


...editing file...

[ andrew@pc01 ex ]$ ls
a


...or by simply using touch:

[ andrew@pc01 ex ]$ touch b && ls
a  b


Bonus:
Background a process with ^z (Ctrl+z)
[ andrew@pc01 ex ]$ nano a
...editing file, then hit ^z...
Use fg to return to nano

[1]+ Stopped nano a
[ andrew@pc01 ex ]$ fg
...editing file again...
Double Bonus:
Kill the current (foreground) process by pressing ^c (Ctrl+c) while it’s running
Kill a background process with kill %N where N is the job index shown by the jobs command


mkdir / rm / rmdir

[ Back to Table of Contents ]

mkdir is used to create new, empty directories:

[ andrew@pc01 ex ]$ ls && mkdir c && ls
a  b
a  b  c


You can remove any file with rm -- but be careful, this is non-recoverable!

[ andrew@pc01 ex ]$ rm a && ls
b  c


You can add an "are you sure?" prompt with the -i flag:

[ andrew@pc01 ex ]$ rm -i b
rm: remove regular empty file 'b'? y


Remove an empty directory with rmdir. If you ls -a in an empty directory, you should only see a reference to the directory itself (.) and a reference to its parent directory (..):

[ andrew@pc01 ex ]$ rmdir c && ls -a
.  ..


rmdir removes empty directories only:

[ andrew@pc01 ex ]$ cd .. && ls test/
*.txt  0.txt  1.txt  a  a.txt  b  c

[ andrew@pc01 ~ ]$ rmdir test/
rmdir: failed to remove 'test/': Directory not empty


...but you can remove a directory -- and all of its contents -- with rm -rf (-r = recursive, -f = force):

[ andrew@pc01 ~ ]$ rm –rf test



Moving and Copying Files, Making Links, Command History


mv / cp / ln

[ Back to Table of Contents ]

mv moves / renames a file. You can mv a file to a new directory and keep the same file name or mv a file to a "new file" (rename it):

[ andrew@pc01 ex ]$ ls && mv a e && ls
a  b  c  d
b  c  d  e


cp copies a file:

[ andrew@pc01 ex ]$ cp e e2 && ls
b  c  d  e  e2


ln creates a hard link to a file:

# first argument to ln is TARGET, second is NEW LINK
[ andrew@pc01 ex ]$ ln b f && ls
b  c  d  e  e2  f


ln -s creates a soft link to a file:

[ andrew@pc01 ex ]$ ln -s b g && ls
b  c  d  e  e2  f  g


Hard links reference the same actual bytes in memory which contain a file, while soft links refer to the original file name, which itself points to those bytes. You can read more about soft vs. hard links here.


Command History

[ Back to Table of Contents ]

bash has two big features to help you complete and re-run commands, the first is tab completion. Simply type the first part of a command, hit the <tab> key, and let the terminal guess what you're trying to do:

[ andrew@pc01 dir ]$ ls <ENTER>
anotherlongfilename  thisisalongfilename  anewfilename

[ andrew@pc01 dir ]$ ls t <TAB>


...hit the TAB key after typing ls t and the command is completed...

[ andrew@pc01 dir ]$ ls thisisalongfilename <ENTER>
thisisalongfilename


You may have to hit <TAB> multiple times if there's an ambiguity:

[ andrew@pc01 dir ]$ ls a <TAB>

[ andrew@pc01 dir ]$ ls an <TAB>
anewfilename  anotherlongfilename


bash keeps a short history of the commands you've typed previously and lets you search through those commands by typing ^r (Ctrl+r):

[ andrew@pc01 dir ]


...hit ^r (Ctrl+r) to search the command history...

(reverse-i-search)`':


...type 'anew' and the last command containing this is found...

(reverse-i-search)`anew': touch anewfilename



Directory Trees, Disk Usage, and Processes


mkdir –p / tree

[ Back to Table of Contents ]

mkdir, by default, only makes a single directory. This means that if, for instance, directory d/e doesn't exist, then d/e/f can't be made with mkdir by itself:

[ andrew@pc01 ex ]$ ls && mkdir d/e/f
a  b  c
mkdir: cannot create directory 'd/e/f': No such file or directory


But if we pass the -p flag to mkdir, it will make all directories in the path if they don't already exist:

[ andrew@pc01 ex ]$ mkdir -p d/e/f && ls
a  b  c  d


tree can help you better visualise a directory's structure by printing a nicely-formatted directory tree. By default, it prints the entire tree structure (beginning with the specified directory), but you can restrict it to a certain number of levels with the -L flag:

[ andrew@pc01 ex ]$ tree -L 2
.
|-- a
|-- b
|-- c
`-- d
    `--e

3 directories, 2 files


You can hide empty directories in tree's output with --prune. Note that this also removes "recursively empty" directories, or directories which aren't empty per se, but which contain only other empty directories, or other recursively empty directories:

[ andrew@pc01 ex ]$ tree --prune
.
|-- a
`-- b



df / du / ps

[ Back to Table of Contents ]

df is used to show how much space is taken up by files for the disks or your system (hard drives, etc.).

[ andrew@pc01 ex ]$ df -h
Filesystem                   Size  Used Avail Use% Mounted on
udev                         126G     0  126G   0% /dev
tmpfs                         26G  2.0G   24G   8% /run
/dev/mapper/ubuntu--vg-root  1.6T  1.3T  252G  84% /
...


In the above command, -h doesn't mean "help", but "human-readable". Some commands use this convention to display file / disk sizes with K for kilobytes, G for gigabytes, and so on, instead of writing out a gigantic integer number of bytes.

du shows file space usage for a particular directory and its subdirectories. If you want to know how much space is free on a given hard drive, use df; if you want to know how much space a directory is taking up, use du:

[ andrew@pc01 ex ]$ du
4       ./d/e/f
8       ./d/e
12      ./d
4       ./c
20      .


du takes a --max-depth=N flag, which only shows directories N levels down (or fewer) from the specified directory:

[ andrew@pc01 ex ]$ du -h --max-depth=1
12K     ./d
4.0K    ./c
20K     .


ps shows all of the user's currently-running processes (aka. jobs):

[ andrew@pc01 ex ]$ ps
  PID TTY          TIME CMD
16642 pts/15   00:00:00 ps
25409 pts/15   00:00:00 bash



Miscellaneous


passwd / logout / exit

[ Back to Table of Contents ]

Change your account password with passwd. It will ask for your current password for verification, then ask you to enter the new password twice, so you don't make any typos:

[ andrew@pc01 dir ]$ passwd
Changing password for andrew.
(current) UNIX password:    <type current password>
Enter new UNIX password:    <type new password>
Retype new UNIX password:   <type new password again>
passwd: password updated successfully


logout exits a shell you’ve logged in to (where you have a user account):

[ andrew@pc01 dir ]$ logout

──────────────────────────────────────────────────────────────────────────────
Session stopped
    - Press <return> to exit tab
    - Press R to restart session
    - Press S to save terminal output to file


exit exits any kind of shell:

[ andrew@pc01 ~ ]$ exit
logout

──────────────────────────────────────────────────────────────────────────────
Session stopped
    - Press <return> to exit tab
    - Press R to restart session
    - Press S to save terminal output to file



clear / *

[ Back to Table of Contents ]

Run clear to move the current terminal line to the top of the screen. This command just adds blank lines below the current prompt line. It's good for clearing your workspace.

Use the glob (*, aka. Kleene Star, aka. wildcard) when looking for files. Notice the difference between the following two commands:




Tags


tech linux programming bash cmd

Comments