HOWTO.bash - raynaldmo/HOWTO GitHub Wiki

BASH Cheat Sheet

Useful links

Shortcuts

CTRL+A  # move to beginning of line
CTRL+B  # moves backward one character
CTRL+C  # halts the current command
CTRL+D  # deletes one character backward or logs out of current session, similar to exit
CTRL+E  # moves to end of line
CTRL+F  # moves forward one character
CTRL+G  # aborts the current editing command and ring the terminal bell
CTRL+J  # same as RETURN
CTRL+K  # deletes (kill) forward to end of line
CTRL+L  # clears screen and re-display the line
CTRL+M  # same as RETURN
CTRL+N  # next line in command history
CTRL+O  # same as RETURN, then displays next line in history file
CTRL+P  # previous line in command history
CTRL+R  # searches backward
CTRL+S  # searches forward
CTRL+T  # transposes two characters
CTRL+U  # kills backward from point to the beginning of line
CTRL+V  # makes the next character typed verbatim
CTRL+W  # kills the word behind the cursor
CTRL+X  # lists the possible filename completefions of the current word
CTRL+Y  # retrieves (yank) last item killed
CTRL+Z  # stops the current command, resume with fg in the foreground or bg in the background

DELETE  # deletes one character backward
!!      # repeats the last command
exit    # logs out of current session

Bash Basics

# show current shell
echo $SHELL

# show bash version         
echo $BASH_VERSION  # displays bash version

# shows where bash is installed
whereis bash        

$var           Value of shell variable var.
${var}abc      Example: value of shell variable var with string abc appended.
#              At start of line, indicates a comment.

var=value      Assign the string value to shell variable var.
cmd1 && cmd2   Run cmd1, then if cmd1 successful run cmd2, otherwise skip.
cmd1 || cmd2   Run cmd1, then if cmd1 not successful run cmd2, otherwise skip.
cmd1; cmd2     Do cmd1 and then cmd2.
cmd1 & cmd2    Do cmd1, start cmd2 without waiting for cmd1 to finish.
(cmds)         Run cmds (commands) in a subshell.

Pattern Matching

*              # matches 0 or more characters.
?              # matches 1 character.
[AaBbCc]       # matches any 1 char from the list.
[^RGB]         # matches any 1 char not in the list.
[a-g]          # matches any 1 char from this range.

Quoting

\c             # take character c literally.
`cmd`          # run cmd and replace it in the line of code with its output.
"whatever"     # take whatever literally, after first interpreting $, `...`, \
'whatever'     # take whatever absolutely literally.

# Examples
match=`ls *.bak`   # puts names of .bak files into shell variable match.
echo \*             # echos * to screen, not all filename as in:  echo *
echo '$1$2hello'   # writes literally $1$2hello on screen.
echo "$1$2hello"   # writes value of parameters 1 and 2 and string hello.

File related commands

ls                            # lists your files
ls -l                         # lists your files in 'long format'
ls -a                         # lists all files, including hidden files
ln -s <filename> <link>     # creates symbolic link to file
touch <filename>              # creates or updates your file
cat > <filename>              # places standard input into file
more <filename>               # shows the first part of a file (move with space and type q to quit)
head <filename>               # outputs the first 10 lines of file
tail <filename>               # outputs the last 10 lines of file (useful with -f option)
emacs <filename>              # lets you create and edit a file
mv <filename1> <filename2>    # moves a file
cp <filename1> <filename2>    # copies a file
rm <filename>                 # removes a file
diff <filename1> <filename2>  # compares files, and shows where they differ
wc <filename>                 # tells you how many lines, words and characters there are in a file
chmod -options <filename>     # lets you change the read, write, and execute permissions on your files
gzip <filename>               # compresses files
gunzip <filename>             # un-compresses files compressed by gzip
gzcat <filename>              # lets you look at gzipped file without actually having to gunzip it
lpr <filename>                # print the file
lpq                           # check out the printer queue
lprm <jobnumber>              # remove something from the printer queue
genscript                     # converts plain text files into postscript for printing and gives you some options for formatting
dvips <filename>              # print .dvi files (i.e. files produced by LaTeX)
grep <pattern> <filenames>    # looks for the string in the files
grep -r <pattern> <dir>       # search recursively for pattern in directory

