Capital City Christian Church

Bash Notes and Examples



Bash Scripting

This page is a concise group of examples of the most commonly used bash coding techniques used at CapCity

The Basics

Define a variable
VARNAME="value"

To use a variable refer to it as ${VARNAME}

Working with external commands

Load the output of a command into a variable. Use backtics

OUTPUT=`ping 127.0.0.1`
OUTPUT=`command and parms here`
Conditional branching

Test for conditions. Use man test for list of supported conditions.

if [condition]
then
    cmd1
    cmd2
    cmd3
elif
then
    cmd4
    cmd5
    cmd6
fi
Command line arguments

$0 contains the script name, and $1 through $9 represent the command line positional arguments where keyboard input uses the -p arg.

read -p "prompt" VARIABLE
read -p "Enter your choice: " CHOICE
Exit status

Exit Status. Use 'man exit status' for details.

echo "$?" will display the error code of the last run command.

Logical operators Functions

The basic syntax is

function function-name() {
    #More Code
}

To call a function, just use it's name.

function hello() {
    echo "Hi there!"
    now
}

function now() {
    echo "It is ($date + %r)"
}

hello()
Substrings

where 12 is the offset (zero-based) and 5 is the length

b=${a:12:5}
INPUT='someletters_12345_moreleters.ext'
SUBSTRING=$(echo $INPUT| cut -d'_' -f 2)
echo $SUBSTRING


Another solution to extract exactly a part of a variable:
number="${filename:offset:length}"

$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]+"
12345
or better
$ echo "someletters_12345_moreleters.ext" | grep -Eo "[[:digit:]]{5}"
12345


STR="0123Linux9"
echo ${STR:4:5}
Linux


#!/bin/bash
# Declare a variable
name="John Doe"
# Extract the substring "John"
firstName=${name:0:4}
# Print the substring "John"
echo "First name is: ${firstName}"
Looping through an array
#! /bin/bash
servers=( 192.xxx.xxx.2 192.xxx.xxx.3
          192.xxx.xxx.4 192.xxx.xxx.5
          192.xxx.xxx.6 192.xxx.xxx.7
)
for server in "${servers[@]}" ; do
    echo "$server"
done

Looping through variables;

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"
for ((i=1; i<7; i++))
do
    servervar="SERVER$i"
    echo "${!servervar}"
done

Looping through the output lines of a command

ls | while IFS= read -r line ; do
   echo "$line"
done


while IFS= read -r line ; do
   echo "$line"
done < file.txt


Loop through a file and cutout a substring and print it
#!/bin/bash
for user in $(cut -d: -f1 /etc/passwd); do
    echo "User: $user"
done

Loop through the lines of a variable containing the output of a command

LIST=`ping -c3 127.0.0.1`
while IFS= read -r line; do
    echo "... $line ..."

From each line in data.csv, we extract column entries to build an INSERT INTO statement, which we can then pipe to the mysql command:

$ cat mysql_insert.sh
#!/usr/bin/env bash
IFS=','
cat data.csv | while read id first_name last_name department; do
    echo "INSERT INTO EmployeeDB.employees
    (ID,FIRST_NAME,LAST_NAME,DEPARTMENT)
    VALUES ('$id','$first_name','$last_name','$department');"
done | mysql --user=sysadmin --password=mypassword
Querying MySQL
#! /bin/bash
user="jonnDoe"
dbname="customers"
password="VerySecret"

mysql -u $user -D $dbname -p $password -e "select Col1 from Table1 where
     Condition;" > /home/$user/queries/Col1Table1Cond
mysql -u $user -D $dbname -p $password -e "select Col5 from Table2 where
     Condition;" > /home/$user/queries/Col5Table2Cond

Executing a MySQL server command;

#!/bin/sh
# mysql_uptime2.sh - report server uptime

mysql -e STATUS | grep "^Uptime"

#!/bin/sh
# mysql_uptime3.sh - report server uptime

echo STATUS | mysql | grep "^Uptime"

mysql -u hoststud -p ****** -e 'show databases'

mysql -u [username] -p [password] -e '[mysql commands]' > output.txt

#!/bin/bash
mysql -u [username] -p [password] << EOF
[mysql commands]
[mysql commands]
[mysql commands]
EOF
$ mysql --user=sysadmin --password=mypassword \
    -e "INSERT INTO EmployeeDB.employees
    (ID,FIRST_NAME,LAST_NAME,DEPARTMENT)
    VALUES ('4','Kim','Zed','Marketing');"
$ mysql --user=sysadmin --password=mypassword \
    -e "INSERT INTO EmployeeDB.employees
    (ID,FIRST_NAME,LAST_NAME,DEPARTMENT)
    VALUES ('5','Val','Ash','R&D');"


$ echo "INSERT INTO EmployeeDB.employees
(ID,FIRST_NAME,LAST_NAME,DEPARTMENT)
    VALUES ('4','Kim','Zed','Marketing');" |
    mysql --user=sysadmin --password=mypassword
$ echo "INSERT INTO EmployeeDB.employees
(ID,FIRST_NAME,LAST_NAME,DEPARTMENT)
    VALUES ('5','Val','Ash','R&D');" |
    mysql --user=sysadmin --password=mypassword
$ mysql --user=sysadmin --password=mypassword -e "SELECT *
    FROM EmployeeDB.employees;"


$ chmod +x mysql_insert.sh
$ ./mysql_insert.sh
$ mysql --user=sysadmin --password=mypassword -e "SELECT *
    FROM EmployeeDB.employees;"

