Quote

Script to send email if your ADSL or cable modem external dynamic IP address changed. Linux based only :)

#!/bin/bash
# Script to test internet IP and send by email
# Script to run every hour from crontab
# Just copy the script to /etc/cron.daily and remove the sh extenstion at the end of the script filename
# Don't forget to add executable permissions to the script chmod +x check_ip
# Note:
# Script works with gmail accounts, didn't test it with other smtp servers
# Script works with mailx by heirloom-mailx only
# Enjoy! Scripted by Daniel Slabodar on 2015 (c) bugz to daniel@dmelody.com
# Globals
email_subject="Current IP address is: "
friendly_name="Your name here"
email_address="Your email address here"
email_password="Your email password here"
smtp_host="smtp.gmail.com"
smtp_port="587"
imap_host="imap.gmail.com"
imap_port="993"
ping_test_url="icanhazip.com" # Nice automation URL to find out your real internet IP address from command line
cur_ip=""
logging="0" # Check this on, if you want to see detailed stdout
# Check if mailx is installed
if [ ! -e /usr/bin/mailx ]; then
 echo "Mailx binary not found"
  if [ ! -e /etc/redhat-release ]; then
   apt-get update 1> /dev/null 2> /dev/null
   apt-get --yes instasll heirloom-mailx 1> /dev/null 2> /dev/null
  else
   echo "Please install RHEL heirloom-mailx"
   exit 1
  fi
fi
function ekko () {
# Function to write to stdout and logger if logging enabled, would write to stdout as well
if [ $logging -eq 1 ]; then
 echo $1
 logger $1
else
 logger $1
fi
}
function check_internet_alive () {
# Function to check current IP address
ping -c1 -t10 -W 3 $ping_test_url 1> /dev/null 2> /dev/null
if [ $? -eq 2 ]; then
 ekko "Internet connection died, sorry"
 exit 1
else
 ekko "Internet connection OK"
fi
}
function check_current_ip () {
# Function to veriry if internet IP address changed and update email message to be sent
# If IP address didn't change, email wouldn't be sent
if [ ! -e /usr/bin/curl ]; then
 apt-get update 1> /dev/null 2> /dev/null
 apt-get --yes install curl 1> /dev/null 2> /dev/null
fi
cur_ip=`curl $ping_test_url`
if [ ! -e /tmp/message.txt ]; then
 # New IP address change after reboot performed
 ekko "New IP address found, or reboot performed"
 echo "$cur_ip" > /tmp/message.txt
else
 existing_ip=`cat /tmp/message.txt`
  if [ "$cur_ip" != "$existing_ip" ]; then
   ekko "The IP address changed to: $cur_ip"
   echo $cur_ip > /tmp/message.txt
  else
   ekko "The IP address didn't change"
  exit 0
 fi
fi
}
function send_email () {
# Function to send email address
mailx -v -s "$email_subject $cur_ip" \
 -S smtp-use-starttls \
 -S ssl-no-default-ca \
 -S smtp-auth=login \
 -S smtp=smtp://$smtp_host:$smtp_port \
 -S from="$email_address($friendly_name)" \
 -S smtp-auth-user=$email_address \
 -S smtp-auth-password=$email_password \
 -S ssl-verify=ignore \
 -S nss-config-dir=/etc/pki/nssdb $email_address < /tmp/message.txt
}
# main
check_internet_alive
check_current_ip
send_email

Simple bash script to backup your folders to remote ssh server.

Hi, a long time I haven’t been writing, so a new nice bash script to backup your folders to remote server which has ssh server enabled. Using sshpass as automated login and for scp instead of interactive expect :)

#/bin/bash
# Script to perform backup of your stuff to remote server

remote_server_name=”<your_host_name or IP address”
remote_server_path=”<your_host_remote_dirpath”
remote_server_user=”<user>”
remote_server_password=”<user_password>”
temp_tar=”<temp_dir_to_store your backups>”

backup_data=( “path1” “path2” ) # where is full path of your data like /home/user /var/lib etc’

cur_path=`pwd`
timedate=`date | sed ‘s/:/ /g’ | awk {‘print $2″_”$3″_”$4″h_”$5″m_”$6″s_”$8’}`