Directory Commands

mkdir <dirname>  # makes a new directory
cd               # changes to home
cd <dirname>     # changes directory
pwd              # tells you where you currently are

SSH, System Info & Network Commands.

ssh user@host            # connects to host as user
ssh -p <port> user@host  # connects to host on specified port as user
ssh-copy-id user@host    # adds your ssh key to host for user to enable a keyed or passwordless login
whoami                   # returns your username
passwd                   # lets you change your password
quota -v                 # shows what your disk quota is
date                     # shows the current date and time
cal                      # shows the month's calendar
uptime                   # shows current uptime
w                        # displays whois online
finger <user>            # displays information about user
uname -a                 # shows kernel information
man <command>            # shows the manual for specified command
df                       # shows disk usage
du <filename>            # shows the disk usage of the files and directories in filename (du -s give only a total)
last <yourUsername>      # lists your last logins
ps -u yourusername       # lists your processes
kill <PID>               # kills (ends) the processes with the ID you gave
killall <processname>    # kill all processes with the name
top                      # displays your currently active processes
bg                       # lists stopped or background jobs ; resume a stopped job in the background
fg                       # brings the most recent job in the foreground
fg <job>                 # brings job to the foreground
ping <host>              # pings host and outputs results
whois <domain>           # gets whois information for domain
dig <domain>             # gets DNS information for domain
dig -x <host>            # reverses lookup host
wget <file>              # downloads file

Basic Shell Programming

Skeleton Scripts

#!/usr/bin/env bash
# Skeleton script #1
# Explain what script does

# don't execute any commands just echo
# set -xvn

# echo and execute commands
# set -xv 

LS=/bin/ls

usage () {
  echo "Usage : <script_name> <param1> <param2> <param3>"
  echo "example : example.sh param1 param2 param3"
  exit 1
}
if [ $# -ne 3 ]
then
  usage
fi

param1=$1
param2=$2
parma3=$3

# Script logic goes here
${LS} param1 param2 param3
#!/usr/bin/env bash
# Skeleton script #2
# ------------------------------------------------------------------
# [Author] Title
#          Description
# ------------------------------------------------------------------

VERSION=0.1.0
SUBJECT=some-unique-id
USAGE="Usage: command -ihv args"

# --- Options processing -------------------------------------------
if [ $# == 0 ] ; then
    echo $USAGE
    exit 1;
fi

while getopts ":i:vh" optname
  do
    case "$optname" in
      "v")
        echo "Version $VERSION"
        exit 0;
        ;;
      "i")
        echo "-i argument: $OPTARG"
        ;;
      "h")
        echo $USAGE
        exit 0;
        ;;
      "?")
        echo "Unknown option $OPTARG"
        exit 0;
        ;;
      ":")
        echo "No argument value for option $OPTARG"
        exit 0;
        ;;
      *)
        echo "Unknown error while processing options"
        exit 0;
        ;;
    esac
  done

shift $(($OPTIND - 1))

# --- Locks -------------------------------------------------------
LOCK_FILE=/tmp/$SUBJECT.lock
if [ -f "$LOCK_FILE" ]; then
   echo "Script is already running"
   exit
fi

trap "rm -f $LOCK_FILE" EXIT
touch $LOCK_FILE

# --- Body --------------------------------------------------------
#  SCRIPT LOGIC GOES HERE
echo $param1
echo $param2
# -----------------------------------------------------------------

Variables

# shell built in variables
$0   # name of this shell script itself.
$1   # positional parameters (similarly $2, $3, etc)
$#   # in a shell script, the number of command line parameters.
$*   # all of the command line parameters.
$-   # options given to the shell.
$?   # return the exit status of the last command.
$$   # process id of script (really id of the shell running the script)

