Bash

= Basics = Source: ss64.com,learnxinyminutes.com


 * POSIX
 * POSIX stands for Portable Operating System Interface, and is an IEEE standard designed to facilitate application portability.
 * POSIX is an attempt by a consortium of vendors to create a single standard version of UNIX.
 * If they are successful, it will make it easier to port applications between hardware platforms.


 * SH
 * sh (or the Shell Command Language) is a programming language described by the POSIX standard.
 * It has many implementations (ksh88, dash, ...). bash can also be considered an implementation of sh (see below).
 * Because sh is a specification, not an implementation, /bin/sh is a symlink (or a hard link) to an actual implementation on most POSIX systems.


 * BASH
 * bash started as an sh-compatible implementation (although it predates the POSIX standard by a few years), but as time passed it has acquired many extensions.
 * Many of these extensions may change the behavior of valid POSIX shell scripts, so by itself bash is not a valid POSIX shell.
 * Rather, it is a dialect of the POSIX shell language.
 * bash supports a --posix switch, which makes it more POSIX-compliant.
 * It also tries to mimic POSIX if invoked as sh.

Variables
$1, $2, $3   are the positional parameters. "$@"         is an array-like construct of all positional parameters, {$1, $2, $3 ...}. "$*"         is the IFS expansion of all positional parameters, $1 $2 $3 .... $#            is the number of positional parameters. $-           current options set for the shell. $$           pid of the current shell (not subshell). $_           most recent parameter (or the abs path of the command to start the current shell immediately after startup). $IFS         is the (input) field separator. $?           is the most recent foreground pipeline exit status. $!           is the PID of the most recent background command. $0           is the name of the shell or shell script.
 * Declaring

dir="/data/.folder/" path="/home/system/Desktop/pending_files.txt" tree $dir | wc -l >> $path
 * Using Variables in Bash:

Variable="Some string"
 * Correct way to declare variable

Variable = "Some string" ==>  Bash will decide that Variable is a command it must execute Variable= 'Some string'  ==> Bash will decide that 'Some string' is a command it must execute
 * Wrong way to declare Varibales:

echo ${text:0:10}
 * Print first 10 characters:

Builtin variables
echo "Last program's return value: $?" echo "Script's PID: $$" echo "Number of arguments passed to script: $#" echo "All arguments passed to script: $@" echo "Script's arguments separated into different variables: $1 $2..."

Array
array0=(one two three four five six) echo $array0 # => "one" echo ${array0[0]} # => "one" echo ${array0[@]} # => "one two three four five six" echo ${#array0[@]} # => "6" echo ${#array0[2]} # => "5" echo ${array0[@]:3:2} # => "four five"
 * Declare an array with 6 elements
 * Print first element
 * Print first element
 * Print all elements
 * Print number of elements
 * Print number of characters in third element
 * Print 2 elements starting from forth
 * Print all elements. Each of them on new line.

Brace Expansion
echo {1..10} echo {a..z}

for number in {2..99..2} do   echo $number done
 * Display Even Numbers

2 is the low end. 99 is the high end. 2 is the step after each iteration.

Builtin variables
Both commands are quivalent echo "I'm in $(pwd)"                 # execs `pwd` and interpolates output echo "I'm in $PWD"                   # interpolates the built in `$PWD` variable

Reading Input
echo "What's your name?" read Name                            # Note we didn't declare a variable echo Hello, $Name!

Expressions
echo $(( 10 + 5 ))


 * Let


 * Expr


 * Double Parentheses

Read Files
Contents=$(cat file.txt) echo "START OF FILE\n$Contents\nEND OF FILE"

Use subshells to work across directories
(echo "First, I'm here: $PWD") && (cd someDir; echo "Then, I'm here: $PWD") pwd                 # still in first directory

Loops

 * General Syntax:


 * Traditional for loop way:


 * Act on files:


 * Output from a command


 * While loop:

