Difference between revisions of "BASH"

From RHS Wiki
Jump to navigation Jump to search
Tag: visualeditor
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
'''BASH Scripting'''
 
'''BASH Scripting'''
== Hello World ==
+
==Hello World==
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 7: Line 7:
 
</source>
 
</source>
  
== Variables ==
+
==Variables==
=== Local Variables ===
+
===Local Variables===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 20: Line 20:
 
echo $HELLO
 
echo $HELLO
 
</source>
 
</source>
=== Boolean ===
+
===Boolean===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 30: Line 30:
 
</source>
 
</source>
  
== Print ==
+
==Print==
=== Print to stderr ===
+
===Print to stderr===
 
  f_pinta_error () {
 
  f_pinta_error () {
 
v_TIMESTAMP=$(date +${v_FORMATO_TIMESTAMP})
 
v_TIMESTAMP=$(date +${v_FORMATO_TIMESTAMP})
Line 37: Line 37:
 
  }
 
  }
  
== Strings ==
+
==Strings==
  
== Loops ==
+
==Loops==
=== While ===
+
===While===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 50: Line 50:
 
</source>
 
</source>
  
=== For ===
+
===For===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 63: Line 63:
 
</source>
 
</source>
  
=== C-like for ===
+
===C-like for===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 71: Line 71:
 
done
 
done
 
</source>
 
</source>
=== Loop files ===
+
===Loop files===
 
  while read p; do echo $p|underscore pretty ; done < /tenkaichi/boo/done/krilin_2017-12-21T12:45:29.544997.jl.boo
 
  while read p; do echo $p|underscore pretty ; done < /tenkaichi/boo/done/krilin_2017-12-21T12:45:29.544997.jl.boo
  
=== Loop files in directory ===
+
===Loop files in directory===
 
With paths:
 