# defines a variable
varname=value  
              
# define a variable to be in the environment of a particular subprocess
varname=value command        

# print a variable's value
echo $varname 
               
# prints process ID of the current shell
echo $$                      

# print process ID of the most recently invoked background job
echo $!
                 
# print the exit status of the last command
echo $?

# export an environment variable (will be available in subprocesses)                  
export VARNAME=value         

# several ways to define an array
arr[0]='val'               
arr[1]='val'
declare -a arr=(element1 element2 element3)
declare -a Unix=('Debian' 'Red hat' 'Red hat' 'Suse' 'Fedora');

# array value via index. If no index is supplied, array element 0 is assumed
${arr[i]}
                 
# length of array             
${#arr[@]}

declare -f                   # uses function names only
declare -F                   # displays function names without definitions
declare -i                   # the variables are treated as integers
declare -r                   # makes the variables read-only
declare -x                   # marks the variables for export via the environment

# if var exists and isn't null, return its value; otherwise return word
${var:-word}             

# if var exists and isn't null, return its value,
# ;otherwise set it word and then return its value
${var:=word}

# if var exists and isn't null, return its value; otherwise print var, 
# followed by message and abort the current command or script             
${var:?message}          

# if var exists and isn't null, return word; otherwise return null
${var:+word}             

# performs substring expansion. It returns the substring of $var starting 
# at offset and up to length characters
${var:offset:length}     

# if the pattern matches the beginning of the variable's value, 
delete the shortest part that matches and return the rest
${var#pattern}

# if the pattern matches the beginning of the variable's value, delete 
# the longest part that matches and return the rest         
${var##pattern}

# if the pattern matches the end of the variable's value, delete 
# the shortest part that matches and return the rest        
${var%pattern}

# if the pattern matches the end of the variable's value, delete 
# the longest part that matches and return the rest         
${var%%pattern}
         
# the longest match to pattern in variable is replaced by string. 
# Only the first match is replaced
${var/pattern/string}

# the longest match to pattern in variable is replaced by string. 
# All matches are replaced   
${var//pattern/string}  

# returns the length of the value of the variable as a character string
${#var}                  

# matches zero or more occurrences of the given patterns
*(patternlist)               

# matches one or more occurrences of the given patterns
+(patternlist)

# matches zero or one ocurence of the given patterns               
?(patternlist)               

# matches exactly one of the given patterns
@(patternlist)               

# matches anything except one of the given patterns
!(patternlist)              

# command substitution
$(command)              

Flow Control

Checking files

# file exists (also true if file is directory)
-a file 
                  
# file exists and is a directory
-d file
                   
# file exists; same -a
-e file                   

# file exists and is a regular file
# (i.e., not a directory or other special type of file)
-f file                   

# file is readable
-r file                   

# file is writeable
-w file 

# file is executable
-x file  

# file exists and is not empty
-s file                   

# file was modified since it was last read                  
-N file                   

# you own file
-O file 
                  
# file's group ID matches yours (or one of yours, if you are in multiple groups)
-G file                   

# file1 is newer than file2
file1 -nt file2 

# file1 is older than file2          
file1 -ot file2           

# Examples
if [ -f "path/to/file" ]
then
  command
  command
fi

if [ -d "/path/to/dir" ] 
then
    echo "Directory /path/to/dir exists." 
else
    echo "Error: Directory /path/to/dir does not exists."
    exit 1
fi

if [ ! -d "/path/to/dir" ] 
then
    echo "Directory /path/to/dir DOES NOT exists." 
    exit 9999 # die with error code 9999
fi

Checking strings

str1=str2    # str1 matches str2
str1!=str2   # str1 does not match str2
str1<str2    # str1 is less than str2
str1>str2    # str1 is greater than str2
-n str1      # str1 is not null (has length greater than 0)
-z str1      # str1 is null (has length 0)

# Examples
if [ $myvar = "hello" ]
then
  echo "We have a match"
fi

Checking numbers

-lt  # less than
-le  # less than or equal
-eq  # equal
-ge  # greater than or equal
-gt  # greater than
-ne  # not equal

# Examples
if [ $# -gt 1 ]
then
  echo "ERROR: should have 0 or 1 command-line parameters"
fi

if [ num -gt 24 ]
then
  echo "big number"
elif [ num -ge 8 ]
then
  echo "medium number"
elif [ num -ge 0 ]
then
  echo "small number"
else
  echo "negative number"
fi

Boolean operators

!     not
-a    and
-o    or

# Examples
   if [ $num -lt 10 -o $num -gt 100 ]
   then
      echo "Number $num is out of range"
   elif [ ! -w $filename ]
   then
      echo "Cannot write to $filename"
   fi

if [ num -gt 24 ]
   then
      echo "big number"
   elif [ num -ge 8 ]
   then
      echo "medium number"
   elif [ num -ge 0 ]
   then
      echo "small number"
   else
      echo "negative number"
   fi

# grouping
# parentheses may be used for grouping, but must be preceded by backslashes
# since parentheses normally have a different meaning to the shell (namely
# to run a command or commands in a subshell)
# For example, you might use:

if test \( -r $file1 -a -r $file2 \) -o \( -r $1 -a -r $2 \)
then
   do something
fi

# Note that ifs can be nested
   if [ $myvar = "y" ]
   then
      echo "Enter count of number of items"
      read num
      if [ $num -le 0 ]
      then
         echo "Invalid count of $num was given"
      else
         ... do whatever ...
      fi
   fi

# The above example also illustrates the use of read to read a string from
# the keyboard and place it into a shell variable.  Also note that most UNIX
# commands return a true (nonzero) or false (0) in the shell variable status
# to indicate whether they succeeded or not.  This return value can be checked.
# At the command line echo $status.  
# In a shell script use something like this:

   if grep -q shell bshellref
   then
      echo "true"
   else
      echo "false"
   fi

# Note that -q is the quiet version of grep.  It just checks whether it is true
# that the string shell occurs in the file bshellref.  It does not print the
# matching lines like grep would otherwise do.

Case statement

Here is an example that looks for a match with one of the characters a, b, c.
If $1 fails to match these, it always matches the * case.  A case statement
can also use more advanced pattern matching.

case expression in
  pattern1 )
    statements ;;
  pattern2 )
    statements ;;
  ...
esac

# Examples
case "$1" in
   a) cmd1 ;;
   b) cmd2 ;;
   c) cmd3 ;;
   *) cmd4 ;;