Functions

 * Declaration:

foo arg1 arg2


 * Another way:

bar

Misc
Trap executes a command whenever script receives a signal (here any of the three listed signals): trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM

Sudo is used to run commands as the superuser: NAME1=$(whoami) NAME2=$(sudo whoami) echo "Was $NAME1, then became more powerful $NAME2"

=Bash Scripts=

One Liners
find $dir -type f | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
 * Script to find file extensions

find. -name "*.webp" -exec dwebp {} -o {}.png \; find. -name "*.webp" -delete
 * Convert files with name "webp" file to Png:

mkdir ep{1..16} mkdir -p sa{0..10}/{1,2,3,4} mkdir -p sa{0..10}/{1..4}
 * Create Multiple Directories with single command:

wget https://imagedump.com/i/1/234{1..100}.jpg wget -i list.txt
 * Download multiple files at once:

echo -n "Count: " >> files.txt find. | wc -l >> files.txt
 * Saving text use echo to continue on same line:

IFS=$'\n'; for i in `find. -type d`; do echo $i; ls $i|wc -l; done; unset IFS
 * Word count for directories

IFS=$'\n'; for i in `find. -name "*.mp4"`; do mediainfo $i | grep "Duration" | awk 'NR == 1 {print i $3$4,$5$6 $7$8}'; done; unset IFS
 * Find Lengths of multiple video files:

Small Scripts
for i in `find /home/test/ -type f -name '*.tar.gz'`; do echo $i; j=$(echo $i | cut -d '.' -f1); mkdir $j; tar xvzf $i -C $j; done
 * Extract multiple tar files to sub-directories:

for i in `find $(pwd) -type f`; do echo $i; j=$(echo $i | cut -d '.' -f1); echo $j; tar cvzf $"$j.tar.gz" $i; done
 * Tar Multiple files at once:


 * Checking Internet connectivity
 * 1) !/bin/bash

if ping -c 1 -W 2 google.com > /dev/null; then echo "Up" else echo "Down" fi


 * Mplayer Play Live Gurbani from 8 to 10AM

trickle -d 20 -u 15 mplayer mms://sgpc.net/live & sleep 2h kill $!
 * 1) !/bin/bash

Cron Entry: 0 8 * * * ./mplayer.sh


 * Download Newspaper front page

URL: http://newspaper.ajitjalandhar.com/newspages/20130226/20130226_1_1.jpg

 cd ~/Desktop D=$(date +"%Y%m%d") FILE="$D"_1_1.jpg if [ -f $FILE ]; then exit else wget "http://newspaper.ajitjalandhar.com/newspages/"$D"/"$D"_1_1.jpg" && notify-send -i /data/Softwares/Wallpapers/icons/ajit.png -t 50 "Ajit Jalandhar" "is saved at your desktop" fi
 * 1) !/bin/bash

Cron Entry to download daily: 0 7-11 * * * ./ajit.sh

PATH=/usr/games:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 * Eye strain preventer:
 * 1) !/bin/bash

while true; do sleep 1200; sm --foreground=white --background=black Look at an Object 20 feet away for 20 Seconds & sleep 20s && killall sm; done

Add following line to startup programs: /home/aman/Scripts/eyesaver.sh >/dev/null 2>&1


 * Extension Doctor

for f in *.{jpg,JPG,png,PNG,jpeg,JPEG,webp}; do    type=$( file "$f" | grep -oP '\w+(?= image)' ) case $type in         PNG)  newext=png ;;         JPEG) newext=jpg ;; P) newext=webp ;;       *)    echo "??? what is this: $f"; continue ;; esac ext=${f##*.}  # remove everything up to and including the last dot if $ext != $newext ; then # remove "echo" if it's working correctly echo mv "$f" "${f%.*}.$newext" fi done

Big Scripts

 * Directory Stats


 * References
 * Reference Guide: gnu.org
 * Check Scripts for errors: shellcheck.net