mysql --user=sysadmin --password=mypassword -e "SELECT *
    FROM EmployeeDB.employees;"


#!/bin/sh

# call mysql client from shell script without
# passing credentials on command line

# This demonstrates small single queries using
# the -e parameter.   Credentials and connection
# info are sent through standard input.

# david . bennett @ percona . com - 12/27/2016

mysql_user=root
mysql_password=password
mysql_host=127.0.0.1
mysql_port=3306
mysql_database=test

mysql_exec() {
  local query="$1"
  local opts="$2"
  mysql_exec_result=$(
    printf "%s\n" \
      "[client]" \
      "user=${mysql_user}" \
      "password=${mysql_password}" \
      "host=${mysql_host}" \
      "port=${mysql_port}" \
      "database=${mysql_database}" \
      | HOME="/sys" mysql --defaults-file=/dev/stdin
          "${opts}" -e "${query}"
  )
}

mysql_exec "select 'Hello World' as Message"
echo "${mysql_exec_result}"
Querying MySQL and Looping through results
#!/bin/bash
set -f        # disable globbing
IFS=$'\n'     # set field separator to NL (only)
arr=($(sudo mysql -u root -h localhost -e
    "USE mydb;SELECT * FROM users"))

for i in "${arr[@]}"
do
   echo "$i"
done
Reading a CSV file
#!/bin/bash
while read line
do
   echo "Record is : $line"
done < input.csv



#! /bin/bash
while IFS="," read -r rec_column1 rec_column2 rec_column3 rec_column4
do
  echo "Displaying Record-$rec_column1"
  echo "Quantity: $rec_column2"
  echo "Price: $rec_column3"
  echo "Value: $rec_column4"
  echo ""
done < (tail -n +2 input.csv)
Formatting OutPut
Options     Definition
-n  Do not print the trailing newline
-E  Disable interpretation of back-slash escaped characters
-e  Enable interpretation of backslash escapes
\a  Alert
\b  Backspace
\c  Suppress trailing newline
\e  Escape
\f  Form feed
\\  backslash
\n  New line
\r  Carriage return
\t  Horizontal tab
\v  Vertical tab


According to the Linux documentation, the following is the
syntax for echo command.

    echo [option(s)][string(s)]

Now, we shall see the different ways in which we can output
the text on the terminal.

Next, review this page; https://ioflood.com/blog/bash-printf/
#!/bin/bash
Echo "Test’

Chmod 755 script.sh
./script.sh


Be sure to code for the shell you are using. On my Dell it is
    "SHELL=/usr/bin/zsh" or "/usr/bin/bash".

variable-name=value
# All upper cast names
To reference, proceed with dollar sign. IE "$TOTAL", or "$SUM"
Uploading Files Via Bash FTP Script
Uploading Files Via Bash FTP Script

Use this to develop a shell script that will upload the updated
files from the local client to the FTP://CapCityTech.info FTP
incoming site. Then manually use Cpanel to move them into
place on the website.

---{Original Script}---

#!/bin/bash
# https://www.geeksforgeeks.org/shell-script-to-put-file-in-a-ftp-server/
# The 3 variables below store server and login details
HOST="192.168.0.104"
USER="user1"
PASSWORD="1234"

# $1 is the first argument to the script
# We are using it as upload directory path
# If it is '.', file is uploaded to current directory.
DESTINATION=$1

# Rest of the arguments are a list of files to be uploaded.
# ${@:2} is an array of arguments without first one.
ALL_FILES="${@:2}"

# FTP login and upload is explained in paragraph below
ftp -inv $HOST <<EOF
user $USER $PASSWORD
cd $DESTINATION
mput $ALL_FILES
bye
EOF

---[Another Example]---

#!/bin/bash
# https://linuxconfig.org/example-of-simple-bash-script-client
ftp_site=127.0.0.1
username=ftpuser
passwd=pass

PS3='Select a destination directory: '

# bash select
select path in "." "/test" "public_html/myblog/" "backup/images/"
do
ftp -n $ftp_site<<EOF
quote USER $username
quote PASS $passwd
binary
cd $path
put $1
quit
EOF
break
done

Resources Some Updated Thinking

As long as I have been with CapCity one of my guidelines was to avoid introducing anything that would be difficult to support once I was gone. So, I have kept from developing any web applications since they would be full-stack and the spectrum of tech already used would be very difficult to maintain.

But I am coming to the conclusion we need some sort of scripting for automation, routine tasks, and administration.

Having considered which scripting language meets the following criteria, I decided on Bash shell scripts.

well established widely supported and used probability of longevity ease of learning, using, finding examples, and support power, flexibility, extensible

Bash is supported on Linux and iOS (https://www.macinstruct.com/tutorials/how-to-make-a-bash-script-executable-on-a-mac/). We currently only have a few Windows hosts and all IT work is assumed to be done on Linux or iOS.

Ideas for scripts; gather and report server, switch, and other logs check the system date of switches query mysql and produce common reports update mysql with dhcp leases and arp-scan run nmap and produce sql queries report nas status

The scripts will be very commented explaining what is happening. A tech in the future should be able to use these for automation, and examine them to alter them.

Tips fir programming; save the files you are work*ng frequently when you make a major change to a script, first make a copy of it with the current date so that if your changes do not go well, and you find out about it a week later. get to know your text/programming program real well develop a script that list all of the scripts and their use, and make it searchable use echo to print the line as a reference to verify how far you got. The $LINENO variable always holds the number of the current line in a bash script. Include lines that print status, variable values, number of current loop print stuff to a log file to log what was done. Print the current date and time