Linux
Linux
Linux
of Contents
About 1.1
Linux Introduction 1.2
Command Line Introduction 1.3
Files and Directories 1.4
Working with Files and Directories 1.5
Text Processing 1.6
Shell 1.7
Shell Customization 1.8
Shell Scripting 1.9
1
About
Linux curated resources for more complete resources list, including tutorials for beginners
For more related resources, visit scripting course
Chapters
Linux Introduction
What is Linux?, Why use Linux?, Where is Linux deployed?, Linux Distros, Linux resource lists
Command Line Introduction
File System, Command Line Interface, Command Help, Do one thing and do it well
Files and Directories
pwd, clear, ls, cd, mkdir, touch, rm, cp, mv, rename, ln, tar and gzip
Working with Files and Directories
cat, less, tail, head, Text Editors, grep, find, locate, wc, du, df, touch, file, identify, basename, dirname, chmod
Text Processing
sort, uniq, comm, cmp, diff, tr, sed, awk, perl, cut, paste, column, pr
Shell
What is Shell?, Popular Shells, Wildcards, Redirection, Process Control, Running jobs in background
Shell Customization
Variables, Config files, Emac mode Readline shortcuts
Shell Scripting
Need for scripting, Hello script, Command Line Arguments, Variables and Comparisons, Accepting User Input
interactively, if then else, for loop, while loop, Debugging, Resource lists
ebook
Read as ebook on gitbook
Download ebook for offline reading - link
Acknowledgements
unix.stackexchange and stackoverflow - for getting answers to pertinent questions as well as sharpening skills by
2
About
License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
3
Linux Introduction
Linux Introduction
Table of Contents
What is Linux?
Why use Linux?
Where is Linux deployed?
Linux Distros
Linux resource lists
What is Linux?
Quoting from Wikipedia
Linux is a family of free and open-source software operating systems built around the Linux kernel. Typically,
Linux is packaged in a form known as a Linux distribution (or distro for short) for both desktop and server use. The
defining component of a Linux distribution is the Linux kernel, an operating system kernel first released on
September 17, 1991, by Linus Torvalds. Many Linux distributions use the word "Linux" in their name. The Free
Software Foundation uses the name GNU/Linux to refer to the operating system family, as well as specific
distributions, to emphasize that most Linux distributions are not just the Linux kernel, and that they have in
common not only the kernel, but also numerous utilities and libraries, a large proportion of which are from the
GNU project
4
Linux Introduction
Smart phones
Android - built on top of Linux kernel
iOS - Unix based
Personal and Enterprise Computers
And many more uses, thanks to being open source
Usage Share of Operating Systems
Linux Distros
There are various Linux flavors called 'distribution' (distro for short), to cater the needs of beginners to advanced users
as well as highly customized as per end use case
Installation
Usually, you'll find installation instructions from respective website of the distro you chose. If you need an overview of
installation process, this should help
5
Command Line Introduction
File System
Absolute and Relative paths
Command Line Interface
Command Help
Do one thing and do it well
Command Structure
Command Network
For any thing that is repetitive or programmable, there likely is a relevant command. Ask your peers or search online
before you start writing a script. Just remember that Unix was first introduced in late 1960s - there is likely to be a
command for what you need
Starting trouble with command line (for those accustomed to GUI) is the sudden trouble of interacting with the computer
using just text commands. After using for a week or so, things will seem very systematic and GUI feels ill suited for
frequent tasks. With continuous use, recalling various commands becomes easier. Short-cuts, history, aliases and tab-
completion help in the process
If you've used a scientific calculator, you'd know that it is handy with too many functionalities cramped into tiny screen
and plethora of multi-purpose buttons. Commands and short-cuts pack much more punch than that on a terminal
Commands presented here are Linux specific and generally behave similarly across distros
Commands in Linux usually have added features compared to POSIX specification
If any command is not found in a particular distro, either it has to be manually installed or probably an alternate
exists
The bash shell version 4+ is used throughout this material
rough overview of changes to Bash over time
File System
Before we dive into ocean of commands, lets get a brief on Linux file system. If you've used Windows, you would be
familiar with C: D: etc.
In Linux, directory structure starts with / symbol, which is referred as the root directory
6
Command Line Introduction
/usr This directory is usually mounted from a separate partition. It should hold only sharable, read-only data,
which are not needed for booting or for repairing the system and which are not installed locally should be
placed in this directory.
/usr/share This directory contains subdirectories with specific application data, that can be shared among
different architectures of the same OS. Often one finds stuff here that used to live in /usr/doc or /usr/lib or
/usr/man.
An absolute or full path points to the same location in a file system regardless of the current working directory.
To do that, it must contain the root directory.
By contrast, a relative path starts from some given working directory, avoiding the need to provide the full
absolute path. A filename can be considered as a relative path based at the current working directory. If the
working directory is not the file's parent directory, a file not found error will result if the file is addressed by its
name.
Further Reading
For example: the cd command would help navigating to a particular directory and ls command to view contents of a
directory. In GUI, you'd use an explorer for directory navigation by point and click, directory contents are shown by
default
Shell and Terminal are sometimes interchangeably used to mean the same thing - a prompt where user types and
executes commands. However, they are quite different
Shell is command line interpreter, sets the syntax rules for invoking commands, etc
Terminal text input/output environment, responsible for visual details like font size, color, etc
We'll learn more about Shell in later chapters. For now, open a Terminal and try these commands by typing them and
pressing Enter key. You can spot the command lines by the prompt $ at start of line
7
Command Line Introduction
$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/bin/tcsh
/usr/bin/tcsh
$ echo "$SHELL"
/bin/bash
Note: Your command prompt might be different, for now you can leave it as or change it to the simple prompt I prefer by
executing PS1="$ "
In the above example, cat command is used to display contents of a file and echo command is used to display
contents of a variable - these commands have other uses as well, which will be covered later on
Command Help
Most distros for personal use come with documentation for commands already installed. Getting used to reading
manual from terminal is handy and there are various ways to get specific information
usually displayed using less command, press q key to quit the man page and h key to get help
for Linux commands, the info command gives the complete documentation
you could also read them online, for ex: GNU Coreutils manual has manuals for most of the commands
covered in this material
man man will give details about the man command itself
man bash will give you the manual page for bash
man find | gvim - to open the manual page in your favorite text editor
man -k printf will search the short descriptions in all the manual pages for the string printf
-k here is a command option
man -k is equivalent for apropos command
Excellent resource unix.stackexchange: How do I use man pages to learn how to use commands?
For certain operations, shell provides its own set of commands, referred as builtin commands
8
Command Line Introduction
$ type cd
cd is a shell builtin
$ type sed
sed is /bin/sed
$ type ls
ls is aliased to `ls --color=auto'
$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls
-d option gives short description for each topic, similar to whatis command
help command by itself without any argument displays all shell commands that are defined internally
$ help pwd
pwd: pwd [-LP]
Print the name of the current working directory.
Options:
-L print the value of $PWD if it names the current working directory
-P print the physical directory, without any symbolic links
Exit Status:
Returns 0 unless an invalid option is given or the current directory
cannot be read.
$ help -d compgen
compgen - Display possible completions depending on the options.
9
Command Line Introduction
$ whatis grep
grep (1) - print lines matching a pattern
$ whereis awk
awk: /usr/bin/awk /usr/share/awk /usr/share/man/man1/awk.1.gz
$ ch sort -k
sort - sort lines of text files
-k, --key=KEYDEF
sort via a key; KEYDEF gives location and type
Examples given below are for demonstration purposes only, more detail in later chapters
Command Structure
only the command
df -h report file system disk space usage, print sizes in human readable format (e.g., 1K 234M 2G)
single quotes preserves the literal value of each character within the quotes
double quotes preserves the literal value of all characters within the quotes, with the exception of '$', '`', '\', and,
when history expansion is enabled, '!'
10
Command Line Introduction
$ echo '$SHELL'
$SHELL
$ echo "$SHELL"
/bin/bash
Command Network
Redirecting output of a command
to another command
du -sh * | sort -h calculate size of files/folders, display size in human-readable format which is then sorted
grep 'error' *.log >> errors.txt appends to file (creates new file if necessary)
to a variable
p=$(pwd) saves the output of pwd command in variable p , there should be no spaces around =
Redirecting input
wc -l < file.txt useful to get just the number of lines, without displaying file name
tr 'a-z' 'A-Z' < ip.txt some commands like tr only work on stdin
Redirecting error
xyz 2> cmderror.log assuming a non-existent command xyz , it would give an error and gets redirected to
specified file
comm -23 <(sort file1.txt) <(sort file2.txt) process substitution, avoids need to create temporary files
(head -n5 ~/.vimrc ; tail -n5 ~/.vimrc) > vimrc_snippet.txt multiple commands (separated by ; ) can be
grouped inside a list
Command substitution
sed -i "s|^|$(basename $PWD)/|" dir_list.txt add current directory path and forward-slash character at the
11
Command Line Introduction
12
Files and Directories
pwd
cd
clear
ls
mkdir
touch
rm
cp
mv
rename
ln
tar and gzip
Let's look at commonly used commands to navigate directories, create and modify files and directories. For certain
commands, a list of commonly used options are also given
Make it a habit to use man command to read about a new command - for example man ls
Short descriptions for commands are shown as quoted text (taken from whatis or help -d )
pwd
print name of current/working directory
apart from knowing your current working directory, often used to copy the absolute path to be pasted elsewhere,
like in a script
some Terminal emulators display the current directory path as window/tab title
$ pwd
/home/learnbyexample
cd
Change the shell working directory
13
Files and Directories
$ pwd
/home/learnbyexample
$ pwd
/home/learnbyexample
cd ~/ or cd ~ or cd will go to directory specified by HOME shell variable (which is usually set to user's home
directory)
$ pwd
/
$ echo "$HOME"
/home/learnbyexample
$ cd
$ pwd
/home/learnbyexample
Further Reading
14
Files and Directories
clear
clear the terminal screen
You can also use Ctrl+l short-cut to clear the Terminal screen (in addition, this retains any typed text)
ls
list directory contents
workshop_brochures:
Python_workshop_2017.pdf Scripting_course_2016.pdf
-F appends a character to each file name indicating the file type (other than regular files)
/ for directories
* for executable files
@ for symbolic links
| for FIFOs
= for sockets
> for doors
the indicator details are described in info ls , not in man ls
15
Files and Directories
$ ls -F
backups/ hello_world.py* palindrome.py* projects@ todo
ch.sh* ip.txt power.log report.log workshop_brochures/
$ ls -l
total 84
drwxrwxr-x 3 learnbyexample eg 4096 Jul 4 18:23 backups
-rwxr-xr-x 1 learnbyexample eg 2746 Mar 30 11:38 ch.sh
-rwxrwxr-x 1 learnbyexample eg 41 Aug 21 2017 hello_world.py
-rw-rw-r-- 1 learnbyexample eg 34 Jul 4 09:01 ip.txt
-rwxrwxr-x 1 learnbyexample eg 1236 Aug 21 2017 palindrome.py
-rw-r--r-- 1 learnbyexample eg 10449 Mar 8 2017 power.log
lrwxrwxrwx 1 learnbyexample eg 12 Jun 21 12:08 projects -> ../projects/
-rw-rw-r-- 1 learnbyexample eg 39120 Feb 25 2017 report.log
-rw-rw-r-- 1 learnbyexample eg 5987 Apr 11 11:06 todo
drwxrwxr-x 2 learnbyexample eg 4096 Jul 5 12:05 workshop_brochures
16
Files and Directories
$ ls -lhtr
total 84K
-rw-rw-r-- 1 learnbyexample eg 39K Feb 25 2017 report.log
-rw-r--r-- 1 learnbyexample eg 11K Mar 8 2017 power.log
-rwxrwxr-x 1 learnbyexample eg 1.3K Aug 21 2017 palindrome.py
-rwxrwxr-x 1 learnbyexample eg 41 Aug 21 2017 hello_world.py
-rwxr-xr-x 1 learnbyexample eg 2.7K Mar 30 11:38 ch.sh
-rw-rw-r-- 1 learnbyexample eg 5.9K Apr 11 11:06 todo
lrwxrwxrwx 1 learnbyexample eg 12 Jun 21 12:08 projects -> ../projects/
-rw-rw-r-- 1 learnbyexample eg 34 Jul 4 09:01 ip.txt
drwxrwxr-x 3 learnbyexample eg 4.0K Jul 4 18:23 backups
drwxrwxr-x 2 learnbyexample eg 4.0K Jul 5 12:05 workshop_brochures
$ ls -X
backups todo power.log hello_world.py ch.sh
projects workshop_brochures report.log palindrome.py ip.txt
$ ls -ARF
.:
backups/ hello_world.py* palindrome.py* projects@ todo
ch.sh* ip.txt power.log report.log workshop_brochures/
./backups:
chrome_bookmarks_02_07_2018.html dot_files/
./backups/dot_files:
.bashrc .inputrc .vimrc
./workshop_brochures:
Python_workshop_2017.pdf Scripting_course_2016.pdf
you might have to install this command or have an equivalent command like gvfs-tree
17
Files and Directories
18
Files and Directories
$ echo b*
backups
$ # since backups is a directory, ls will list its contents
$ ls b*
chrome_bookmarks_02_07_2018.html dot_files
$ # -d option will show the directory entry instead of its contents
$ ls -d b*
backups
Further Reading
mkdir
make directories
Linux filenames can use any character other than / and the ASCII NUL character
quote the arguments if name contains characters like space, * , etc to prevent shell interpretation
shell considers space as argument separator, * is a globbing character, etc
unless otherwise needed, try to use only alphabets, numbers and underscores for filenames
19
Files and Directories
$ mkdir reports
mkdir: cannot create directory ‘reports’: File exists
$ echo $?
1
$ # when -p is used, mkdir won't give an error if directory already exists
$ mkdir -p reports
$ echo $?
0
a/b:
c
a/b/c:
Further Reading
touch
Usually files are created using a text editor or by redirecting output of a command to a file
But sometimes, for example to test file renaming, creating empty files comes in handy
the touch command is primarily used to change timestamp of a file (see touch section of next chapter)
if a filename given to touch doesn't exist, an empty file gets created with current timestamp
$ touch ip.txt
$ ls -1F
a/
ip.txt
low power adders/
reports/
rm
remove files and directories
20
Files and Directories
use -f option to force remove without prompt for non-existing files and write protected files (provided user has
appropriate permissions)
$ ls
a ip.txt low power adders reports
$ rm ip.txt
$ ls
a low power adders reports
$ rm reports
rm: cannot remove 'reports': Is a directory
$ rm -r reports
$ ls
a low power adders
typos like misplaced space, wrong glob, etc could wipe out files not intended for deletion
apart from having backups and snapshots, one could take some mitigating steps
using -i option to interactively delete each file
using echo as a dry run to see how the glob expands
using a trash command (see links below) instead of rm
$ rm -ri a
rm: descend into directory 'a'? y
rm: descend into directory 'a/b'? y
rm: remove directory 'a/b/c'? y
rm: remove directory 'a/b'? y
rm: remove directory 'a'? y
$ ls
low power adders
Further Reading
See if a trash command is available for your distro (for ex: gvfs-trash on Ubuntu) - this will send items to trash
instead of deletion
or, unix.stackexchange: creating a simple trash command
Files removed using rm can still be recovered with time/skill. Use shred command to overwrite files
unix.stackexchange: recover deleted files
unix.stackexchange: recovering accidentally deleted files
wiki.archlinux: Securely wipe disk
rm Q&A on unix stackexchange
rm Q&A on stackoverflow
21
Files and Directories
cp
copy files and directories
to copy a single file or directory, specify the source as first argument and destination as second argument
similar to rm command, use -r for directories
$ # when destination is a directory, specified sources are placed inside that directory
$ # recall that . is a relative path referring to current directory
$ cp /usr/share/dict/words .
$ ls
low power adders words
$ cp /usr/share/dict .
cp: omitting directory '/usr/share/dict'
$ cp -r /usr/share/dict .
$ ls -1F
dict/
low power adders/
words
$ cp /usr/share/dict/words words_ref.txt
$ cp -r /usr/share/dict word_lists
$ ls -1F
dict/
low power adders/
word_lists/
words
words_ref.txt
multiple files and directories can be copied at once if the destination is a directory
using -t option, one could specify destination directory first followed by sources (this is helpful with find
command and other places)
$ mkdir bkp_dot_files
see man cp and info cp for more options and complete documentation
some notable options are
-u copy files from source only if they are newer than those in destination or if it doesn't exist in destination
location
-b and --backup for back up options if file with same name already exists in destination location
--preserve option to copy files along with source file attributes like timestamp
Further Reading
22
Files and Directories
rsync examples
rsync Q&A on unix stackexchange
rsync Q&A on stackoverflow
mv
move (rename) files
$ ls
bkp_dot_files dict low power adders word_lists words words_ref.txt
$ mkdir backups
$ mv bkp_dot_files/ backups/
$ ls -F
backups/ dict/ low power adders/ word_lists/ words words_ref.txt
$ ls -F backups/
bkp_dot_files/
like cp command, for single file/directory one can provide a different destination name
so, when source and destination has same parent directory, mv acts as renaming command
$ mv backups/bkp_dot_files backups/dot_files
$ ls -F backups/
dict/ dot_files/ words
Further Reading
rename
renames multiple files
23
Files and Directories
Note: The perl based rename is presented here which is different from util-linux-ng version. Check man rename for
details
$ ls
backups low power adders word_lists words_ref.txt
$ # here, the * glob will expand to all non-hidden files in current directory
$ # -n option is for dry run, to see changes before actually renaming files
$ # s/ /_/g means replace all space characters with _ character
$ rename -n 's/ /_/g' *
rename(low power adders, low_power_adders)
Further Reading
ln
make links between files
hard link can only point to another file (not a directory, and restricted to within the same filesystem)
24
Files and Directories
the . and .. special directories are the exceptions, they are hard links which are automatically created
once a hard link is created, there is no distinction between the two files other than different filename/location - they
have same inode, permissions, timestamps, etc
any of the hard link will continue working even if all the other hard links are deleted
if a hard link is moved to another location, the links will still be in sync - any change in one of them will be reflected
in all the other links
$ touch foo.txt
$ ln foo.txt baz.txt
Further Reading
first, lets see an example of creating single archive file from multiple input files
note that the archive file so created is a new file and doesn't overwrite input files
$ ls -F
backups/ low_power_adders/ word_lists/ words_ref.txt
$ ls -F
backups/ bkp_words.tar low_power_adders/ word_lists/ words_ref.txt
$ ls -sh bkp_words.tar
2.3M bkp_words.tar
25
Files and Directories
$ gzip bkp_words.tar
$ ls -F
backups/ bkp_words.tar.gz low_power_adders/ word_lists/ words_ref.txt
$ ls -sh bkp_words.tar.gz
652K bkp_words.tar.gz
$ gunzip bkp_words.tar.gz
$ ls -F
backups/ bkp_words.tar low_power_adders/ word_lists/ words_ref.txt
$ ls -sh bkp_words.tar
2.3M bkp_words.tar
$ mkdir test_extract
$ mv bkp_words.tar test_extract/
$ cd test_extract/
$ ls
bkp_words.tar
$ ls -F
backups/ low_power_adders/ word_lists/ words_ref.txt
there are loads of options for various needs, see documentation for details
-v for verbose option
-r to append files to archive
-t to list contents of archive
--exclude= to specify files to be ignored from archiving
-j and -J to use bzip2 or xz compression technique instead of -z which uses gzip
26
Files and Directories
Further Reading
27
Working with Files and Directories
In this chapter, we will see how to display contents of a file, search within files, search for files, get file properties and
information, what are the permissions for files/directories and how to change them to our requirements
cat
concatenate files and print on the standard output
Options
Examples
One or more files can be given as input and hence a lot of times, cat is used to quickly see contents of small
single file on terminal
But not needed to simply pass file content as stdin to other commands. See Useless Use of Cat Award
To save the output of concatenation, just redirect stdout
28
Working with Files and Directories
$ ls
marks_2015.txt marks_2016.txt marks_2017.txt
$ cat marks_201*
Name Maths Science
foo 67 78
bar 87 85
Name Maths Science
foo 70 75
bar 85 88
Name Maths Science
foo 68 76
bar 90 90
often used option is -A to see various non-printing characters and end of line
$ tac marks_2015.txt
bar 87 85
foo 67 78
Name Maths Science
$ seq 3 | tac
3
2
1
Further Reading
For more detailed examples and discussion, see section cat from command line text processing repo
cat Q&A on unix stackexchange
cat Q&A on stackoverflow
less
opposite of more
cat command is not suitable for viewing contents of large files on the Terminal. less displays contents of a file,
automatically fits to size of Terminal, allows scrolling in either direction and other options for effective viewing. Usually,
man command uses less command to display the help page. The navigation options are similar to vi editor
Commonly used commands are given below, press h for summary of options
29
Working with Files and Directories
g go to start of file
G go to end of file
q quit
N go to previous pattern
less -s large_filename display contents of file large_filename using less command, consecutive blank lines are
tail
output the last part of files
Examples
$ # all lines starting from 3rd line i.e all lines except first two lines
$ seq 13 17 | tail -n +3
15
16
17
characterwise extraction
Note that this works byte wise and not suitable for multi-byte character encodings
30
Working with Files and Directories
Further Reading
For more detailed examples and discussion, see section tail from command line text processing repo
tail Q&A on unix stackexchange
tail Q&A on stackoverflow
head
output the first part of files
Examples
$ # tail gives last 10 lines, head then gives first 2 from tail output
$ tail sample.txt | head -n2
Just do-it
Believe it
Good day
characterwise extraction
31
Working with Files and Directories
Note that this works byte wise and not suitable for multi-byte character encodings
Further Reading
For more detailed examples and discussion, see section head from command line text processing repo
head Q&A on unix stackexchange
Text Editors
For editing text files, the following applications can be used. Of these, gedit , nano , vi and/or vim are available in
most distros by default
Easy to use
gedit
geany
nano
vim
vim learning resources and vim reference for further info
emacs
atom
sublime
grep
print lines matching a pattern
grep stands for Global Regular Expression Print. Used to search for a pattern in given files - whether a particular
word or pattern is present (or not present), name of files containing the pattern, etc. By default, matching is performed in
any part of a line, options and regular expressions can be used to match only the desired part
Options
--color=auto display the matched pattern, file names, line numbers etc with color distinction
-i ignore case while matching
-v print non-matching lines, i.e it inverts the selection
-n print also line numbers of matched pattern
32
Working with Files and Directories
-F interpret pattern to search as fixed string (i.e not a regular expression). Faster as well
-B number print matching line and 'number' of lines before the matched line
-C number print matching line and 'number' of lines before and after the matched line
-m number restrict printing to upper limit of matched lines specified by 'number'
-q no standard output, quit immediately if match found. Useful in scripts to check if a file contains search pattern
or not
-s suppress error messages if file doesn't exist or not readable. Again, more useful in scripts
-h do not prefix filename for matching lines (default behavior for single file search)
-H prefix filename for matching lines (default behavior for multiple file search)
Examples
grep 'area' report.log will print all lines containing the word area in report.log
grep 'adder power' report.log will print lines containing adder power
man grep | grep -i -A 5 'exit status' will print matched line and 5 lines after containing the words 'exit status'
independent of case
See Context Line Control topic in info grep for related options like --no-group-separator
grep -m 5 'error' report.log will print maximum of 5 lines containing the word error
grep "$HOME" /etc/passwd will print lines matching the value of environment variable HOME
Note the use of double quotes for variable substitution
grep -w 'or' story.txt match whole word or, not part of word like for, thorn etc
grep -x 'power' test_list.txt match whole line containing the pattern power
Note: All of the above examples would be suited for -F option as these do not use regular expressions and will be
faster with -F option
Regular Expressions
Regular Expressions help in defining precise patterns, like extracting only alphabets or numbers, matching at start of
line, end of line, character sequence, etc
The following reference is for ERE - Extended Regular Expressions
Anchors
Character Quantifiers
33
Working with Files and Directories
Character classes
\w match alphabets, digits and underscore character, short cut for [a-zA-Z0-9_]
\s match white-space characters: tab, newline, vertical tab, form feed, carriage return, and space
\S match other than white-space characters
Pattern groups
By default, the pattern passed to grep is treated as Basic Regular Expressions(BRE), which can be overridden using
options like -E for ERE and -P for Perl Compatible Regular Expression(PCRE)
Paraphrasing from info grep
In Basic Regular Expressions the meta-characters ? + { | ( ) lose their special meaning, instead use the
backslashed versions \? \+ \{ \| \( \)
Examples
grep -i '[a-z]' report.log will print all lines having atleast one alphabet character
grep '[0-9]' report.log will print all lines having atleast one number
grep 'area\|power' report.log will match lines containing area or power
grep -E 'area|power' report.log will match lines containing area or power
grep -P '\d' report.log will print all lines having atleast one number
grep -P '(Th)?is' short_story.txt match This or is
grep -oP 'file\K\d+' report.log print only digits that are preceded by the string 'file'
man pcrepattern syntax and semantics of the regular expressions that are supported by PCRE
look-around assertions example
34
Working with Files and Directories
$ cat ip.txt
Roses are red,
Violets are blue,
Sugar is sweet,
And so are you.
35
Working with Files and Directories
Further Reading
For more detailed examples and discussion, see GNU grep chapter from command line text processing repo
how grep command was born
why GNU grep is fast
Difference between grep, egrep and fgrep
grep Q&A on stackoverflow
grep Q&A on unix stackexchange
find
search for files in a directory hierarchy
Examples
find . -iname 'power.log' search and print path of file named power.log (ignoring case) in current directory and
its sub-directories
find -name '*log' search and print path of all files whose name ends with log in current directory - using . is
optional when searching in current directory
find -not -name '*log' print path of all files whose name does NOT end with log in current directory
find -regextype egrep -regex '.*/\w+' use extended regular expression to match filename containing only [a-
zA-Z_] characters
.*/ is needed to match initial part of file path
find /home/guest1/proj -type f print path of all regular files found in specified directory
find /home/guest1/proj -type d print path of all directories found in specified directory
find /home/guest1/proj -type f -name '.*' print path of all hidden files
36
Working with Files and Directories
The relative path . is considered as depth 0 directory, files and folders immediately contained in a directory are at
depth 1 and so on
find -maxdepth 1 -type f all regular files (including hidden ones) from current directory (without going to sub-
directories)
find -maxdepth 1 -type f -name '[!.]*' all regular files (but not hidden ones) from current directory (without
going to sub-directories)
-not -name '.*' can be also used
find -mindepth 1 -maxdepth 1 -type d all directories (including hidden ones) in current directory (without going to
sub-directories)
find -mtime -2 print files that were modified within last two days in current directory
find -daystart -type f -mtime -1 files that were modified from beginning of day (not past 24 hours)
find -size +10k print files with size greater than 10 kilobytes in current directory
find -size -1M print files with size less than 1 megabytes in current directory
find -size 2G print files of size 2 gigabytes in current directory
find report -name '*log*' -exec rm {} \; delete all filenames containing log in report folder and its sub-folders
here rm command is called for every file matching the search conditions
since ; is a special character for shell, it needs to be escaped using \
find report -name '*log*' -delete delete all filenames containing log in report folder and its sub-folders
find -name '*.txt' -exec wc {} + list of files ending with txt are all passed together as argument to wc
command instead of executing wc command for every file
no need to use escape the + character in this case
also note that number of invocations of command specified is not necessarily once if number of files found is
too large
find -name '*.log' -exec mv {} ../log/ \; move files ending with .log to log directory present in one hierarchy
above. mv is executed once per each filtered file
find -name '*.log' -exec mv -t ../log/ {} + the -t option allows to specify target directory and then provide
multiple files to be moved as argument
Similarly, one can use -t for cp command
Further Reading
using find
Collection of find examples
find Q&A on unix stackexchange
find and tar example
find Q&A on stackoverflow
Why is looping over find's output bad practice?
locate
find files by name
37
Working with Files and Directories
Faster alternative to find command when searching for a file by its name. It is based on a database, which gets
updated by a cron job. So, newer files may be not present in results. Use this command if it is available in your distro
and you remember some part of filename. Very useful if one has to search entire filesystem in which case find
command might take a very long time compared to locate
Examples
locate 'power' print path of files containing power in the whole filesystem
locate -b '\proj_adder' the -b option also comes in handy to print only the path of directory name, otherwise
every file under that folder would also be displayed
find vs locate - pros and cons
wc
print newline, word, and byte counts for each file
Examples
other options
38
Working with Files and Directories
Further Reading
For more detailed examples and discussion, see section wc from command line text processing repo
wc Q&A on unix stackexchange
wc Q&A on stackoverflow
du
estimate file space usage
Examples
39
Working with Files and Directories
$ # number of bytes
$ du -b words.txt
938848 words.txt
$ # sorting
$ du -sh projs/* words.txt | sort -h
712K projs/report.log
924K words.txt
14M projs/half_addr
18M projs/full_addr
Further Reading
For more detailed examples and discussion, see section du from command line text processing repo
du Q&A on unix stackexchange
du Q&A on stackoverflow
df
report file system disk space usage
Examples
$ # use df without arguments to get information on all currently mounted file systems
$ df .
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 98298500 58563816 34734748 63% /
40
Working with Files and Directories
$ df -h --output=size,used,file / /media/learnbyexample/projs
Size Used File
94G 56G /
92G 35G /media/learnbyexample/projs
$ df -h --output=pcent .
Use%
63%
Further Reading
For more detailed examples and discussion, see section df from command line text processing repo
df Q&A on stackoverflow
touch
change file timestamps
Examples
$ ls foo.txt
ls: cannot access 'foo.txt': No such file or directory
$ touch foo.txt
$ ls foo.txt
foo.txt
Further Reading
For more detailed examples and discussion, see section touch from command line text processing repo
41
Working with Files and Directories
file
determine file type
Examples
$ file sample.txt
sample.txt: ASCII text
$ printf 'hi\n' | file -
/dev/stdin: UTF-8 Unicode text
$ file ch
ch: Bourne-Again shell script, ASCII text executable
find all files of particular type in current directory, for example image files
$ find -type f -exec bash -c '(file -b "$0" | grep -wq "image data") && echo "$0"' {} \;
./sunset.jpg
./moon.png
Further Reading
For more detailed examples and discussion, see section file from command line text processing repo
See also identify command which describes the format and characteristics of one or more image files
basename
strip directory and suffix from filenames
Examples
42
Working with Files and Directories
$ basename "$PWD"
learnbyexample
$ # use single quotes if arguments contain space and other special shell characters
$ # use suffix option -s to strip file extension from filename
$ basename -s '.log' '/home/learnbyexample/proj adder/power.log'
power
$ # -a is implied when using -s option
$ basename -s'.log' foo/a/report.log bar/y/power.log
report
power
For more detailed examples and discussion, see section basename from command line text processing repo
dirname
strip last component from file name
Examples
$ echo "$PWD"
/home/learnbyexample
$ dirname "$PWD"
/home
$ # use single quotes if arguments contain space and other special shell characters
$ dirname '/home/learnbyexample/proj adder/power.log'
/home/learnbyexample/proj adder
For more detailed examples and discussion, see section dirname from command line text processing repo
chmod
change file mode bits
43
Working with Files and Directories
$ ls -l sample.txt
-rw-rw-r-- 1 learnbyexample learnbyexample 111 May 25 14:47 sample.txt
In the output of ls -l command, the first 10 characters displayed are related to type of file and its permissions.
First character indicates the file type The most common are
- regular file
d directory
l symbolic link
The other 9 characters represent three sets of file permissions for 'user', 'group' and 'others' - in that order
We'll be seeing only rwx file properties in this section, for other types of properties, refer this detailed doc
File Permissions
44
Working with Files and Directories
$ pwd
/home/learnbyexample/linux_tutorial
$ ls -lF
total 8
-rw-rw-r-- 1 learnbyexample learnbyexample 40 May 28 13:25 hello_world.pl
-rw-rw-r-- 1 learnbyexample learnbyexample 111 May 25 14:47 sample.txt
$ #Read permission
$ cat sample.txt
This is an example of adding text to a new file using cat command.
Press Ctrl+d on a newline to save and quit.
$ chmod -r sample.txt
$ ls -lF sample.txt
--w--w---- 1 learnbyexample learnbyexample 111 May 25 14:47 sample.txt
$ cat sample.txt
cat: sample.txt: Permission denied
Directory Permissions
45
Working with Files and Directories
$ ls -ld linux_tutorial/
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ #Read Permission
$ ls linux_tutorial/
hello_world.pl sample.txt
$ chmod -r linux_tutorial/
$ ls -ld linux_tutorial/
d-wx-wx--x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ ls linux_tutorial/
ls: cannot open directory linux_tutorial/: Permission denied
$ chmod +r linux_tutorial/
$ #Execute Permission
$ chmod -x linux_tutorial/
$ ls -ld linux_tutorial/
drw-rw-r-- 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ ls linux_tutorial/
ls: cannot access linux_tutorial/hello_world.pl: Permission denied
ls: cannot access linux_tutorial/sample.txt: Permission denied
hello_world.pl sample.txt
$ chmod +x linux_tutorial/
$ #Write Permission
$ chmod -w linux_tutorial/
$ ls -ld linux_tutorial/
dr-xr-xr-x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ touch linux_tutorial/new_file.txt
touch: cannot touch ‘linux_tutorial/new_file.txt’: Permission denied
$ chmod +w linux_tutorial/
$ ls -ld linux_tutorial/
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 10:59 linux_tutorial/
$ touch linux_tutorial/new_file.txt
$ ls linux_tutorial/
hello_world.pl new_file.txt sample.txt
$ # r(4) + w(2) + 0 = 6
$ # r(4) + 0 + 0 = 4
$ chmod 664 sample.txt
$ ls -lF sample.txt
-rw-rw-r-- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt
46
Working with Files and Directories
$ ls -lR linux_tutorial/
linux_tutorial/:
total 12
-rwxr-xr-x 1 learnbyexample learnbyexample 40 May 28 13:25 hello_world.pl
drwxrwxr-x 2 learnbyexample learnbyexample 4096 May 29 14:32 report
-rw-rw---- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt
linux_tutorial/report:
total 0
-rw-rw-r-- 1 learnbyexample learnbyexample 0 May 29 11:46 new_file.txt
$ ls -ld linux_tutorial/
drwxrwxr-x 3 learnbyexample learnbyexample 4096 May 29 14:32 linux_tutorial/
$ chmod +w linux_tutorial/
$ ls -ld linux_tutorial/
drwxrwxr-x 3 learnbyexample learnbyexample 4096 May 29 14:32 linux_tutorial/
$ chmod -w -R linux_tutorial/
$ ls -lR linux_tutorial/
linux_tutorial/:
total 12
-r-xr-xr-x 1 learnbyexample learnbyexample 40 May 28 13:25 hello_world.pl
dr-xr-xr-x 2 learnbyexample learnbyexample 4096 May 29 14:40 report
-r--r----- 1 learnbyexample learnbyexample 148 May 29 11:00 sample.txt
linux_tutorial/report:
total 0
-r--r--r-- 1 learnbyexample learnbyexample 0 May 29 14:39 power.log
$ rm linux_tutorial/report/power.log
rm: remove write-protected regular empty file ‘linux_tutorial/report/power.log’? y
rm: cannot remove ‘linux_tutorial/report/power.log’: Permission denied
47
Working with Files and Directories
What permissions are affected by +-/rwx depends on umask value as well. It is usually 002 which means
+r -r +x -x without u g o qualifier affects all the three categories
+w -w without u g o qualifier affects only user and group categories
Further Reading
48
Text Processing
Text Processing
sort
uniq
comm
cmp
diff
tr
sed
awk
perl
cut
paste
column
pr
The rich set of text processing commands is comprehensive and time saving. Knowing even their existence is enough
to avoid the need of writing yet another script (which takes time and effort plus debugging) – a trap which many
beginners fall into. An extensive list of text processing commands and examples can be found here
sort
sort lines of text files
As the name implies, this command is used to sort files. How about alphabetic sort and numeric sort? Possible. How
about sorting a particular column? Possible. Prioritized multiple sorting order? Possible. Randomize? Unique? Just
about any sorting need is catered by this powerful command
Options
-R random sort
-r reverse the sort order
-o redirect sorted result to specified filename, very useful to sort a file inplace
-n sort numerically
-V version sort, aware of numbers within text
Examples
49
Text Processing
du -sh * | sort -h sort file/directory sizes in current directory in human readable format
$ cat ip.txt
6.2 : 897 : bar
3.1 : 32 : foo
2.3 : 012 : bar
1.2 : 123 : xyz
$ # -n option for numeric sort, check out what happens when -n is not used
$ sort -t: -k2,2n ip.txt
2.3 : 012 : bar
3.1 : 32 : foo
1.2 : 123 : xyz
6.2 : 897 : bar
Further Reading
uniq
report or omit repeated lines
This command is more specific to recognizing duplicates. Usually requires a sorted input as the comparison is made on
adjacent lines only
Options
Examples
sort test_list.txt | uniq outputs lines of test_list.txt in sorted order with duplicate lines removed
50
Text Processing
uniq -cd sorted_list.txt print only duplicate lines and prefix the line with number of times it is repeated
uniq -u sorted_list.txt print only unique lines, repeated lines are ignored
uniq Q&A on unix stackexchange
$ uniq -d sorted_colors.txt
Blue
Red
$ uniq -u sorted_colors.txt
Black
Green
comm
compare two sorted files line by line
Without any options, it prints output in three columns - lines unique to file1, line unique to file2 and lines common to
both files
Options
Examples
51
Text Processing
examples
cmp
compare two files byte by byte
Useful to compare binary files. If the two files are same, no output is displayed (exit status 0)
If there is a difference, it prints the first difference - line number and byte location (exit status 1)
Option -s allows to suppress the output, useful in scripts
52
Text Processing
diff
compare files line by line
Options
-w ignore white-spaces
-r recursively compare files between the two directories specified
-q report if files differ, not the details of difference
Examples
Further Reading
tr
translate or delete characters
Options
Examples
53
Text Processing
tr a-z n-za-m < test_list.txt > encrypted_test_list.txt Encrypt by replacing every lowercase alphabet with
sed
stream editor for filtering and transforming text
Options
commands
check out 'Often-Used Commands' and 'Less Frequently-Used Commands' sections in info sed for complete list
of commands
range
By default, sed acts on all of input contents. This can be refined to specific line number or a range defined by line
numbers, search pattern or mix of the two
54
Text Processing
sed '1,/test/d' dir_list.txt delete all lines from beginning of file to first occurrence of line containing test (the
matched line is also deleted)
sed '/test/,$d' dir_list.txt delete all lines from line containing test to end of file
sed -n '5p' story.txt print 5th line, -n option overrides default print behavior of sed
/^\s*exit status/I checks for line starting with 'exit status' in case insensitive way, white-space may be
present at start of line
/^$/ empty line
sed -i 's/cat/dog/g' story.txt search and replace every occurrence of cat with dog in story.txt
sed -i.bkp 's/cat/dog/g' story.txt in addition to inplace file editing, create backup file story.txt.bkp, so that if a
Since -i option is not used, output is displayed on standard output and story.txt is not changed
spacing between range and command is optional, sed '/cat/s/animal/mammal/g' story.txt can also be
used
sed -i -e 's/cat/dog/g' -e 's/lion/tiger/g' story.txt search and replace every occurrence of cat with dog
55
Text Processing
$ cat mem_test.txt
mreg2 = 1200 # starting address
mreg4 = 2180 # ending address
$ s_add='1760'; e_add='2500'
$ sed "s/1200/$s_add/; s/2180/$e_add/" mem_test.txt
mreg2 = 1760 # starting address
mreg4 = 2500 # ending address
56
Text Processing
inplace editing
Further Reading
sed basics
sed detailed tutorial
sed-book
cheat sheet
sed examples
sed one-liners explained
common search and replace examples with sed
sed Q&A on unix stackexchange
sed Q&A on stackoverflow
awk
pattern scanning and text processing language
awk derives its name from authors Alfred Aho, Peter Weinberger and Brian Kernighan.
syntax
57
Text Processing
$ cat test.txt
abc : 123 : xyz
3 : 32 : foo
-2.3 : bar : bar
$ # bash environment variables like PWD, HOME is also accessible via ENVIRON
$ s="%" awk '{sub("3", ENVIRON["s"])} 1' test.txt
abc : 12% : xyz
% : 32 : foo
-2.% : bar : bar
filtering content
58
Text Processing
59
Text Processing
column manipulations
by default, one or more consecutive spaces/tabs are considered as field separators
60
Text Processing
$ # second column
$ echo -e "1 3 4\na b c" | awk '{print $2}'
3
b
$ # last column
$ echo -e "1 3 4\na b c" | awk '{print $NF}'
4
c
61
Text Processing
$ cat duplicates.txt
abc 123 ijk
foo 567 xyz
abc 123 ijk
bar 090 pqr
tst 567 zzz
$ # whole line
$ awk '!seen[$0]++' duplicates.txt
abc 123 ijk
foo 567 xyz
bar 090 pqr
tst 567 zzz
$ # particular column
$ awk '!seen[$2]++' duplicates.txt
abc 123 ijk
foo 567 xyz
bar 090 pqr
inplace editing
Further Reading
awk basics
Gawk: Effective AWK Programming
awk detailed tutorial
basic tutorials for grep, awk, sed
awk one-liners explained
awk book
awk cheat-sheet for awk variables, statements, functions, etc
awk examples
awk Q&A on unix stackexchange
awk Q&A on stackoverflow
perl
The Perl 5 language interpreter
Larry Wall wrote Perl as a general purpose scripting language, borrowing features from C, shell scripting, awk,
sed, grep, cut, sort etc
Reference tables given below for frequently used constructs with perl one-liners. Resource links given at end for
further reading.
62
Text Processing
Option Description
-n iterate over input files in a loop, lines are NOT printed by default
-a autosplit input lines on space, implicitly sets -n for Perl version 5.20.0 and above
-F specifies the pattern to split input lines, implicitly sets -a and -n for Perl version 5.20.0 and above
-0777 slurp entire file as single string, not advisable for large input files
Variable Description
Function Description
length Returns the length in characters of the value of EXPR. If EXPR is omitted, returns the length of $_
eof Returns 1 if the next read on FILEHANDLE will return end of file
63
Text Processing
$ cat test.txt
abc : 123 : xyz
3 : 32 : foo
-2.3 : bar : bar
$ # use g flag to replace all occurrences, not just first match in line
$ perl -pe 's/3/%/g' test.txt
abc : 12% : xyz
% : %2 : foo
-2.% : bar : bar
$ # conditional replacement
$ perl -pe 's/3/@/g if /foo/' test.txt
abc : 123 : xyz
@ : @2 : foo
-2.3 : bar : bar
The \Q and q() constructs are helpful to nullify regex meta characters
64
Text Processing
65
Text Processing
$ seq 123 135 | perl -ne 'print if $. >= 3 && $. <= 5'
125
126
127
.. vs ...
Column manipulations
66
Text Processing
$ perl -F: -lane '$F[2] =~ s/\w(?=\w)/$&,/g; print join ":", @F' test.txt
abc : 123 : x,y,z
3 : 32 : f,o,o
-2.3 : bar : b,a,r
$ perl -F'\s*:\s*' -lane 'print join ",", grep {/[a-z]/i} @F' test.txt
abc,xyz
foo
bar,bar
$ perl -F: -ane 'print if (grep {/\d/} @F) < 2' test.txt
abc : 123 : xyz
-2.3 : bar : bar
$ cat duplicates.txt
abc 123 ijk
foo 567 xyz
abc 123 ijk
bar 090 pqr
tst 567 zzz
$ # whole line
$ perl -ne 'print if !$seen{$_}++' duplicates.txt
abc 123 ijk
foo 567 xyz
bar 090 pqr
tst 567 zzz
$ # particular column
$ perl -ane 'print if !$seen{$F[1]}++' duplicates.txt
abc 123 ijk
foo 567 xyz
bar 090 pqr
67
Text Processing
Multiline processing
$ # with multiline matching, -0777 slurping not advisable for very large files
$ perl -0777 -ne 'print $1 if /.*abc.*\n(.*3.*\n)/' test.txt
3 : 32 : foo
$ perl -0777 -ne 'print $1 if /(.*abc.*\n.*3.*\n)/' test.txt
abc : 123 : xyz
3 : 32 : foo
Using modules
68
Text Processing
$ base64 test.txt
YWJjICA6IDEyMyA6IHh5egozICAgIDogMzIgIDogZm9vCi0yLjMgOiBiYXIgOiBiYXIK
$ base64 test.txt | base64 -d
abc : 123 : xyz
3 : 32 : foo
-2.3 : bar : bar
$ base64 test.txt | perl -MMIME::Base64 -ne 'print decode_base64($_)'
abc : 123 : xyz
3 : 32 : foo
-2.3 : bar : bar
$ perl -MList::MoreUtils=indexes -nale '@i = indexes { /[a-z]/i } @F if $. == 1; print join ",", @F[@i]' tes
t.txt
abc,xyz
3,foo
-2.3,bar
In place editing
Further Reading
cut
69
Text Processing
For columns operations with well defined delimiters, cut command is handy
Examples
character)
-f option specifies which fields to print separated by commas, in this case field 1
cut -d':' -f1,7 /etc/passwd prints 1st and 7th column of /etc/passwd file with : character in between
cut -d':' --output-delimiter=' ' -f1,7 /etc/passwd use space as delimiter between 1st and 7th column while
printing
cut Q&A on unix stackexchange
paste
merge lines of files
Examples
paste list1.txt list2.txt list3.txt > combined_list.txt combines the three files column-wise into single file,
of TAB
See pr command for multiple character delimiter
paste Q&A on unix stackexchange
70
Text Processing
$ seq 5 | paste - -
1 2
3 4
5
column
columnate lists
$ cat dishes.txt
North alootikki baati khichdi makkiroti poha
South appam bisibelebath dosa koottu sevai
West dhokla khakhra modak shiro vadapav
East handoguri litti momo rosgulla shondesh
$ column -t dishes.txt
North alootikki baati khichdi makkiroti poha
South appam bisibelebath dosa koottu sevai
West dhokla khakhra modak shiro vadapav
East handoguri litti momo rosgulla shondesh
pr
convert text files for printing
71
Text Processing
$ pr sample.txt
Options include converting text files for printing with header, footer, page numbers, double space a file, combine
multiple files column wise, etc
More examples here
$ seq 15 | pr -5ts,
1,4,7,10,13
2,5,8,11,14
3,6,9,12,15
$ seq 15 | pr -5ats,
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
72
Text Processing
$ seq 74 | pr -36ats,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72
73,74
$ seq 74 | pr -37ats,
pr: page width too narrow
$ # (37-1)*1 + 37 = 73
$ seq 74 | pr -Jw 73 -37ats,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37
38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,
74
$ # (3-1)*4 + 3 = 11
$ seq 6 | pr -Jw 10 -3ats'::::'
pr: page width too narrow
$ seq 6 | pr -Jw 11 -3ats'::::'
1::::2::::3
4::::5::::6
We can use a combination of different commands for complicated operations. For example, transposing a table
Notice how pr neatly arranges the columns. If spacing is too much, we can use column
73
Shell
Shell
What is Shell?
Popular Shells
Wildcards
Redirection
Process Control
Running jobs in background
What is Shell?
Quoting from wikipedia
A Unix shell is a command-line interpreter or shell that provides a traditional Unix-like command line user
interface. Users direct the operation of the computer by entering commands as text for a command line interpreter
to execute, or by creating text scripts of one or more such commands. Users typically interact with a Unix shell
using a terminal emulator, however, direct operation via serial hardware connections, or networking session, are
common for server systems. All Unix shells provide filename wildcarding, piping, here documents, command
substitution, variables and control structures for condition-testing and iteration
Popular Shells
Like any indispensible software, Shell has undergone transformation from the days of basic sh shell that was used in
1970s Unix. While bash is default shell in most distros and most commonly used, powerful and feature rich shells are
still being developed and released
sh bourne shell (light weight Linux distros might come with sh shell only)
bash bourne again shell
csh C shell
tcsh tenex C shell
ksh Korn shell
zsh Z shell (bourne shell with improvements, including features from bash, tcsh, ksh)
cat /etc/shells displays list of login shells available in the current Linux distro
echo $SHELL path of current user's login shell
The material presented here is primarily for interactive shell
difference between login shell and non-login shell
74
Shell
Further Reading
git bash
Cygwin
MinGW
Linux Subsystem for Windows
Shell, choosing shell and changing default shells
Wildcards
It is easy to specify complete filenames as command arguments when they are few in number. But suppose, one has to
delete hundreds of log files, spread across different sub-directories? Wildcards, or also known as globbing patterns help
in such cases, provided the filenames have a commonality to exploit. We have already seen regular expressions used
in commands like grep and sed . Shell wildcards are similar but has fundamental and syntactical differences
as a special case, * won't match the starting . of hidden files and has to be explicity specified
? match any character exactly 1 time
Examples
rm *.??? remove any file ending with . character followed by exactly three characters
ls bkp/201[0-5] list files in bkp directory matching 2010/2011/2012/2013/2014/2015
echo *txt for dry runs, use echo command to see how the wildcard expands
Brace Expansion
ls *{txt,log} list all files ending with txt or log in the current directory
cp ~/projects/adders/verilog/{half_,full_}adder.v . copy half_adder.v and full_adder.v to current directory
mv story.txt{,.bkp} rename story.txt as story.txt.bkp
cp story.txt{,.bkp} to create bkp file as well retain original
mv story.txt{.bkp,} rename story.txt.bkp as story.txt
75
Shell
actual command
Extended globs
From info bash , where pattern-list is a list of one or more patterns separated by a |
$ shopt extglob
extglob on
$ # unset extglob
$ shopt -u extglob
$ shopt extglob
extglob off
$ # set extglob
$ shopt -s extglob
$ shopt extglob
extglob on
Examples
$ ls
123.txt main.c math.h power.log
$ echo +([0-9]).txt
123.txt
$ ls @(*.c|*.h)
main.c math.h
$ ls !(*.txt)
main.c math.h power.log
$ ls !(*.c|*.h)
123.txt power.log
76
Shell
$ shopt -s globstar
$ ls **/*.txt
bar/baz/f2.txt bar/f1.txt song_list.txt
Further Reading
Glob
See topic 'Pathname Expansion' in info bash
brace expansion wiki
when to use brace expansion
Redirection
By default all results of a command are displayed on the terminal, which is the default destination for standard output.
But often, one might want to save or discard them or send as input to another command. Similarly, inputs to a command
can be given from files or from another command. Errors are special outputs generated on a wrong usage of command
or command name
grep -i 'error' report/*.log > error.log create new file, overwrite if file already exists
grep -i 'fail' test_results_20mar2015.log >> all_fail_tests.log creates new file if file doesn’t exist, otherwise
append the result to existing file
./script.sh > /dev/null redirect output to a special file /dev/null that just discards everything written to it,
whatever may be the size
explicitly override the setting of noclobber with the >| redirection operator
du -sh * | sort -h calculate size of files/folders, display size in human-readable format which is then sorted
./script.sh | tee output.log the tee command displays standard output on terminal as well as writes to file
(head -5 ~/.vimrc ; tail -5 ~/.vimrc) > vimrc_snippet.txt multiple commands can be grouped in () and
Command substitution
77
Shell
sed -i "s|^|$(basename $PWD)/|" dir_list.txt add current directory path and forward-slash character at the
Command Substitution
Process Substitution
comm -23 <(sort file1.txt) <(sort file2.txt) allows to create named pipes, effectively avoiding need to create
temporary files
Process Substitution
input and output process substitution examples
Redirecting error
xyz 2> cmderror.log assuming a non-existent command xyz , it would give an error and gets redirected to
specified file
./script.sh 2> /dev/null discard error messages
Assume that the file 'report.log' exists containing the text 'test' and non-existing file 'xyz.txt'
grep 'test' report.log xyz.txt &> cmb_out.txt redirect both stdout and stderr to a file
grep 'test' report.log xyz.txt &>> cmb_out.txt append both stdout and stderr to a file
ls report.log xyz.txt |& grep '[st]' redirect both stdout and stderr as stdin
Earlier versions:
grep 'test' report.log xyz.txt > cmb_out.txt 2>&1 redirect both stdout and stderr to a file
grep 'test' report.log xyz.txt 2> cmb_out.txt 1>&2 redirect both stdout and stderr to a file
grep 'test' report.log xyz.txt >> cmb_out.txt 2>&1 append both stdout and stderr to a file
ls report.log xyz.txt 2>&1 | grep '[st]' redirect both stdout and stderr as stdin
Redirecting input
tr a-z A-Z < test_list.txt convert lowercase to uppercase, tr command only reads from stdin and doesn't
have the ability to read from a file directly
wc -l < report.log useful to avoid filename in wc output
< report.log grep 'test' useful to easily modify previous command for different command options, search
patterns, etc
grep 'test' report.log | diff - test_list.txt output of grep as one of the input file for diff command
difference between << , <<< and < <
grep -rlZ 'pattern' | xargs -0 sed -i 's/pattern/replace/' search and replace only those files matching the
required pattern (Note: search pattern could be different for grep and sed as per requirement)
the -Z option would print filename separated by ASCII NUL character which is in turn understood by xargs
via the -0 option. This ensures the command won't break on filenames containing characters like spaces,
newlines, etc
When to use xargs
has a good example for parallel processing jobs with xargs
78
Shell
Further Reading
Process Control
Process is any running program
ps
kill
top
79
Shell
free
free -h shows amount of free and used memory in human readable format
pgrep
pgrep -l foobar search for process names containing foobar, displays PID and full process name
Further Reading
Process Management
Managing Linux Processes
Linux Processes
what is daemon)
Job Control commands
Useful examples for top command
tkdiff result_v1.log result_v2.log & tkdiff, if installed, shows differences between two files in a GUI. If & is
not used, the program would hog the command prompt
What if you forgot to add & and using kill on the process might corrupt lot of things?
80
Shell Customization
Shell Customization
Variables
Config files
Emac mode Readline shortcuts
Variables
Quoting from article on BASH Environment & Shell Variables
Variables provide a simple way to share configuration settings between multiple applications and processes in
Linux, and are mainly set in either a terminal or shell configuration file upon start up.
They are either environmental or shell variables by convention. Both of which are usually defined using all capital
letters. This helps users distinguish environmental variables from within other contexts.
“Environment variables” have been defined for use in the current shell and will be inherited by any child shells or
processes spawned as a result of the parent. Environmental variables can also be used to pass information into
processes that are spawned by the shell
“Shell variables” are contained exclusively within the shell in which they were set or defined. They are mostly used
to keep track of ephemeral temporal data, like the current working directory in a session
HOME The home directory of the current user; the default argument for the cd builtin command. The value of this
variable is also used when performing tilde expansion
SHELL The full pathname to the shell is kept in this environment variable. If it is not set when the shell starts, bash
assigns to it the full pathname of the current user's login shell
PATH The search path for commands. It is a colon-separated list of directories in which the shell looks for
commands. A common value is /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
PWD and OLDPWD full path of current working directory and previous working directory
HISTFILESIZE,HISTSIZE,HISTCONTROL,HISTFILE command history related variables
PS1 The value of this parameter is expanded and used as the primary prompt string. The default value is \s-
\v\$
printenv command to display names and values of Environment variables
set builtin command to display the names and values of all the variables when used without options/arguments
echo "$HOME" use $ when Variable value is needed
User can define variables as well - for temporary use, in shell script, etc.
Using lowercase is preferred to avoid potential conflict with shell or environment variables
81
Shell Customization
Further Reading
Config files
Through use of aliases, functions, shell variables, etc one can customize the shell as per their needs
~/.bashrc
When an interactive shell that is not a login shell is started, bash reads and executes commands from
/etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option. The --rcfile file
option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.
set +o history disable command history, useful to temporarily disable logging command history for current
82
Shell Customization
easy way to generate PS1 - above example was generated using this site, has options to add color as well
What does the ~/.bashrc file do?
Distros like Ubuntu come with ~/.bashrc already created with useful configurations like bash_completion
sample bashrc
~/.inputrc
Key bindings for command line (readline) are customized in this file. By default, emacs-style is on and can be changed
using the set command as discussed in previous section
Some of the default key bindings are discussed later in this chapter
"\e[A": history-search-backward up arrow to match history starting with partly typed text
~/.bash_aliases
Before creating an alias or function, use type alias_name to check if an existing command or alias exists with that
name
alias used without argument shows all aliases currently set, sorted in alphabetical order
alias c='clear' alias clear command to just the single letter c
83
Shell Customization
alias l='ls -ltrh' map favorite options, plus color output as previously set alias will be substituted for ls
alias grep='grep --color=auto' colorize file names, line numbers, matched pattern, etc
alias s='du -sh * | sort -h' sort files/directories by size and display in human-readable format
\ls override alias and use original command by using the \ prefix
ch() { man $1 | sed -n "/^\s*$2/,/^$/p" ; } simple command help (ch) function to get information on a
command option
for example: ch ls -F , ch grep -o , etc
ch() { whatis $1; man $1 | sed -n "/^\s*$2/,/^$/p" ; } also prints description of command
ch does a much better job with capability to handle multiple options, multiple arguments, builtin commands, etc
explainshell does even better
o() { gnome-open "$@" &> /dev/null ; } open files with their default applications, discards output and error
messages
for example: o bashguide.pdf
$1 first positional argument
sample bash_aliases
Further Reading
84
Shell Customization
For example: if you typed sp instead of ps, press Ctrl+t when the cursor is to right of sp and it will change to ps
Esc+t swap the previous two words around
for example: if cat temp.txt was the last command used, rm !$ will delete temp.txt file
Esc+. will insert the last used argument, useful when you need to modify before execution. Also multiple
presses allows to traverse through second last command and so on
Mouse scroll button click highlight text you want to copy and then press scroll button of mouse in destination to
paste the text
to disable pasting text on Mouse scroll button click , use the xinput command and get the number
corresponding to your mouse.. say it is 11
xinput set-button-map 11 1 0 3 to disable
85
Shell Scripting
Shell Scripting
Need for scripting
Hello script
Sourcing script
Command Line Arguments
Variables and Comparisons
Accepting User Input interactively
if then else
for loop
while loop
Reading a file
Debugging
Real world use case
Resource lists
Note:
Hello script
#!/bin/bash
Comments
86
Shell Scripting
Multiline comments
Single quotes preserves the literal value of each character within the quotes
Double quotes preserves the literal value of all characters within the quotes, with the exception of '$', '`', '\', and,
when history expansion is enabled, '!'
Difference between single and double quotes
$ chmod +x hello_script.sh
$ ./hello_world.sh
Hello learnbyexample
Today is Wednesday
Have a nice day
Sourcing script
$ help -d source
source - Execute commands from a file in the current shell.
If script should be executed in current shell environment instead of sub-shell, use the . or source command
For example, after editing ~/.bashrc one can use source ~/.bashrc for changes to be immeditely effective
$ # contents of prev_cmd.sh
prev=$(fc -ln -2 | sed 's/^[ \t]*//;q')
echo "$prev"
For example, to access history of current interactive shell from within script
87
Shell Scripting
#!/bin/bash
Command line arguments are saved in positional variables starting with $1 $2 $3 etc
If a particular argument requires multiple word string, enclose them in quotes or use appropriate escape sequences
$0 contains the name of the script itself - useful to code different behavior based on name of script used
Further Reading
88
Shell Scripting
#!/bin/bash
help -d read Read a line from the standard input and split it into fields
-a array assign the words read to sequential indices of the array variable ARRAY, starting at zero
-p prompt output the string PROMPT without a trailing newline before attempting to read
$ ./user_input.sh
Hi there! This script returns the sum of two numbers
Enter two numbers separated by spaces: 7 42
7 + 42 = 49
Thank you for using the script, Have a nice day :)
if then else
#!/bin/bash
if (( $# != 2 ))
then
echo "Error!! Please provide two file names"
# simple convention for exit values is '0' for success and '1' for error
exit 1
else
# Use ; to combine multiple commands in same line
# -f option checks if file exists, ! negates the value
# white-space around [[ and ]] is necessary
if [[ ! -f $1 ]] ; then
echo "Error!! '$1' is not a valid filename" ; exit 1
else
echo "No of lines in '$1' is $(wc -l < "$1")"
fi
# Conditional Execution
[[ ! -f $2 ]] && echo "Error!! '$2' is not a valid filename" && exit 1
echo "No of lines in '$2' is $(wc -l < "$2")"
fi
When handling user provided arguments, it is always advisable to check the sanity of arguments. A simple check
can reduce hours of frustrating debug when things go wrong
89
Shell Scripting
The code inside if [[ ! -f $1 ]] ; then block is only intended for demonstration, we could as well have used
error handling of wc command if file doesn't exist
Default exit value is 0 , so need not be explicitly written for successful script completion
Use elif if you need to test more conditions after if
The operator && is used to execute a command only when the preceding one successfully finishes
To redirect error message to stderr, use echo "Error!! Please provide two file names" 1>&2 and so on
Control Operators && and ||
More examples for if conditional block
$ ./if_then_else.sh
Error!! Please provide two file names
$ echo $?
1
$ ./if_then_else.sh hello_script.sh
Error!! Please provide two file names
$ echo $?
1
Sometimes one needs to know if intended command operation was successful or not and then take action depending
on outcome. Exit status of 0 is considered as successful condition when used with if statement. When avaiable,
use appropriate options to suppress stdout/stderr of command being used, otherwise redirection might be needed to
avoid cluttering output on terminal
90
Shell Scripting
Example
#!/bin/bash
for loop
#!/bin/bash
file_count=0
total_lines=0
This form of for loop is useful if we need only element of an array, without having to iterate over length of an
array and using an index for each iteration to get array elements
In this example we use the control operator || to stop the script if wc fails i.e 'exit status' other than 0
91
Shell Scripting
$ ./for_loop.sh
Error!! Please provide atleast one file name
$ echo $?
1
#!/bin/bash
# Print 0 to 4
for ((i = 0; i < 5; i++))
do
echo $i
done
$ files=('report.log' 'pass_list.txt')
$ for f in "${files[@]}"; do echo "$f"; done
report.log
pass_list.txt
A common mistake is to use output of ls command which is error prone and needless. Instead, the arguments can be
directly used.
$ ls
pass_list.txt power.log report.txt
92
Shell Scripting
while loop
#!/bin/bash
# Print 5 to 1
(( i = 5 ))
while (( i != 0 ))
do
echo $i
((i--))
done
Use while when you need to execute commands according to a specified condition
$ ./while_loop.sh
5
4
3
2
1
Reading a file
Reading line by line
#!/bin/bash
IFS is used to specify field separator which is by default whitespace. IFS= will clear the default value and
$ cat files.txt
hello_script.sh
if_then_else.sh
$ ./while_read_file.sh
hello_script.sh
if_then_else.sh
93
Shell Scripting
$ cat read_file_field.sh
#!/bin/bash
$ ./read_file_field.sh
fantasy :: Harry Potter
sci-fi :: The Martian
mystery :: Sherlock Holmes
$ while read -n1 char; do echo "Character read is: $char"; done <<< "\word"
Character read is: w
Character read is: o
Character read is: r
Character read is: d
Character read is:
$ while read -r -n2 chars; do echo "Characters read: $chars"; done <<< "\word"
Characters read: \w
Characters read: or
Characters read: d
Debugging
-x Print commands and their arguments as they are executed
-v verbose option, print shell input lines as they are read
set -xv use this command to enable debugging from within script itself
$ bash -x hello_script.sh
+ echo 'Hello learnbyexample'
Hello learnbyexample
++ date -u +%A
+ echo 'Today is Friday'
Today is Friday
+ echo 'Have a nice day'
Have a nice day
94
Shell Scripting
Some explanation
```bash
$ seq 3
1
2
3
More explanations
```bash
$ help -d readarray
readarray - Read lines from a file into an array variable.
$ a=5
$ printf "$a\n"
5
```
The whole file is read into an array so that index of next line to be read can be controlled dynamically
Once a command is identified to be tested
the expected output is collected into a variable. Multiple lines are concatenated. Some commands do not have
stdout to compare against
95
Shell Scripting
#!/bin/bash
cb_start=0
readarray -t lines < 'sample.md'
# collect command output lines until line starting with $ or ``` block end
cmp_str=''
j=1
while [[ ${lines[$i+$j]:0:2} != '$ ' && ${lines[$i+$j]:0:3} != '```' ]]; do
cmp_str+="${lines[$i+$j]}"
((j++))
done
((i+=j-1))
cmd_op=$(eval "$cmd")
if [[ "${cmd_op//$'\n'}" == "${cmp_str//$'\n'}" ]]; then
echo "Pass: $cmd"
else
echo "Fail: $cmd"
fi
fi
done
Note how sourcing the script is helpful to take into consideration commands dependent on previous commands
$ ./verify_cmds.sh
Pass: seq 3
Pass: printf 'hi there!\n'
Pass: help -d readarray
Pass: a=5
Fail: printf "$a\n"
$ source verify_cmds.sh
Pass: seq 3
Pass: printf 'hi there!\n'
Pass: help -d readarray
Pass: a=5
Pass: printf "$a\n"
Resource lists
96
Shell Scripting
Shell Scripting
Bash Guide - for everything related to bash and bash scripting, also has a downloadable pdf
ryanstutorial - good introductory tutorial
bash handbook
writing shell scripts
snipcademy - shell scripting
wikibooks - bash shell scripting
linuxconfig - Bash scripting tutorial
learnshell
Specific topics
shellcheck - online static analysis tool that gives warnings and suggestions for scripts
See github link for more info and install instructions
Common bash scripting issues faced by beginners
bash FAQ
bash best Practices
bash pitfalls
Google shell style guide
better bash scripting
robust shell scripting
Bash Sheet
bash reference - nicely formatted and explained well
bash special variables reference
Testing exit values in bash
97