Skip to main content

Bash Proficency

Bash Proficiency In Under 15 Minutes

Bash Proficiency In Under 15 Minutes

Cheat sheet and in-depth explanations located below main article contents… The UNIX shell program interprets user commands, which are…

Bash Proficiency In Under 15 Minutes

Cheat sheet and in-depth explanations located below main article contents… The UNIX shell program interprets user commands, which are either directly entered by the user, or which can be read from a file called the shell script or shell program. Shell scripts are interpreted, not compiled. The shell reads commands from the script line per line and searches for those commands on the system while a compiler converts a program into machine readable form, an executable file.


LIFE SAVING PROTIP:

A nice thing to do is to add on the first line

#!/bin/bash -x


What is Bash?

Apart from passing commands to the kernel, the main task of a shell is providing a user environment through which they can issue the computer commands via a command line instead of the graphical user interfaces most software consumers are familiar with.

fire meme

Here’s a REPL with some examples for you to practice….

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ below motivational monologue ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

Remember: learning is an effortful activity… it’s not comfortable… practice might be unpleasant but if you don’t you might as well skip reading too because without application… reading articles just provides a false sense of accomplishment….

quote by: … me 1 minute ago (inspired by veritasium….)

Aforementioned Repl:


Navigate the file system

Change bash’s current working directory

cd <file path here>
# to go up a directory from your current directory
cd ..

List a directory’s contents

ls
# for more details, add -l (long)
ls -l
# this will output something like this:
# -rw-r--r-- 1 cameronnokes staff 1237 Jun 2 22:46 index.js
# in order, those columns are:
# permissions for you, your group, all
# number of links (hardlinks & softlinks)
# owner user
# owner group
# file size
# last modified time
# file name
# to see hidden files/folders (like .git or .npmignore)
ls -a
# Note, flags can be combined like so
ls -la

View files and folders in bash

Output a file to the screen (stdout)

cat <file name>
# shows it with line numbers
cat -n <file name>

View a file in bash

# view the file without dumping it all onto your screen
less <file name>
# Some useful shortcuts in less
# Shift+g (jump to end)
# g (go back to top)
# / (search)
# q (quit/close)

View file/folder in default application associated with it

open <file/folder name>
# view current directory in Finder
open .
# specify an application to use
open <file name> -a TextEdit
folder structure

Create and delete files and folders

Create a file

touch <file name>

Set or append to a file

# set the file's contents
echo 'hi' > file.txt
# append to file's contents
echo 'hi' >> file.txt
# note that if you pass a file name that doesn't exist, it'll get created on the fly

Create a directory

mkdir <folder name>
# make intermediary directories as needed
mkdir -p parent/child/grandchild

Remove a file

# Note, this permanently deletes a file
rm <file name>
# Remove a folder and it's contents, recursively
rm -rf <folder name>

Move and Copy Files and Folders with bash

Move a file