With paths:
<source lang="bash">for filename in /usr/bin/*; do echo $filename; done</source>
+
<source lang="bash">for filename in /usr/bin/*; do echo $filename; done</source>
 
Without path:
 
Without path:
<source lang="bash">for i in $(ls /usr/bin);do echo $i; done;</source>
+
<source lang="bash">for i in $(ls /usr/bin);do echo $i; done;</source>
  
=== Until ===
+
===Until===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 90: Line 90:
 
</source>
 
</source>
  
== Conditional ==
+
==Conditional==
=== if ===
+
===if===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 103: Line 103:
 
</source>
 
</source>
  
=== case ===
+
===case===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 138: Line 138:
 
</source>
 
</source>
  
== User Input ==
+
==User Input==
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 150: Line 150:
 
done
 
done
 
</source>
 
</source>
=== Password prompt ===
+
===Password prompt===
 
<source lang="bash">
 
<source lang="bash">
 
read -s -p "Password: " PASSWORD
 
read -s -p "Password: " PASSWORD
 
</source>
 
</source>
  
== Arrays ==
+
==Arrays==
 
<source lang="bash">
 
<source lang="bash">
 
ARRAY=(one two three)
 
ARRAY=(one two three)
Line 174: Line 174:
 
</source>
 
</source>
  
== Functions ==
+
==Functions==
 
<source lang="bash">
 
<source lang="bash">
 
function quit {
 
function quit {
Line 192: Line 192:
 
fun1 || fun2 will only run fun2 if fun1 returns a 0 value<br />
 
fun1 || fun2 will only run fun2 if fun1 returns a 0 value<br />
  
== Redirections ==
+
==Redirections==
=== stdout 2 file ===
+
===stdout 2 file===
 
  ls -l > ls-l.txt
 
  ls -l > ls-l.txt
=== stderr 2 file ===
+
===stderr 2 file===
 
  grep da * 2> grep-errors.txt
 
  grep da * 2> grep-errors.txt
=== stdout 2 stderr ===
+
===stdout 2 stderr===
 
  grep da * 1>&2
 
  grep da * 1>&2
=== stderr 2 stdout ===
+
===stderr 2 stdout===
 
  grep * 2>&1
 
  grep * 2>&1
=== stderr and stdout 2 file ===
+
===stderr and stdout 2 file===
 
  rm -f $(find / -name core) &> /dev/null
 
  rm -f $(find / -name core) &> /dev/null
== extras ==
+
==Extras==
=== Ping IP range ===
+
 
<source lang="bash">#!/bin/bash
+
===Killswitch When ssh user logs in===
 +
<syntaxhighlight lang="bash">
 +
#!/bin/bash
 +
ME=10.0.253.131
 +
 
 +
while true; do
 +
    OTHER=$( who | grep -v tmux | grep -v ${ME} )
 +
    if [ -z "${OTHER}" ]; then
 +
        echo "No one"
 +
    else
 +
        tmux kill-session -t test
 +
    fi
 +
    sleep 5
 +
done
 +
</syntaxhighlight><br />
 +
===Set files and folder permissions===
 +
<syntaxhighlight lang="bash">
 +
#!/bin/sh
 +
# syntax: setperm.s destdir
 +
#
 +
 
 +
destdir=/var/www/rrahome
 +
 
 +
dirmode=0770
 +
filemode=0660
 +
 
 +
find $destdir -type f -exec chmod ${filemode} {} \;
 +
find $destdir -type d -exec chmod ${dirmode} {} \;
 +
</syntaxhighlight>
 +
 
 +
===Backup Hard Drive===
 +
<source lang="bash">#!/bin/bash
 +
USAGE="./$(basename ${0}) UUID output_filename"
 +
BACKUP_ROOT=/mnt/backup
 +
 
 +
if [ -z "${1}" ]; then
 +
    echo ${USAGE}
 +
    exit
 +
fi
 +
if [ -z "${2}" ]; then
 +
    echo ${USAGE}
 +
    exit
 +
fi
 +
 
 +
HD=$(blkid | grep $1 | awk -F : '{print $1}')
 +
ISO=${BACKUP_ROOT}/$(hostname)/$(date '+%Y/%m')/$2.iso
 +
 
 +
dd if=${HD} of=${ISO} bs=1M</source>
 +
 
 +
===Extract date from string===
 +
<syntaxhighlight lang="bash">
 +
#!/bin/bash
 +
DATE=$( echo ${FILE} | grep -Eo '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}' )
 +
</syntaxhighlight>
 +
 
 +
===Ping IP range===
 +
<source lang="bash">#!/bin/bash
 
# cat ping_result.txt | grep ttl | awk '{print $4}' | sed s/:/''/g| sort | uniq
 
# cat ping_result.txt | grep ttl | awk '{print $4}' | sed s/:/''/g| sort | uniq
 
BASE=192.168.0.
 
BASE=192.168.0.
Line 211: Line 267:
 
     ping -c 3 ${BASE}$i >> ping_result.txt
 
     ping -c 3 ${BASE}$i >> ping_result.txt
 
done</source>
 
done</source>
=== Check if a package is installed ===
+
===Check if a package is installed===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/sh
 
#!/bin/sh
Line 220: Line 276:
 
debInst terminator
 
debInst terminator
 
</source>
 
</source>
=== Check if a file exists ===
+
===Check if a file exists===
 
<source lang="bash">
 
<source lang="bash">
 
if [ -f $FILE1 ]
 
if [ -f $FILE1 ]
Line 232: Line 288:
 
</source>
 
</source>
  
=== Check if directory exists ===
+
===Check if directory exists===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 249: Line 305:
 
</source>
 
</source>
  
=== Check user ===
+
===Check user===
<source lang="bash">
+
<syntaxhighlight lang="bash">
 +
#!/bin/bash
 +
if [ "$EUID" -ne 0 ]
 +
  then echo "Please run as root"
 +
  exit
 +
fi
 +
</syntaxhighlight><source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
 
user=$(whoami)
 
user=$(whoami)
Line 262: Line 324:
 
fi
 
fi
 
</source>
 
</source>
=== Execute localScript on remote server ===
+
===Execute localScript on remote server===
 
  <nowiki>ssh [user]@[server] 'bash -s' < [local_script]</nowiki>
 
  <nowiki>ssh [user]@[server] 'bash -s' < [local_script]</nowiki>
  
=== Remove directorys ===
+
===Remove directorys===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/sh
 
#!/bin/sh
Line 285: Line 347:
 
~/myfolder3/$1/thisisafolder
 
~/myfolder3/$1/thisisafolder
 
EOF
 
EOF
</source>
+
</source><br />
=== Check if variable is set ===
+
===Check if variable is set===
 
  if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi
 
  if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi
=== Check command success ===
+
===Check command success===
  
<source lang="bash">#!/bin/bash
+
<source lang="bash">#!/bin/bash
 
###########################################
 
###########################################
 
#          Pull latest code &            #
 
#          Pull latest code &            #
Line 330: Line 392:
 
</source>
 
</source>
  
=== Ubuntu proxy setup ===
+
===Ubuntu proxy setup===
 
<source lang="bash">
 
<source lang="bash">
 
#! /bin/bash
 
#! /bin/bash
Line 357: Line 419:
 
</source>
 
</source>
  
=== Git check version ===
+
===Git check version===
<source lang="bash">#!/bin/bash
+
<source lang="bash">#!/bin/bash
  
 
function set_upstream() {
 
function set_upstream() {
Line 397: Line 459:
 
}
 
}
 
check_latest_version</source>
 
check_latest_version</source>
=== Git check for updates and prompt to update ===
+
===Git check for updates and prompt to update===
 
<source lang="bash">
 
<source lang="bash">
 
#!/bin/bash
 
#!/bin/bash
Line 439: Line 501:
 
</source>
 
</source>
  
=== Logging ===
+
===Logging===
  
  
 
For logging, you can wrap sections of your script in curly braces and redirect the stdout to a log file:
 
For logging, you can wrap sections of your script in curly braces and redirect the stdout to a log file:
<source lang=bash>
+
<source lang="bash">
 
{
 
{
 
     script_command_1
 
     script_command_1
Line 451: Line 513:
 
</source>
 
</source>
  
=== Links ===
+
===Links===
 
[http://tldp.org/LDP/abs/html/ Advanced Bash-Scripting Guide]
 
[http://tldp.org/LDP/abs/html/ Advanced Bash-Scripting Guide]

Latest revision as of 14:19, 13 April 2021

BASH Scripting

Hello World

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

Variables

Local Variables

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

Boolean

#!/bin/bash
the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
    echo 'Be careful not to fall off!'
fi

Print

Print to stderr

f_pinta_error () {

v_TIMESTAMP=$(date +${v_FORMATO_TIMESTAMP}) >&2 echo "${v_TIMESTAMP} $1"

}

Strings

Loops

While

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

For

#!/bin/bash
for i in $( ls ); do
    echo item: $i
done

Example: git pull from all repositories in a pwd

for i in $( ls ); do cd $i; git pull; cd ..; done

C-like for

#!/bin/bash
for i in `seq 1 10`;
do
    echo $i
done

Loop files

while read p; do echo $p|underscore pretty ; done < /tenkaichi/boo/done/krilin_2017-12-21T12:45:29.544997.jl.boo

Loop files in directory

With paths:

for filename in /usr/bin/*; do echo $filename; done

Without path:

for i in $(ls /usr/bin);do echo $i; done;

Until

#!/bin/bash
COUNTER=20
until [ $COUNTER -lt 10 ]; do
    echo COUNTER $COUNTER
    let COUNTER-=1
done

Conditional

if

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

case

#!/bin/bash
case $yn in
    [YySs]* ) adduser $user; break;;
    [Nn]* ) echo no se creo usuario $user; break;;
    * ) echo "Elije y/n";;
esac

#!/bin/bash
# naclient <login|logout|status|guistatus> [-profile <profile name>] [ -user <user-name>] [-password  <password>] 


function start_vpn(){
    naclient login -profile Multi-OS  -user xe54512 -password  *******
}


function stop_vpn(){
    naclient logout
}

function status_vpn(){
    naclient status
}

case $1 in
    start ) start_vpn;;
    stop ) stop_vpn;;
    status ) status_vpn;;
    * ) echo "Unknown command";;
esac

User Input

#!/bin/bash
while true; do
    read -p "Do you wish to install this program?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

Password prompt

read -s -p "Password: " PASSWORD

Arrays

ARRAY=(one two three)

echo ${ARRAY[*]}
one two three

echo $ARRAY[*]
one[*]

echo ${ARRAY[2]}
three

ARRAY[3]=four

echo ${ARRAY[*]}
one two three four

Functions

function quit {
    exit
}
function e {
    echo $1
}
e Hello
e World
quit
echo foo

return can only be an integer between 0-255 (0=success); to get the return value (if you just want to return an integer 0-255) is $?
To return something else use echo so output can be captured with $(func)
fun1 || fun2 will only run fun2 if fun1 returns a 0 value

Redirections

stdout 2 file

ls -l > ls-l.txt

stderr 2 file

grep da * 2> grep-errors.txt

stdout 2 stderr

grep da * 1>&2

stderr 2 stdout

grep * 2>&1

stderr and stdout 2 file

rm -f $(find / -name core) &> /dev/null

Extras

Killswitch When ssh user logs in

#!/bin/bash
ME=10.0.253.131

while true; do
    OTHER=$( who | grep -v tmux | grep -v ${ME} )
    if [ -z "${OTHER}" ]; then
        echo "No one"
    else
        tmux kill-session -t test
    fi
    sleep 5
done


Set files and folder permissions

#!/bin/sh
# syntax: setperm.s destdir
#

destdir=/var/www/rrahome

dirmode=0770
filemode=0660

find $destdir -type f -exec chmod ${filemode} {} \;
find $destdir -type d -exec chmod ${dirmode} {} \;

Backup Hard Drive

#!/bin/bash
USAGE="./$(basename ${0}) UUID output_filename"
BACKUP_ROOT=/mnt/backup

if [ -z "${1}" ]; then
    echo ${USAGE}
    exit
fi
if [ -z "${2}" ]; then
    echo ${USAGE}
    exit
fi

HD=$(blkid | grep $1 | awk -F : '{print $1}')
ISO=${BACKUP_ROOT}/$(hostname)/$(date '+%Y/%m')/$2.iso

dd if=${HD} of=${ISO} bs=1M

Extract date from string

#!/bin/bash
DATE=$( echo ${FILE} | grep -Eo '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}' )

Ping IP range

#!/bin/bash
# cat ping_result.txt | grep ttl | awk '{print $4}' | sed s/:/''/g| sort | uniq
BASE=192.168.0.
for i in {1..126}; do
    ping -c 3 ${BASE}$i >> ping_result.txt
done

Check if a package is installed

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

debInst terminator

Check if a file exists

if [ -f $FILE1 ]
then
if [ -f $FILE2 ]
then
  echo OK
  # MAIN PROGRAM HERE
fi
fi

Check if directory exists

#!/bin/bash
if [ -d /opt/ ]; then
    echo "Sí, sí existe."
else
    echo "No, no existe"
fi

#-d -» Comprobar si existe determinado directorio
#-f -» Comprobar si existe determinado archivo
#-w -» Comprobar si determinado archivo tiene permisos de escritura
#-x -» Comprobar si determinado archivo tiene permisos de ejecución.

#if not: if [ ! -d /opt/ ]; then

Check user

#!/bin/bash
if [ "$EUID" -ne 0 ]
  then echo "Please run as root"
  exit
fi
#!/bin/bash
user=$(whoami)
if [ "$user" == "root" ]; then
   isroot=true
   echo "Eres Root! :)"
else
   isroot=false
   echo "No eres root... :'(" 
   exit
fi

Execute localScript on remote server

ssh [user]@[server] 'bash -s' < [local_script]

Remove directorys

#!/bin/sh
die () {
    echo >&2 "$@"
    exit 1
}

[ "$#" -eq 1 ] || die "1 argument required, $# provided"
echo $1 | grep -E -q '^[0-9]+$' || die "Numeric argument required, $1 provided"

while read dir 
do
    [ -d "$dir" ] || die "Directory $dir does not exist"
    rm -rf "$dir"
done <<EOF
~/myfolder1/$1/anotherfolder 
~/myfolder2/$1/yetanotherfolder 
~/myfolder3/$1/thisisafolder
EOF


Check if variable is set

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

Check command success

#!/bin/bash
###########################################
#          Pull latest code &             #
#      Restart application services       #
###########################################

OK="[\033[01;32m OK \033[01;36m]\033[01;00m"
FAIL="[\033[01;33m FAIL \033[01;36m]\033[01;00m"
LOG_FILE=/dev/null

function check_success {
    if [ $? -eq 0 ]; then
        echo -e ${OK}
    else
        echo -e ${FAIL}
    fi
}


git pull
cd /home/cpc/cpc
./post_pull.sh

echo -en "\033[01;36m    Restarting Gunicorn ... "
sudo /usr/sbin/service gunicorn restart &> ${LOG_FILE}
check_success

echo -en "\033[01;36m    Restarting Daphne ... "
sudo /usr/sbin/service daphne restart &> ${LOG_FILE}
check_success

echo -en "\033[01;36m    Restarting Celery ... "
sudo /usr/sbin/service celery restart &> ${LOG_FILE}
check_success

echo -en "\033[01;36m    Restarting CeleryBeat ... "
sudo /usr/sbin/service celerybeat restart &> ${LOG_FILE}
check_success

Ubuntu proxy setup

#! /bin/bash
HTTP_PROXY_HOST=proxy.example.com
HTTP_PROXY_PORT=3128
HTTPS_PROXY_HOST=proxy.example.com
HTTPS_PROXY_PORT=3128

gsettings set org.gnome.system.proxy mode manual
gsettings set org.gnome.system.proxy.http host "$HTTP_PROXY_HOST"
gsettings set org.gnome.system.proxy.http port "$HTTP_PROXY_PORT"
gsettings set org.gnome.system.proxy.https host "$HTTPS_PROXY_HOST"
gsettings set org.gnome.system.proxy.https port "$HTTPS_PROXY_PORT"

sudo sed -i.bak '/http[s]::proxy/Id' /etc/apt/apt.conf
sudo tee -a /etc/apt/apt.conf <<EOF
Acquire::http::proxy "http://$HTTP_PROXY_HOST:$HTTP_PROXY_PORT/";
Acquire::https::proxy "http://$HTTPS_PROXY_HOST:$HTTPS_PROXY_PORT/";
EOF

sudo sed -i.bak '/http[s]_proxy/Id' /etc/environment
sudo tee -a /etc/environment <<EOF
http_proxy="http://$HTTP_PROXY_HOST:$HTTP_PROXY_PORT/"
https_proxy="http://$HTTPS_PROXY_HOST:$HTTPS_PROXY_PORT/"
EOF

Git check version

#!/bin/bash

function set_upstream() {
    echo "No upstream found, setting up branch to track "
    exit
}

function set_upstream() {
    echo "No upstream found"
}


function check_latest_version(){
    UPSTREAM=${1:-'@{u}'}
    
    if [ -z $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) ]; then
        set_upstream
    fi

    echo "Upstream: "$UPSTREAM
    exit
    # TODO: check if no upstream is configured, ask if should be automatically configured (git branch --set-upstream-to remotes/$TRACK_REPO/$TRACK_BRANCH)
    # to get the upstream branch: git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)

    LOCAL=$(git rev-parse @)
    REMOTE=$(git rev-parse "$UPSTREAM")
    BASE=$(git merge-base @ "$UPSTREAM")

    if [ ${LOCAL} = ${REMOTE} ]; then
        status="Up-to-date"
    elif [ ${LOCAL} = ${BASE} ]; then
        status="Need-to-pull"
    elif [ ${REMOTE} = ${BASE} ]; then
        status="Need-to-push"
    else
        status="Diverged"
    fi
}
check_latest_version

Git check for updates and prompt to update

#!/bin/bash
PROJECT_DIR="$HOME/cpc"
PROJECT_PYTHON_INTERPRETER="$HOME/Virtualenvs/cpc/bin/python"
TRACK_BRANCH="MacBookPablo"
TRACK_REPO="origin"


cd $PROJECT_DIR
remote_commit=$(git branch -av | sed s/*/' '/g | grep $TRACK_BRANCH | grep $TRACK_REPO | awk '{print $2}')
echo "Remote commit: $remote_commit"
local_commit=$(git branch -av | sed s/*/' '/g | grep $TRACK_BRANCH | grep -v remotes/ | awk '{print $2}')
echo "Local commit: $local_commit"


django_migrate() {
    $PROJECT_PYTHON_INTERPRETER manage.py migrate
}

update() {
    echo "Updating code"
    git pull $TRACK_REPO, $TRACK_BRANCH
    django_migrate
}


if [ "$remote_commit" = "$local_commit" ]; then
    echo "Runing latest version"
else
    while true; do
        read -p "Update available. Do you wish to update? " yn
        case $yn in
            [YySs]*) update; break;;
            [Nn]* ) echo "Skipping update..." ; break;;
            * ) echo "Choose y/n";;
        esac
    done
fi

Logging

For logging, you can wrap sections of your script in curly braces and redirect the stdout to a log file:

{
    script_command_1
    script_command_2
    script_command_3
} >> /path/to/log_file

Links

Advanced Bash-Scripting Guide