esac

Select statement

select name [in list]
do
  statements that can use $name
done

Examples:

Loops

# for loop
for name [in list]
do
  statements that can use $name
done

for arg in [list] ; do
    echo $arg
done

# Examples
NUMBERS="1 2 3"
for number in `echo $NUMBERS`
do
  echo $number 
done

for number in $NUMBERS
do
  echo -n $number
done

for number in 1 2 3
do
  echo -n $number
done

for file in *.tar.gz
do
  tar -xzf $file
done

for x in `ls -tr *.log`
do
   cat $x >> biglog
done

for (( initialisation ; ending condition ; update ))
do
  statements...
done

# Examples

# while loop
while condition; do
  statements
done

# Examples

# until loop
until condition; do
  statements
done

# Examples

Shell Arithmetic

# In the original Bourne shell arithmetic is done using the expr command as in:
result=`expr $1 + 2`
result2=`expr $2 + $1 / 2`
result=`expr $2 \* 5`     (note the \ on the * symbol)

# With bash, an expression is normally enclosed using [ ] and can use the
# following operators, in order of precedence:
* / %       (times, divide, remainder)
+ -         (add, subtract)
< > <= >=   (the obvious comparison operators)
== !=       (equal to, not equal to)
&&          (logical and)
||          (logical or)
=           (assignment)
Arithmetic is done using long integers.

# Example
result=$[$1 + 3]

In this example we take the value of the first parameter, add 3, and place
the sum into result.

Functions