mv <target> <destination>
# for example, to rename a file
mv a.js b.js
# move all files in a folder to another folder
mv lib/* src

Copy a file

cp <target> <destination>
# copy everything recursively from one folder to another
cp -R src/* lib

Find Files and Folders with find in bash

find
# find all the PNGs in a folder
find <path> -name "*.png"
# find all the JPGs (case insensitive) in a folder
find <path> -iname "*.jpg"
# find only directories
find <path> -type d
# delete all matching files
find <path> -name "*.built.js" -delete
# execute an arbitrary action on each match
# remember `{}` will be replaced with the file name
find <path> -name "*.png" -exec pngquant {} \;

Search for text with grep

# Basic usage
grep <pattern> <target file or glob>
# Useful flags
# --color (colorizes matches)
# -n (show line numbers)
# -C <number> (show N lines above/below match for context)
# -e (regex search)

Make HTTP requests in bash with curl

http

The test server is available in the curl-practice-server directory. Run npm install && npm start to run it.

curl <url>
# Useful flags
# -i (show response headers only)
# -L (follow redirects)
# -H (header flag)
# -X (set HTTP method)
# -d (request body)
# -o (output to a file)
# to POST JSON
# (technically you don't need -X POST because -d will make it POST automatically, but I like to be explicit)
curl -X POST -H "Content-Type: application/json" -d '{ "title": "Curling" }' http://localhost:3000/api/posts
# POST a url encoded form
curl -X POST --data-urlencode title="Curling again" http://localhost:3000/api/posts
# multiline curl (applies to any bash command)
curl -i -X PUT \
-d '{ "title": "Changed title" }' \
-H "Content-Type: application/json" \
http://localhost:3000/api/posts
# pretty print JSON with jsome
curl https://swapi.co/api/people/1/ | jsome

Here’s the jsome package that pretty prints JSON

Create and run bash scripts

bash scripting
echo 'echo Hello World' > script.sh
chmod u+x script.sh
./script.sh

The init-js.sh script for scaffolding a JS project

echo "Initializing JS project at $(pwd)"
git init
npm init -y # create package.json with all the defaults
mkdir src
touch index.js
code .

One way to add that script to your $PATH:

cp init-js.sh /usr/local/bin/init-js

Store and Use Values with bash Variables

# no spaces between name, =, and value
var=123
echo $var
# to make it accessible to all child processes of current shell, export it
export var
# this deletes the variable
unset var

To see all environment variables

env

clone-to-temp.sh script:

temp=$(mktemp -d)
git clone --branch $1 $PWD $temp
echo "branch $1 cloned to $temp"
# run some tasks, tests, etc here

Understand and use functions in bash

greet() {
echo "$1 world"
}
greeting=$(greet "howdy")
echo "the greeting is $greeting"
global=123
test() {
echo "global = $global"
local local_var="i'm a local"
echo "local_var = $local_var"
}
test
echo "global = $global"
echo "local_var = $local_var" # will be empty because it's out of scope

Understand exit statuses in bash

Get the last run command’s exit status

ls
# will be 0 if it ran successfully, 1 - 255 for an error
echo $?

Exit statuses and functions. script.sh

ok() {
return 0
}
fail() {
return 1
}
fail
ok
./script.sh
echo $? # exit status is same as the last run function/command

Use Conditional Statements in bash

Basic form

# Some conditional primaries that can be used in the if expression:
# =, != string (in)equality
# -eq, -ne numeric (in)equality
# -lt, -gt less/greater than
# -z check variable is not set
# -e check file/folder exists
if [[ $USER = 'cameronnokes' ]]; then
echo "true"
else
echo "false"
fi

Conditionals can be used inline in a more ternary-like format

[[ $USER = 'cameronnokes' ]] && echo "yes" || echo "no"

check-status.sh for checking a URL is responding with a 200

check_status() {
local status=$(curl -ILs $1 | head -n 1 | cut -d ' ' -f 2)
if [[ $status -lt 200 ]] || [[ $status -gt 299 ]]; then
echo "$1 failed with a $status"
return 1
else
echo "$1 succeeded with a $status"
fi
}
check_status https://example.org
check_status https://example.org/404

Chain Commands with Pipes and Redirect Output in bash

Pipes

# ps ax will list all running processes
ps ax | grep Chrome | less
# get the file size after uglify + gzip
uglifyjs -c -m -- index.js | gzip -9 | wc -c

Redirection

# redirect stdout to a file
ls > ls.txt
# append stdout to a file
echo "hi" >> ls.txt

Update(Utility Commands):

Find files that have been modified on your system in the past 60 minutes

find / -mmin 60 -type f

Find all files larger than 20M

find / -type f -size +20M

Find duplicate files (based on MD5 hash)

find -type f -exec md5sum '{}' ';' | sort | uniq --all-repeated=separate -w 33

Change permission only for files

cd /var/www/site && find . -type f -exec chmod 766 {} \;
cd /var/www/site && find . -type f -exec chmod 664 {} +

Change permission only for directories

cd /var/www/site && find . -type d -exec chmod g+x {} \;
cd /var/www/site && find . -type d -exec chmod g+rwx {} +

Find files and directories for specific user/group

# User:
find . -user <username> -print
find /etc -type f -user <username> -name "*.conf"
# Group:
find /opt -group <group>
find /etc -type f -group <group> -iname "*.conf"

Find files and directories for all without specific user/group

# User:
find . \! -user <username> -print
# Group:
find . \! -group <group>

Looking for files/directories that only have certain permission

# User
find . -user <username> -perm -u+rw # -rw-r--r--
find /home -user $(whoami) -perm 777 # -rwxrwxrwx
# Group:
find /home -type d -group <group> -perm 755 # -rwxr-xr-x

Delete older files than 60 days

find . -type f -mtime +60 -delete

Recursively remove all empty sub-directories from a directory

find . -depth  -type d  -empty -exec rmdir {} \;

How to find all hard links to a file

find </path/to/dir> -xdev -samefile filename

Recursively find the latest modified files

find . -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

Recursively find/replace of a string with sed

find . -not -path '*/\.git*' -type f -print0 | xargs -0 sed -i 's/foo/bar/g'