for i in ${backup_data[@]}; do
construct=`basename $i`
tarfile=`echo “$construct”_”$timedate””.tgz”`
logger “Compressing: $tarfile”
tar cfz $temp_tar/$tarfile $i
logger “Copying $tarfile to $remote_server_name:/$remote_server_path using ssh”
sshpass -p “$remote_server_password” scp $temp_tar/$tarfile $remote_server_user@$remote_server_name:/$remote_server_path
done
rm -rf $temp_tar/*.tgz

Enjoy!

The ending result would work for as many directories you want, you can also include this in your /etc/cron.daily/ folder so the script can run automatically every day.

Note, that you would need the sshpass package for the script to work fine, otherwise you can use me other solution using expect interactive scripting.

How to perform a full backup over network of a hard drive using dd and Knoppix Bootable disk on key.

Lot’s of people try to perform backups these days, there are lots of options. Some perform backup on cloud, some on their local cloud or 2TB Western Digital share drive, whatever… One of the ways is just copy your files and photos to some dropbox / onedrive / google drive / rapidshare you name it.

It’s a pain, since if you’ve installed something on your Windows / Linux / Mac machine and it caused kernel panic, or drive corruption, it would be quite hard to restore the OS from scratch you will need to pay a technician or do it yourself. There is a simple solution, using DD and Knoppix, you can even store the files to remote SMB or NFS share (knoppix can be connected to a network as well!).

  • Get a Knoppix disk on key distro from here: http://www.knoppix.org/
  • Get a disk on key creator which can get an iso and create a bootable disk on key: http://www.pendrivelinux.com/install-knoppix-6-to-a-usb-flash-drive-in-windows/ (you can do it both on Windows or Linux) distros.
  • Boot from disk on key on the machine you need to backup.
  • Find your correct hard drive which host all the OS, it is usually /dev/sda ( in case of multiboot system, check twice ), note, not to use /dev/sda1 or /dev/sda6 /dev/sda<N> (these are partition names, it will not backup your whole drive, just a portion of a drive, partition of a drive)
  • Open a konsole (console) as root user, you can root user by typing su – root or just su
  • Mount your SMB or NFS share to /media folder (to mount smbfs do: mount //<IP>/<share_name> -o username=<username>,password=<password /media/<share_name>/ (create the share_name directory first mkdir /media/<share_name>)
  • To backup: (Would create a 10GB files note the . after the image.gz.)
  • dd if=/dev/sda bs=1M | gzip -c –fast | split -b 10000000000 – /media/<share_name>/image.gz.
  • To restore:
  • cat /media/mounted/image.gz.* | gzip -dc | dd of=/dev/sda bs=1M

That’s it.

Locking of multiple scripts running, in Linux with Bash

Got it from this page – http://wiki.bash-hackers.org/howto/mutex

Occasionally you will need to protect multiple script run time, so no one in your neighborhood can run the same in parallel. This is done in order to prevent data loss / corruption memory leaks and you name it. There are lots of ways to achieve locking (mutex) functionality. Doing it plain and simple, and doing it the right way. And frankly, there is a best way, I looked up in the internet and found the above website. I also put the script source here for your management.

The usage of script is quite simple, just source the file in your program and it will lock it.

<MyProgram.sh>

#!/bin/bash

source locker.sh # Include the locker script

# run your code here

ls -la /tmp

<EOF>

<Locker.sh>

#!/bin/bash

# lock dirs/files
LOCKDIR=”/var/lock/MyProgram” # Directory to store your locks
PIDFILE=”${LOCKDIR}/MyProgram.lock” # Your specific lock file with PID

# exit codes and text for them – additional features nobody needs :-)
ENO_SUCCESS=0; ETXT[0]=”ENO_SUCCESS”
ENO_GENERAL=1; ETXT[1]=”ENO_GENERAL”
ENO_LOCKFAIL=2; ETXT[2]=”ENO_LOCKFAIL”
ENO_RECVSIG=3; ETXT[3]=”ENO_RECVSIG”

###
### start locking attempt
###

trap ‘ECODE=$?; echo “[statsgen] Exit: ${ETXT[ECODE]}($ECODE)” >&2’ 0
echo -n “[statsgen] Locking: ” >&2

if mkdir “${LOCKDIR}” &>/dev/null; then
# lock succeeded, install signal handlers before storing the PID just in case
# storing the PID fails
trap ‘ECODE=$?;
echo “[statsgen] Removing lock. Exit: ${ETXT[ECODE]}($ECODE)” >&2
rm -rf “${LOCKDIR}”‘ 0
echo “$$” >”${PIDFILE}”
# the following handler will exit the script on receiving these signals
# the trap on “0” (EXIT) from above will be triggered by this trap’s “exit” command!
trap ‘echo “[statsgen] Killed by a signal.” >&2
exit ${ENO_RECVSIG}’ 1 2 3 15
echo “success, installed signal handlers”
else
# lock failed, now check if the other PID is alive
OTHERPID=”$(cat “${PIDFILE}”)”
# if cat wasn’t able to read the file anymore, another instance probably is
# about to remove the lock — exit, we’re *still* locked
# Thanks to Grzegorz Wierzowiecki for pointing this race condition out on
# http://wiki.grzegorz.wierzowiecki.pl/code:mutex-in-bash
if [ $? != 0 ]; then
echo “lock failed, PID ${OTHERPID} is active” >&2
exit ${ENO_LOCKFAIL}
fi
if ! kill -0 $OTHERPID &>/dev/null; then
# lock is stale, remove it and restart
echo “removing stale lock of nonexistant PID ${OTHERPID}” >&2
rm -rf “${LOCKDIR}”
echo “[statsgen] restarting myself” >&2
exec “$0” “$@”
else
# lock is valid and OTHERPID is active – exit, we’re locked!
echo “lock failed, PID ${OTHERPID} is active” >&2
exit ${ENO_LOCKFAIL}
fi
fi

Remotely connect to SSH server without being asked for password using expect.

First, there is a big pain with regards to usage of remote ssh connections using and not using passwords in various companies, who claim to spend huge amount of time writing the right script to remotely connect with ssh, perform a command then check the return code and come back to the automation scripting tool :)

It took some time to gather, but I am going to show you a nice example of combining quite simple solution using Bash + Expect and one configuration parameter in /etc/ssh/ssh_config files. And it should run a remote command without asking a password or yes and no, check return code, and come back to you :)

First, configure on ssh client side, so it won’t ask you if you want to add a new key to your local keys repository, it is quite annoying question, most of they time you connect to your known servers, and perform automation operations, so you don’t need to check the key fingertip.

echo StrictHostKeyChecking no >> /etc/ssh/ssh_config

Second, you can detect if an existing (passwordless ssh keys are configured ignoring that script to perform the expect script).

#!/bin/bash

ip_address=”127.0.0.1″

user=”root”

user_password=”password”

command=”ls -la /tmp”

if ssh -o BatchMode=yes $ip_address true

        ssh -o StrictHostKeyChecking=no $user@$ip_address $command

else

        call_expect_function $user $ip_address “$command”

fi

# Here you would see how the temporary expect function is being created on each command call

call_expect_function () { # Function would accept $1 as user name, $2 ip address of remote ssh machine and $3 a command you need to send

# Creation of temporary file for run, note you need working expect package, on Debian, perform apt-get install expect

cat << SOF > /tmp/ssh_expect.exp

#!/usr/bin/expect -f

set timeout 35

set env(TERM)

spawn ssh -o StrictHostKeyChecking=no $1@$2 “$3; echo $\?”

expect “assword:” send “$user_password\r”

interact

SOF

chmod 755 /tmp/ssh_expect.exp # Set executable permission for temporary expect script.

/tmp/ssh_expect.exp | tee > /tmp/ssh_expect.out # This can be used for secondary logging purposes

cat /tmp/ssh_expect.out | sed -n ‘/password:/,//p’|grep -v password:|head -n -1 # This is used to actually see what is going on during the command on stdout cmd_result=`cat /tmp/ssh_expect.out | tail -1 | sed ‘s/[^0-9]//g’` # This is used to catch the remote return code and send it to ssh client

if [ $cmd_result -eq 0 ]; then # If the result is 0, then the remote command succeeded, else return 1

rm -rf /tmp/ssh_expect*

return 0

else

rm -rf /tmp/ssh_expect*

return 1

fi

}

Please shoot for questions!