function_name() {
  shell commands
}

# deletes a function definition
unset -f function_name

# displays all defined functions in your login session
declare -f          

Command-Line Processing Cycle

# The default order for command lookup is 
# 1. functions, 
# 2  built-ins, 
# 3 scripts and executables

# There are three built-ins that you can use to override this order: `command`, `builtin` and `enable`.

command  # removes alias and function lookup. Only built-ins and commands found in the search path are executed
builtin  # looks up only built-in commands, ignoring functions and commands found in PATH
enable   # enables and disables shell built-ins

eval     # takes arguments and run them through the command-line processing steps all over again

Input/Output Redirection

# file descriptor 0 is normally standard input
# file descriptor 1 is standard output
# file descriptor 2 is standard error output.
cmd1|cmd2  # pipe; takes standard output of cmd1 as standard input to cmd2
> file     # directs standard output to file
< file     # takes standard input from file
>> file    # directs standard output to file; append to file if it already exists
>|file     # forces standard output to file even if noclobber is set
n>|file    # forces output to file from file descriptor n even if noclobber is set
<> file    # uses file as both standard input and standard output
n<>file    # uses file as both input and output for file descriptor n
<<label    # here-document
n>file     # directs file descriptor n to file
n<file     # takes file descriptor n from file
n>>file    # directs file description n to file; append to file if it already exists
n>&        # duplicates standard output to file descriptor n
n<&        # duplicates standard input from file descriptor n
n>&m       # file descriptor n is made to be a copy of the output file descriptor
n<&m       # file descriptor n is made to be a copy of the input file descriptor
&>file     # directs standard output and standard error to file
<&-        # closes the standard input
>&-        # closes the standard output
n>&-       # closes the ouput from file descriptor n
n<&-       # closes the input from file descripor n

Process Handling

# To suspend a job, type CTRL+Z while it is running. 
# You can also suspend a job with CTRL+Y.
# This is slightly different from CTRL+Z in that the process is only stopped 
# when it attempts to read input from terminal.
# To interrupt a job, type CTRL+C.

myCommand &  # runs job in the background and prompts back the shell

jobs         # lists all jobs (use with -l to see associated PID)

fg           # brings a background job into the foreground
fg %+        # brings most recently invoked background job
fg %-        # brings second most recently invoked background job
fg %N        # brings job number N
fg %string   # brings job whose command begins with string
fg %?string  # brings job whose command contains string

kill -l      # returns a list of all signals on the system, by name and number
kill PID     # terminates process with specified PID

ps           # prints a line of information about the current running login shell and any processes running under it
ps -a        # selects all processes with a tty except session leaders

trap cmd sig1 sig2  # executes a command when a signal is received by the script
trap "" sig1 sig2   # ignores that signals
trap - sig1 sig2    # resets the action taken when the signal is received to the default

disown <PID|JID>    # removes the process from the list of jobs

wait                # waits until all background jobs have finished

Debugging shell scripts

bash -n scriptname  # don't run commands; check for syntax errors only
set -o noexec       # alternative (set option in script)

bash -v scriptname  # echo commands before running them
set -o verbose      # alternative (set option in script)

bash -x scriptname  # echo commands after command-line processing
set -o xtrace       # alternative (set option in script)

# useful when you want to print out the values of variables at the point that your script exits
trap 'echo $varname' EXIT  

function errtrap {
  es=$?
  echo "ERROR line $1: Command exited with status $es."
}

# is run whenever a command in the surrounding script or function exists with non-zero status 
trap 'errtrap $LINENO' ERR  

function dbgtrap {
  echo "badvar is $badvar"
}

# causes the trap code to be executed before every statement in a function or script
# ...section of code in which the problem occurs...
trap dbgtrap DEBUG  

# turn off the DEBUG trap
trap - DEBUG  

function returntrap {
  echo "A return occurred"
}

# is executed each time a shell function or a script executed with 
# the . or source commands finishes executing
trap returntrap RETURN  
⚠️ **GitHub.com Fallback** ⚠️