Recursively find/replace of a string in directories and file names

find . -depth -name '*test*' -execdir bash -c 'mv -v "$1" "${1//foo/bar}"' _ {} \;

Recursively find suid executables

find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \;

Additional learning resources


Here’s My Github & Website … feel free to reach out!

Explanations:

Pipes

Pipes let you use the output of a program as the input of another one

simple pipe with sed

This is very simple way to use pipes.

ls -l | sed -e "s/[aeio]/u/g"

Here, the following happens: first the command ls -l is executed, and it’s output, instead of being printed, is sent (piped) to the sed program, which in turn, prints what it has to.

an alternative to ls -l *.txt

Probably, this is a more difficult way to do ls -l *.txt, but this is for educational purposes.

ls -l | grep "\.txt$"
Here, the output of the program ls -l is sent to the grep program, which, in turn, will print lines which match the regex “\.txt$”.

Variables

You can use variables as in any programming languages. There are no data types. A variable in bash can contain a number, a character, a string of characters.

You have no need to declare a variable, just assigning a value to its reference will create it.

Hello World! using variables

#!/bin/bash          
STR="Hello World!"
echo $STR

Line 2 creates a variable called STR and assigns the string “Hello World!” to it. Then the VALUE of this variable is retrieved by putting the ‘$’ in at the beginning. Please notice (try it!) that if you don’t use the ‘$’ sign, the output of the program will be different, and probably not what you want it to be.

A very simple backup script (little bit better)

#!/bin/bash          
OF=/var/my-backup-$(date +%Y%m%d).tgz
tar -cZf $OF /home/me/
This script introduces another thing. First of all, you should be familiarized with the variable creation and assignation on line 2. Notice the expression ‘$(date +%Y%m%d)’. If you run the script you’ll notice that it runs the command inside the parenthesis, capturing its output.
Notice that in this script, the output filename will be different every day, due to the format switch to the date command(+%Y%m%d). You can change this by specifying a different format.

examples:

echo ls

echo $(ls)

Local variables

Local variables can be created by using the keyword local.

#!/bin/bash
HELLO=Hello
function hello {
local HELLO=World
echo $HELLO
}
echo $HELLO
hello
echo $HELLO

Basic conditional example if .. then

#!/bin/bash
if [ "foo" = "foo" ]; then
echo expression evaluated as true
fi

The code to be executed if the expression within braces is true can be found after the ‘then’ word and before ‘fi’ which indicates the end of the conditionally executed code.

Basic conditional example if .. then … else

#!/bin/bash
if [ "foo" = "foo" ]; then
echo expression evaluated as true
else
echo expression evaluated as false
fi

Conditionals with variables

#!/bin/bash
T1="foo"
T2="bar"
if [ "$T1" = "$T2" ]; then
echo expression evaluated as true
else
echo expression evaluated as false
fi

Loops

  • for
  • while
(there’s another loop called until but I don’t use it so you can look it up if you’d like)
The until loop is almost equal to the while loop, except that the code is executed while the control expression evaluates to false.

The for loop is a little bit different from other programming languages. Basically, it let’s you iterate over a series of ‘words’ within a string.

