Useful Shell Commands
printenv | less # display all the environment variables
set | less # same as above but includes shell variables sorted alphabetically
> test.txt # create a new file
ls -l /bin/usr > ouput.txt 2>&1 # write stdout and stderr to output2.txt
ls -l $(which node) # displays information about a command
mkdir {2007..2009}-{01..12} # create folders from year 2007 to 2012.
history | grep docker # searches for docker commands in history
!3 # displays the 3rd item in bash's command history
kill -l # list all supported signals
source .bashrc # forces bash to re-read the file
. .bashrc # same as above, where . is the same as source
find ~ -type f -name "*.JPG" -delete # searches for jpeg files and deletes them
ls -l /etc | gzip > foo.txt.gz # compress a folder
ssh REMOTE 'tar cf - REMOTE_FOLDER | tar xf -' # transfer files from a remote server
grep -i '^j' /usr/share/dict/words # search dictionary for words starting with j
cat -A foo.txt # output non-printing characters like tabs and spaces
cat -ns test.txt > testwithnumbers.txt # add line numbers to a text file
sort file1.txt file2.txt file3.txt > sorted.txt # creates 1 sorted file
[[ -d DIRECTORY ]] || mkdir DIRECTORY # check a directory, create it if not found
basename FILEPATH # to extract the filename from a specified path
export USER_DATE=$(date +%Y%m%d_%H%M%S) # easy date variable in .bashrc Introduction
- "graphical user interfaces make easy tasks easy, while command line interfaces make difficult tasks possible"
- command line knowledge is akin to knowledge of sql, it lasts a long time because the technology has survived the test of time
Part 1 – Learning The Shell
1 – What Is The Shell?
- BASH - Bourne Again because it's supposed to be an enhanced replacement for
shwritten by Steve Bourne - Terminal emulators like the
terminalapplication (interacts with or gives access) to the shell programbashbut isn't really the shell itself. - If the shell prompt starts with a
#, it means your session has superuser privileges cal 2017to display a calendar
2 – Navigation
cd -switch to the previous working directorycd ~user_nameswitch to the home directory of said user- Linux has no concept of file extensions. The contents of files are determined by other means. You can name your files however you want.
- Recommended to use underscore in favor of spaces for file names
3 – Exploring The System
- Most commands follow this syntax
command -options arguments ls . / /varto list 3 directoriesfile <FILENAME>to determine the file type - note 3rd point on Chapter 2less <FILENAMEto page through contents of a file
4 – Manipulating Files And Directories
ls -lito show hard links
5 – Working With Commands
alias name='string'to create an alias, andunalias ALIAS_NAMEto remove italiasto list all the environment alias
6 – Redirection (and Pipelines)
- There are always 3 files open when you work in the shell - (1)
stdinfor the keyboard (2)stdoutfor the screen and (3)stderrfor error messages sent to the screen. - Unix maintains "everything is a file". The same is true for results of shell commands, only their outputs and errors are sent to
stdout(Standard Output) andstderr(Standard Error) respectively but both are connected to your terminal screen. I/O Redirection works by passing along shell outputs to a different program other than the terminal (like a text file) using the>symbol creating another file as an end result. > FILENAMEfaster way of creating a new file than usingtouch FILENAME- Use
>>when appending results to a file ls -l /bin/usr > ls-output.txt 2>&1Redirects stdout and stderr to the same file where&1means use the file descriptor 1ls-output.txt. The order of commands is important for obvious reasons. More recent bash versions support this shorter versionls -l /bin/usr &> ls-output.txt- To dispose unwanted output you can redirect it to
/dev/null. It's a system bit bucket that does nothing to its input cat > FILENAME.EXTto save typed text in the terminal to a file. You mustCtrl + dat the end of editing.- The use of pipes are usually associated to filtering
tail -f FILENAMEallows you to view file changes real timeteecopies results to bothstdoutand a file. This can be a good strategy to inspect changes before it happens like inls /usr/bin | tee ls.txt | grep zip
7 – Seeing The World As The Shell Sees It
- Expansion is the process that expands an expression (like wildcards) before the shell acts on it. Although the next points below uses
echo, expansion works on (almost??) all shell commands. echo *Pathname expansion where*translates to everything in the current directory. It is suppressed when the expression is wrapped in double quotes.echo ~Tilde expansion that prints the path of the current user's home directory. It is suppressed when the expression is wrapped in double quotes.echo $((2+2))- Math expansion, requires double parentheses. It still works when the expression is wrapped in double quotes.echo {1..9}- Brace expansion that generates a set of of items from the given pattern. It is suppressed when the expression is wrapped in double quotes.echo $USER- Parameter expansion that outputs theUSERenvironment variable. It still works when the expression is wrapped in double quotes.echo $(ls)- Command substitution. It prints the results ofls. Older shell programs uses back quotes instead of$()syntax. It still works when the expression is wrapped in double quotes.- Suppressing expansions
echo "1+1 = $((1+1))"Double quotes suppresses some expansionsecho '1+1 = $((1+1))'Single quotes suppresses all expansions
8 – Advanced Keyboard Tricks
- Tab completion works on path names, environment variables, user names, and hostnames (some caveats at least in Ubuntu) if it is listed in
/etc/hosts
9 – Permissions
idfinds out information about your identity- User related folders
/etc/passwdfor user accounts/etc/groupfor user groupsetc/shadowfor passwords and account expiration
- Symbolic links have dummy permissions. The target file has the right permission.
- Page 118 has some good explanation on octal vs hex vs decimal number systems
- Although there are a lot of similarities,
sudodoes not start a new shell nor load a user's environment unlikesu.
10 – Processes
topdisplays a list of running processes updated every 3s. Presshfor help andqto quit.- Put a
&after a command to run it in the background. A background process ignores keyboard input. Usejobsto see a list thenfg %JOB_NUMBERto return the process to the foreground, thenbg %JOB_NUMBERto put it back to the background. Ctrl-csends aINT(interrupt) signal,Ctrl-zsends aTSTP(Terminal Stop).- Common signals that you can use when using
kill. You can use the number, name or the name prefixed withSIG. Usekill -lto view a list of signals. - Use
killallto send signals to multiple processes
Part 2 – Configuration And The Environment
11 – The Environment
^Xat the footer when you runnano FILENAMEindicates the use ofCtrlin combination with the character.
12 – A Gentle Introduction To vi
- The lack of graphical interface in some Unix systems encourages the use of
vibecause it is universal (POSIX standard) viis derived from "visual" intended to allow editing on a video terminal- If you get lost in
vi, pressing Esc twice should help you out viruns on different modes. At startup it is configured to run on command mode. That's why you have to pressito enter into insert mode
13 – Customizing The Prompt
Part 3 – Common Tasks And Essential Tools
14 – Package Management
- Low-level tools (dpkg for Debian, rpm for Fedora) takes care of install/uninstall while High-level tools (apt-get for Debian, yum for Fedora) perform metadata searching and dependency resolution.
15 – Storage Media
- Unmounting entails moving the buffer to the device so it can be safely removed mitigating chances of corruption
genisoimage -o FILENAME.iso -R -J ~/DIRECTORYcreates a disc image from a directory- Mounting an image
mkdir /mnt/iso_image # creates a mount point
mount -t iso9660 -o loop FILENAME.iso /mnt/iso_image16 – Networking
- When
ping'ed, a properly working network should have 0 packet loss - Use
netstatto examine various network settings
17 – Searching For Files
locate STRINGsearches for files and pathnames. The database it searches for relies on a cron that runsupdatedb. When search is out of sync, one can runupdatedbfirst.find DIRECTORY (EXPRESSION) -LOGICAL_OPERATOR (EXPRESSION)searches for files in a directory with filters. Supportedfindsize units arebdefault for 512-byte blocks,cfor Bytes,wfor 2-byte words,kfor Kilobytes,Mfor Megabytes,Gfor Gigabytesxargsaccepts input from standard input and uses it as argument for the piped command.find . -type f -name '*git' -print | xargs ls -lfinds all the files withgitin its name on the current directory and passes it alonglsfor more details.
18 – Archiving And Backup (using Lossless Compressions)
- Data compression is the process of removing redundant data. Compression algorithms fall into 2 categories:
- Lossless preserves all the all the information of the uncompressed version during compression creating an identical match of the original on restore
- Lossy removes data during compression to allow for more compression creating a close approximation of the original when restored. Examples are JPEG and MP3 compressions.
gzipdeletes the file and creates a compressed version of the original.gzip FILEto compress,gunzip FILEto uncompress and assumes thatFILEends with.gzsogunzip file1.txt.gzis the same asgunzip file1.txtbzipandbunzipis similar to gzip but with a different algorithm- Archiving is the process of bundling files together
tar(short for tape archive) is the most common tool for archiving in Unix.- It follows
tar mode[options] pathnamesyntax. - An important note is
tarpaths are created relative to your current directory during extraction. If you rantaron the~folder then extract it on/, the output will be/home/myaccount/TAR_CONTENTS. So remember tocdinto a folder first if you plan to restore files that match the directory structure of the original. - You can gzip a tar by adding the
zoption, e.g.tar czf TARFILE.tgz . - You can pipe
findresults e.g. `find ~/Downloads -name 'file-A' | tar czf
- It follows
downloads.tgz -T -where the trailing slash means the output of thefind` command piped as standard input, or "use standard input for the input file."
zipis both compression and archiving tool. Use withunzip. Can be piped to and understands the trailing dash argument liketar. Mainly used for Windows interoperability.rsyncsyncs local and remote (and possible combinations except remote to remote) directories. Syntax isrsync options source destination
19 – Regular Expressions
- Unix systems supports POSIX standard regular expressions, POSIX Character classes like
[:word:], and Extended Regular Expressions (use of pipes for alternation) grepis global regular expression print. Syntax isgrep [options] regex [file...]
20 – Text Processing
- You can use
sortto order contents of standard input into standard output. You can also merge multiple files into one sorted file. When referencing columns,sortuses tabs and spaces as delimiter for fields by default or you can use-toption to specify your own separator character. uniqonly removes duplicates from adjacent lines. You need to have your input sorted first before it can be ran.cut -f 3 -d '^' distros.txt | cut -c 7-10-cutis piped here to further text extraction from the 7th to 10th character of the first outputpasteandjoinallows you to add contents to a filecomm -OPTION[1|2|3] file1.txt file2.txtfor simple file comparisons anddifffor more complex ones. You can usepatchin conjunction withdiffto resolve differences.- Use
tr(transliterate) for simple search and replace andsedfor more complex tasks. Both works with standard input and output withsedproviding so much more options - Use
aspellto check for spelling errors interactively
21 – Formatting Output
nl FILENAMEto print numbered linesfoldwraps lines of text to a specified length andfmtperforming the same plus some more features.pris used to paginate text
22 – Printing
- Back in heydays of impact printers, a US-Letter paper composed of 85 characters wide and 66 lines of monospaced characters. It explains why terminal displays are normally 80 characters wide.
23 – Compiling Programs
- Most programs build follow the 2-command sequence
./configureandmake. The former relies on theMakefile. Then to install a built program, runmake install.
Part 4 – Writing Shell Scripts
24 – Writing Your First Script
- Use
755withchmodfor scripts that everyone can execute and700to limit to the owner - The
PATHvariable values stores locations of executables that do not require reference to the folder when ran in the terminal. - Local executables are recommended to be placed under
/usr/local
25 – Starting A Project
- The shebang
#!/bin/bashline or the interpreter directive indicates the location of the interpreter to use,/bin/bashin this case, when the script is ran as a program. - There should be no spaces when assigning values to variables in a script file, else it will not get picked up. This
TITLE = "Test"will result in the errorTITLE: Command not found - All variables are treated as string unless you use
declarewith an-ioption - Wrap a variable in curly braces to avoid ambiguity. Assuming
USERis "foo",touch ${USER}1.txtcreates a file namefoo1.txt. - A Here Document is a form of redirection to feed a body of text or a code block into an interactive command like
cat,ftp, orgrep. The most common use in a shell script is to preserve multiple lines of text, preserving double quotes, single quotes and tabs (if specified). It uses an arbitrary token to indicate the start and end of the input.
#!/bin/bash
TITLE="Hello World"
# Use cat <<- HERETOKEN
cat << HERETOKEN
<HTML>
<HEAD>
<TITLE>$TITLE</TITLE>
</HEAD>
<BODY>
<P>Title: "$TITLE"</P>
</BODY>
</HTML>
HERETOKEN26 – Top-Down Design
- Shell functions
function NAME_OF_FUNCTION {
commands #at least 1 command
return #optional
}
#or the preferred method
NAME_OF_FUNCTION() {
commands
return
}
# execute
NAME_OF_FUNCTION- Local function variables are preceded by
localon declaration
funct_1 () {
local foo # variable foo local to funct_1
foo=1
echo "funct_1: foo = $foo"
}- Shell functions are great replacement for the limits of aliases
27 – Flow Control: Branching With if
- IF Syntax, where
[ EXPRESSION ]is a shorthand fortest EXPRESSIONcommand. Note that the space after the brackets are required.- Short form:
if [ EXPRESSION ]; then COMMANDS; else COMMANDS; fi - Long form:
- Short form:
if [ EXPRESSION ]; then
COMMANDS
elif [ EXPRESSION ]; then
COMMANDS...
else
COMMANDS
fi- A
testexpression can be:- File expression
if [ -e FILE ]; then ...if file exists - String expressions
if [ -n STRING /> 0 ]; then..if a string is not empty. Note the use of backslash to avoid redirection when used withtest - Integer expression
if [ 3 -eq 2 ]; then..if integer 1 is equal to integer 2
- File expression
- There are also compound commands to replace
testexpressions and is preferred for modern scripts because of its readability- If you want to use regular expressions you can use the compound command
if [[ "hello" =~ ^[world+$ ]]]... - If you want to check for patterns, use the compound command
if [[ "hello" == hell.* ]]; ... - If you want to use math operators you can use the compound command
(( FOO > 0 )), whereFOOis a variable but without the need to be prefixed with a$sign
- If you want to use regular expressions you can use the compound command
- Differences when combining expressions between
testand compound commands
| operator | test | compound |
|------------|------|----------|
| AND | -a | && |
| OR | -o | || |
| NOT | ! | ! |- If a variable can have a null value, you can wrap it in double quotes within your expression to fallback to an empty string, e.g.
if [[ "$int1" == 1 ]]; - Every command has its exit code. A value of
0indicates that the command executed and a greater value meant an error occurred. You can assign your own non-zero value to indicate an error in your function or when yourIFconditions fail. You can pick up the exit code value from$?. Use this to your advantage in your shell script to check whether a command ran properly:
#!/bin/bash
cd ~/Downlooads
if [[ $? > 0 ]]; then
echo "no such directory"
fi28 – Reading Keyboard Input
- You can use
readin your shell file to listen for a keyboard input. If you did not explicitly assign a variable (int1in the example below) for the input, the value will be assigned to$REPLYby default.
#-n suppresses the trailing new line
echo -n "Enter an integer "
# Or read int1 int2 int3 if expecting multiple inputs
read int1
# Or use the -p for prompt option to replace the first 2 lines
# -i supplies 1 as the default value
# read -e -p "Enter an integer " -i 1 int1
echo $int1readcannot be piped to
29 – Flow Control: Looping With while / until
- While loop uses the same expressions as
IFand its syntax iswhile EXPRESSION; do COMMANDS; done. You can use thebreakkeyword to exit out. untilis the opposite ofwhile.while [[ $count <= 5 ]]is the same asuntil [[ $count > 5 ]]
30 – Troubleshooting
- Activate bash tracing by adding
-xin your directive#!/bin/bash -x
31 – Flow Control: Branching With case
- Case example
cd ~/Downloadss
case $? in
0) echo "Directory found."
exit
;;
*) echo "No such directory."
exit 1
;;
esac32 – Positional Parameters
- Whenever you run a command, the shell creates a set of variables called positional parameters to represent every word in the command. By default it gives you
$0to$9where$0always represent the name of the command you ran. - For parameters greater than 9, you have to wrap the number in braces, e.g.
${10} - Use
$#to determine the number of arguments - If the arguments are too large such as in the case when an
*is used, you can run awhileloop against$#and useshiftto move an argument up one at a time, e.g.$2to$1,$3to$2 - Use
$*or$0to capture arguments at once. If there are 2 command arguments where one argument consists of 3 words and the other 1 word,$*will split the arguments from 1-4 and"$*"will combine all 4 into 1$@will split the arguments from 1-4 and"$@"will split it into 2 matching the command executed
33 – Flow Control: Looping With for
- Traditional
forexample
# for i in A B C D;
# for i in ARRAY_VARIABLE
for i in {A..D}; do
echo $i;
doneforin C Language form
for (( i=0; i<5; i=i+1 )); do
echo $i
done34 – Strings And Numbers
- Wrap variables in braces if you intend to use it next to a string, e.g.
${VAR}_string - Assigning default values to variables:
echo ${VARIABLE:-VALUE}, variable is unchanged and just uses the given valueecho ${VARIABLE:=VALUE}, assigns value to the variableecho ${VARIABLE:?VALUE}throws an error if value is not suppliedecho ${VARIABLE:+VALUE}does nothing if empty, but uses the value without altering the variable if supplied
- Useful string functions:
echo "${#foo} for character length"echo "${foo:5:6} for substring"echo "$(foo#*.} removes the first word from file.txt.zip - before the dot"echo "${foo%.*} removes the last word from file.txt.zip - after the dot"echo ${foo//find/replace} #global find and replace
- Use
declare -u upper|lowerto enforce variable casing
35 – Arrays
- Declaring arrays
a[0] = 1
declare -a b #indexed arrays
b[0] = 0
declare -A c #keyed arrays
c[key] = value
d=(Su Mo Tu We Th Fr Sa)
e=([0]=Jan [1]=Feb [2]=Mar)- Printing array contents
animals=("a dog" "a cat" "a fish")
# Difference between array[*] and array[@]
# both will print each word on its own line (6 total)
for i in ${animals[*]}; do echo $i; done
for i in ${animals[@]}; do echo $i; done
# quoted, this prints in a single line
for i in "${animals[*]}"; do echo $i; done
# quoted, this prints 3 lines reflecting the number of items in an array
for i in "${animals[@]}"; do echo $i; doneecho ${#ARRAY[@]}to get the length of the arrayecho ${#ARRAY[INDEX]}to get the length of an array itemfoo+=(d e f)appends an item to the arraya_sorted=($(for i in "${a[@]}"; do echo $i; done | sort))sorts an array into a new one- Use
unset ARRAYto delete an array orunset 'ARRAY[INDEX]'to delete an item - quoted to prevent expansion - Newer bash versions support associated arrays
declare -A colors
colors["red"]="#ff0000"
echo ${colors["red"]}36 – Exotica
- Combining commands using
{}and()instead of multi-line approach{ cd ~; ls -l } > test.txt- grouping- a space is required here. Commands are executed in its own shell. Preferred because of its shell handling.(cd ~; ls -l) > test.txt- subshell. Commands are executed in a child copy of the current shell
- Process Substitution to capture values from a subshell. -
read < <(echo "foo") #$REPLY is now "foo"