The while executes a piece of code if the control expression is true, and only stops when it is false …or a explicit break is found within the executed code.

For

#!/bin/bash
for i in $( ls ); do
echo item: $i
done
On the second line, we declare i to be the variable that will take the different values contained in $( ls ).
The third line could be longer if needed, or there could be more lines before the done (4).
‘done’ (4) indicates that the code that used the value of $i has finished and $i can take a new value.
A more useful way to use the for loop would be to use it to match only certain files on the previous example

While

#!/bin/bash 
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done

Functions

As in almost any programming language, you can use functions to group pieces of code in a more logical way or practice the divine art of recursion.

Declaring a function is just a matter of writing function my_func { my_code }.

Calling a function is just like calling another program, you just write its name.

Functions ex.)

#!/bin/bash 
function quit {
exit
}
function hello {
echo Hello!
}
hello
quit
echo foo
Lines 2–4 contain the ‘quit’ function. Lines 5–7 contain the ‘hello’ function If you are not absolutely sure about what this script does, please try it!.
Notice that a functions don’t need to be declared in any specific order.
When running the script you’ll notice that first: the function ‘hello’ is called, second the ‘quit’ function, and the program never reaches line 10.

Functions with parameters

#!/bin/bash 
function quit {
exit
}
function e {
echo $1
}
e Hello
e World
quit
echo foo

Backup Directory Script:

#!/bin/bash          
SRCD="/home/"
TGTD="/var/backups/"
OF=home-$(date +%Y%m%d).tgz
tar -cZf $TGTD$OF $SRCD

File Renamer:

Bonus Commands:

Included in a gist below (so you can see them syntax highlighted..) I am also including them in text so that they might turn up as a result of google searches … I have a hunch that google’s SEO rankings don’t put much emphasis on the content of github gists.

Example

#!/usr/bin/env bash
NAME="John"
echo "Hello $NAME!"

Variables

NAME="John"
echo $NAME
echo "$NAME"
echo "${NAME}!"

String quotes

NAME="John"
echo "Hi $NAME" #=> Hi John
echo 'Hi $NAME' #=> Hi $NAME

Shell execution

echo "I'm in $(pwd)"
echo "I'm in `pwd`"
# Same

See Command substitution

Conditional execution

git commit && git push
git commit || echo "Commit failed"

Functions

{: id=’functions-example’}

get_name() {
echo "John"
}
echo "You are $(get_name)"

See: Functions

Conditionals

{: id=’conditionals-example’}

if [[ -z "$string" ]]; then
echo "String is empty"
elif [[ -n "$string" ]]; then
echo "String is not empty"
fi

See: Conditionals

Strict mode

set -euo pipefail
IFS=$'\n\t'

See: Unofficial bash strict mode

Brace expansion

echo {A,B}.js

ExpressionDescription{A,B}Same as A B{A,B}.jsSame as A.js B.js{1..5}Same as 1 2 3 4 5

See: Brace expansion

Parameter expansions

{: .-three-column}

Basics

name="John"
echo ${name}
echo ${name/J/j} #=> "john" (substitution)
echo ${name:0:2} #=> "Jo" (slicing)
echo ${name::2} #=> "Jo" (slicing)
echo ${name::-1} #=> "Joh" (slicing)
echo ${name:(-1)} #=> "n" (slicing from right)
echo ${name:(-2):1} #=> "h" (slicing from right)
echo ${food:-Cake} #=> $food or "Cake"
length=2
echo ${name:0:length} #=> "Jo"

See: Parameter expansion

STR="/path/to/foo.cpp"
echo ${STR%.cpp} # /path/to/foo
echo ${STR%.cpp}.o # /path/to/foo.o
echo ${STR%/*} # /path/to
echo ${STR##*.}     # cpp (extension)
echo ${STR##*/} # foo.cpp (basepath)
echo ${STR#*/}      # path/to/foo.cpp
echo ${STR##*/} # foo.cpp
echo ${STR/foo/bar} # /path/to/bar.cpp
STR="Hello world"
echo ${STR:6:5} # "world"
echo ${STR: -5:5} # "world"
SRC="/path/to/foo.cpp"
BASE=${SRC##*/} #=> "foo.cpp" (basepath)
DIR=${SRC%$BASE} #=> "/path/to/" (dirpath)

Substitution

CodeDescription${FOO%suffix}Remove suffix${FOO#prefix}Remove prefix------${FOO%%suffix}Remove long suffix${FOO##prefix}Remove long prefix------${FOO/from/to}Replace first match${FOO//from/to}Replace all------${FOO/%from/to}Replace suffix${FOO/#from/to}Replace prefix

Comments

# Single line comment
: '
This is a
multi line
comment
'

Substrings

ExpressionDescription${FOO:0:3}Substring (position, length)${FOO:(-3):3}Substring from the right

Length

ExpressionDescription${#FOO}Length of $FOO

Manipulation

STR="HELLO WORLD!"
echo ${STR,} #=> "hELLO WORLD!" (lowercase 1st letter)
echo ${STR,,} #=> "hello world!" (all lowercase)
STR="hello world!"
echo ${STR^} #=> "Hello world!" (uppercase 1st letter)
echo ${STR^^} #=> "HELLO WORLD!" (all uppercase)

Default values

ExpressionDescription${FOO:-val}$FOO, or val if unset (or null)${FOO:=val}Set $FOO to val if unset (or null)${FOO:+val}val if $FOO is set (and not null)${FOO:?message}Show error message and exit if $FOO is unset (or null)

Omitting the : removes the (non)nullity checks, e.g. ${FOO-val} expands to val if unset otherwise $FOO.

Loops

{: .-three-column}

Basic for loop

for i in /etc/rc.*; do
echo $i
done

C-like for loop

for ((i = 0 ; i < 100 ; i++)); do
echo $i
done

Ranges

for i in {1..5}; do
echo "Welcome $i"
done

With step size

for i in {5..50..5}; do
echo "Welcome $i"
done

Reading lines

cat file.txt | while read line; do
echo $line
done

Forever

while true; do
···
done

Functions

{: .-three-column}

Defining functions

myfunc() {
echo "hello $1"
}
# Same as above (alternate syntax)
function myfunc() {
echo "hello $1"
}
myfunc "John"

Returning values

myfunc() {
local myresult='some value'
echo $myresult
}
result="$(myfunc)"

Raising errors

myfunc() {
return 1
}
if myfunc; then
echo "success"
else
echo "failure"
fi

Arguments

ExpressionDescription$#Number of arguments$*All postional arguments (as a single word)$@All postitional arguments (as separate strings)$1First argument$_Last argument of the previous command

Note: $@ and $* must be quoted in order to perform as described. Otherwise, they do exactly the same thing (arguments as separate strings).

See Special parameters.

Conditionals

{: .-three-column}

Conditions

Note that [[ is actually a command/program that returns either 0 (true) or 1 (false). Any program that obeys the same logic (like all base utils, such as grep(1) or ping(1)) can be used as condition, see examples.

ConditionDescription[[ -z STRING ]]Empty string[[ -n STRING ]]Not empty string[[ STRING == STRING ]]Equal[[ STRING != STRING ]]Not Equal------[[ NUM -eq NUM ]]Equal[[ NUM -ne NUM ]]Not equal[[ NUM -lt NUM ]]Less than[[ NUM -le NUM ]]Less than or equal[[ NUM -gt NUM ]]Greater than[[ NUM -ge NUM ]]Greater than or equal------[[ STRING =~ STRING ]]Regexp------(( NUM < NUM ))Numeric conditions

More conditions

ConditionDescription[[ -o noclobber ]]If OPTIONNAME is enabled------[[ ! EXPR ]]Not[[ X && Y ]]And`[[ X

File conditions

ConditionDescription[[ -e FILE ]]Exists[[ -r FILE ]]Readable[[ -h FILE ]]Symlink[[ -d FILE ]]Directory[[ -w FILE ]]Writable[[ -s FILE ]]Size is > 0 bytes[[ -f FILE ]]File[[ -x FILE ]]Executable------[[ FILE1 -nt FILE2 ]]1 is more recent than 2[[ FILE1 -ot FILE2 ]]2 is more recent than 1[[ FILE1 -ef FILE2 ]]Same files

Example

# String
if [[ -z "$string" ]]; then
echo "String is empty"
elif [[ -n "$string" ]]; then
echo "String is not empty"
else
echo "This never happens"
fi
# Combinations
if [[ X && Y ]]; then
...
fi
# Equal
if [[ "$A" == "$B" ]]
# Regex
if [[ "A" =~ . ]]
if (( $a < $b )); then
echo "$a is smaller than $b"
fi
if [[ -e "file.txt" ]]; then
echo "file exists"
fi

Arrays

Defining arrays

Fruits=('Apple' 'Banana' 'Orange')
Fruits[0]="Apple"
Fruits[1]="Banana"
Fruits[2]="Orange"

Working with arrays

echo ${Fruits[0]}           # Element #0
echo ${Fruits[-1]} # Last element
echo ${Fruits[@]} # All elements, space-separated
echo ${#Fruits[@]} # Number of elements
echo ${#Fruits} # String length of the 1st element
echo ${#Fruits[3]} # String length of the Nth element
echo ${Fruits[@]:3:2} # Range (from position 3, length 2)
echo ${!Fruits[@]} # Keys of all elements, space-separated

Operations

Fruits=("${Fruits[@]}" "Watermelon")    # Push
Fruits+=('Watermelon') # Also Push
Fruits=( ${Fruits[@]/Ap*/} ) # Remove by regex match
unset Fruits[2] # Remove one item
Fruits=("${Fruits[@]}") # Duplicate
Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
lines=(`cat "logfile"`) # Read from file

Iteration

for i in "${arrayName[@]}"; do
echo $i
done

Dictionaries

{: .-three-column}

Defining

declare -A sounds
sounds[dog]="bark"
sounds[cow]="moo"
sounds[bird]="tweet"
sounds[wolf]="howl"

Declares sound as a Dictionary object (aka associative array).

Working with dictionaries

echo ${sounds[dog]} # Dog's sound
echo ${sounds[@]} # All values
echo ${!sounds[@]} # All keys
echo ${#sounds[@]} # Number of elements
unset sounds[dog] # Delete dog

Iteration

Iterate over values

for val in "${sounds[@]}"; do
echo $val
done

Iterate over keys

for key in "${!sounds[@]}"; do
echo $key
done

Options

Options

set -o noclobber  # Avoid overlay files (echo "hi" > foo)
set -o errexit # Used to exit upon error, avoiding cascading errors
set -o pipefail # Unveils hidden failures
set -o nounset # Exposes unset variables

Glob options

shopt -s nullglob    # Non-matching globs are removed  ('*.foo' => '')
shopt -s failglob # Non-matching globs throw errors
shopt -s nocaseglob # Case insensitive globs
shopt -s dotglob # Wildcards match dotfiles ("*.sh" => ".foo.sh")
shopt -s globstar # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb')

Set GLOBIGNORE as a colon-separated list of patterns to be removed from glob matches.

History

Commands

CommandDescriptionhistoryShow historyshopt -s histverifyDon't execute expanded result immediately

Expansions

ExpressionDescription!$Expand last parameter of most recent command!*Expand all parameters of most recent command!-nExpand nth most recent command!nExpand nth command in history!<command>Expand most recent invocation of command <command>

Operations

CodeDescription!!Execute last command again!!:s/<FROM>/<TO>/Replace first occurrence of <FROM> to <TO> in most recent command!!:gs/<FROM>/<TO>/Replace all occurrences of <FROM> to <TO> in most recent command!$:tExpand only basename from last parameter of most recent command!$:hExpand only directory from last parameter of most recent command

!! and !$ can be replaced with any valid expansion.

Slices

CodeDescription!!:nExpand only nth token from most recent command (command is 0; first argument is 1)!^Expand first argument from most recent command!$Expand last token from most recent command!!:n-mExpand range of tokens from most recent command!!:n-$Expand nth token to last from most recent command

!! can be replaced with any valid expansion i.e. !cat!-2!42, etc.

Miscellaneous

Numeric calculations

$((a + 200))      # Add 200 to $a
$(($RANDOM%200))  # Random number 0..199

Subshells

(cd somedir; echo "I'm now in $PWD")
pwd # still in first directory

Redirection

python hello.py > output.txt   # stdout to (file)
python hello.py >> output.txt # stdout to (file), append
python hello.py 2> error.log # stderr to (file)
python hello.py 2>&1 # stderr to stdout
python hello.py 2>/dev/null # stderr to (null)
python hello.py &>/dev/null # stdout and stderr to (null)
python hello.py < foo.txt      # feed foo.txt to stdin for python

Inspecting commands

command -V cd
#=> "cd is a function/alias/whatever"

Trap errors

trap 'echo Error at about $LINENO' ERR

or

traperr() {
echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
}
set -o errtrace
trap traperr ERR

Case/switch

case "$1" in
start | up)
vagrant up
;;
  *)
echo "Usage: $0 {start|stop|ssh}"
;;
esac

Source relative

source "${0%/*}/../share/foo.sh"

printf

printf "Hello %s, I'm %s" Sven Olga
#=> "Hello Sven, I'm Olga
printf "1 + 1 = %d" 2
#=> "1 + 1 = 2"
printf "This is how you print a float: %f" 2
#=> "This is how you print a float: 2.000000"

Directory of script

DIR="${0%/*}"

Getting options

while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
-V | --version )
echo $version
exit
;;
-s | --string )
shift; string=$1
;;
-f | --flag )
flag=1
;;
esac; shift; done
if [[ "$1" == '--' ]]; then shift; fi

Heredoc

cat <<END
hello world
END

Reading input

echo -n "Proceed? [y/n]: "
read ans
echo $ans
read -n 1 ans    # Just one character

Special variables

ExpressionDescription$?Exit status of last task$!PID of last background task$$PID of shell$0Filename of the shell script

See Special parameters.

Go to previous directory

pwd # /home/user/foo
cd bar/
pwd # /home/user/foo/bar
cd -
pwd # /home/user/foo

Check for command’s result

if ping -c 1 google.com; then
echo "It appears you have a working internet connection"
fi

Grep check

if grep -q 'foo' ~/.bash_history; then
echo "You appear to have typed 'foo' in the past"
fi

Also see

{: .-one-column}

Comments

Popular posts from this blog

These Are The Bash Shell Commands That Stand Between Me And Insanity

These Are The Bash Shell Commands That Stand Between Me And Insanity These Are The Bash Shell Commands That Stand Between Me And Insanity I will not profess to be a bash shell wizard… but I have managed to scour some pretty helpful little scripts from Stack Overflow and modify… These Are The Bash Shell Commands That Stand Between Me And Insanity I will not profess to be a bash shell wizard… but I have managed to scour some pretty helpful little scripts from Stack Overflow and modify them to suit my needs. All of these commands are for Ubuntu/WSL … some may work in other scenarios but I can’t guarantee it. ...
Deploy-React-App-To-Heroku-Using-Postgres Deploy React App To Heroku Using Postgres & Express Heroku is an web application that makes deploying applications easy for a beginner. Deploy React App To Heroku Using Postgres & Express Heroku is an web application that makes deploying applications easy for a beginner. Before you begin deploying, make sure to remove any console.log ’s or debugger ’s in any production code. You can search your entire project folder if you are using them anywhere. You will set up Heroku to run on a production, not development, version of your application. When a Node.js application like yours is pushed up to Heroku, it is identified as a Node.js application because of the package.json file. It runs npm install automatically. Then, if there is a heroku-postbui...

Data Structures Resources

Data Structures & Algorithms Resource List Part 1 Data Structures & Algorithms Resource List Part 1 Guess the author of the following quotes: Data Structures & Algorithms Resource List Part 1 Guess the author of the following quotes: Talk is cheap. Show me the code. Software is like sex: it’s better when it’s free. Microsoft isn’t evil, they just make really crappy operating systems. Update: Here’s some more: ...