I was looking to setup automatic EBS snapshot at a particular time interval (let say once every week), for this I did Google and found that this task can be done using shell script and I found the same at this link.
Here is whole script, I am using :
#!/bin/bash
# Volume list file will have volume-id:Volume-name format
VOLUMES_LIST = /var/log/volumes-list
SNAPSHOT_INFO = /var/log/snapshot_info
DATE = `date +%Y-%m-%d`
REGION = "ap-south-1a"
# Snapshots Retention Period for each volume snapshot
RETENTION=6
SNAP_CREATION = /var/log/snap_creation
SNAP_DELETION = /var/log/snap_deletion
EMAIL_LIST = shishupal.shakya#itsmysun.com
echo "List of Snapshots Creation Status" > $SNAP_CREATION
echo "List of Snapshots Deletion Status" > $SNAP_DELETION
# Check whether the volumes list file is available or not?
if [ -f $VOLUMES_LIST ]; then
# Creating Snapshot for each volume using for loop
for VOL_INFO in `cat $VOLUMES_LIST`
do
# Getting the Volume ID and Volume Name into the Separate Variables.
VOL_ID = `echo $VOL_INFO | awk -F":" '{print $1}'`
VOL_NAME = `echo $VOL_INFO | awk -F":" '{print $2}'`
# Creating the Snapshot of the Volumes with Proper Description.
DESCRIPTION = "${VOL_NAME}_${DATE}"
/usr/local/bin/aws ec2 create-snapshot --volume-id $VOL_ID --description "$DESCRIPTION" --region $REGION &>> $SNAP_CREATION
done
else
echo "Volumes list file is not available : $VOLUMES_LIST Exiting." | mail -s "Snapshots Creation Status" $EMAIL_LIST
exit 1
fi
echo >> $SNAP_CREATION
echo >> $SNAP_CREATION
# Deleting the Snapshots which are 10 days old.
for VOL_INFO in `cat $VOLUMES_LIST`
do
# Getting the Volume ID and Volume Name into the Separate Variables.
VOL_ID = `echo $VOL_INFO | awk -F":" '{print $1}'`
VOL_NAME = `echo $VOL_INFO | awk -F":" '{print $2}'`
# Getting the Snapshot details of each volume.
/usr/local/bin/aws ec2 describe-snapshots --query Snapshots[*].[SnapshotId,VolumeId,Description,StartTime] --output text --filters "Name=status,Values=completed" "Name=volume-id,Values=$VOL_ID" | grep -v "CreateImage" > $SNAPSHOT_INFO
# Snapshots Retention Period Checking and if it crosses delete them.
while read SNAP_INFO
do
SNAP_ID=`echo $SNAP_INFO | awk '{print $1}'`
echo $SNAP_ID
SNAP_DATE=`echo $SNAP_INFO | awk '{print $4}' | awk -F"T" '{print $1}'`
echo $SNAP_DATE
# Getting the no.of days difference between a snapshot and present day.
RETENTION_DIFF = `echo $(($(($(date -d "$DATE" "+%s") - $(date -d "$SNAP_DATE" "+%s"))) / 86400))`
echo $RETENTION_DIFF
# Deleting the Snapshots which are older than the Retention Period
if [ $RETENTION -lt $RETENTION_DIFF ];
then
/usr/local/bin/aws ec2 delete-snapshot --snapshot-id $SNAP_ID --region $REGION --output text> /tmp/snap_del
echo DELETING $SNAP_INFO >> $SNAP_DELETION
fi
done < $SNAPSHOT_INFO
done
echo >> $SNAP_DELETION
# Merging the Snap Creation and Deletion Data
cat $SNAP_CREATION $SNAP_DELETION > /var/log/mail_report
# Sending the mail Update
cat /var/log/mail_report | mail -s "Volume Snapshots Status" $EMAIL_LIST
But when I ran it over terminal, it is showing me following errors.
Since I am new in this type of work so I am little uncomfortable in resolving this.
Please suggest the fix, I am on this since last few days.
There should not be spaces around the equals (=) signs.
FOO = 1
-bash: FOO: command not found
The correct syntax is:
FOO=1
Go through the script and remove all the spaces in the statements that assign values to variables.
But there is another error "expecting do" -- this makes me think the script is not being run with the correct shell. Instead of 'sh ec2.sh', try running it with bash explicitly: bash ec2.sh
It will be more easy to do it through AWS console.
In cloudwatch you create a new event rule. The event source is "scheduled". For the target you pick up "EC2 Createsnapshot API call". Enter the volume ID (you can find it in the ec2 instances console). Let AWS create a new role for this specific resource.
That's it !
Related
I don't know why I am getting this error --> : integer expression expected: [: 82
value 82 comes from CURRENT. I am trying to grab the disk space usage and assign to variable called CURRENT and then email out. I don't know where I am going wrong? Any help is appreciated.
#!/bin/bash
ADMIN=email#email.com
THRESOLD=80
CURRENT=$(df -H | grep '/dev/mapper/cvs-cvs' | awk '{ print $5}' | cut -d'%' -f1)
if [ $CURRENT -ge $THRESOLD ]; then
echo "My CVS disk space usage is $CURRENT %" | mailx -s "Disk Space Usage" $ADMIN
fi
Probably your script is in DOS format that the assignment includes \r The extra value appended to the number causes the error. Try converting it first with either of the following commands:
sed -i 's|\r||' script
dos2unix script
It looks like your CURRENT value is not being assigned to an integer from the command substitution output.
I'd recommend running df on the directory you want, then parse the output.
#!/bin/bash
ADMIN=email#email.com
THRESOLD=80
read -ra DF_OUT < <(df -H /dev/mapper/cvs-cvs 2>&1|tail -n 1)
if [[ ${DF_OUT[#]} != "df:"* ]]; then
CURRENT=${DF_OUT[4]/\%/}
if [ $CURRENT -ge $THRESOLD ]; then
echo "My CVS disk space usage is $CURRENT %" | mailx -s "Disk Space Usage" $ADMIN
fi
else
echo -e "df encountered the following error:\n$DF_OUT"
fi
This first checks for an error on the df output before proceeding to parse the results for disk usage.
As others suggested, using -x with the script helps diagnose things.
try
#!/bin/bash
ADMIN=email#email.com
let "THRESOLD=80"
declare -i CURRENT
let CURRENT=$(df -H | grep '/dev/sda1' | awk '{ print $5}' | cut -d'%' -f1)
if (($CURRENT >= $THRESOLD )) ; then
echo "My CVS disk space usage is $CURRENT %" | mailx -s "Disk Space Usage" $ADMIN
fi
How do I create a script that will identify all live hosts (responding to ping) using bin/bash in linux? My thoughts are to first have a
fping -A "some URL" // to get the IP address
then to set that to a var. then run a
fping -g "var" // having the ip address inserted by using a var.
Is there an easier way? If so, what would that script look like?
Not sure what you want to do and why you use fping, but if you just need the IP for a host you should use somthing like this:
getent ahostsv4 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent ahostsv6 www.google.de | grep STREAM | head -n 1 | cut -d ' ' -f 1
getent hosts google.de | head -n 1 | cut -d ' ' -f 1
All commands will resolve an IP address if host still exist. If host points to CNAME it will also get the IP in that case.
Lets say, you have a text file containing all your hosts to test:
like: test-hosts.txt
www.server1.dom
www.server2.dom
server3.dom
1.3.5.7
then the command line (contains bash-script) will do it:
cat test-hosts.txt | xargs -i\{\} bash -c 'HOST="{}"; IP=$(getent ahostsv4 "{}" | grep STREAM | head -n 1 | cut -d " " -f 1); ping -c 1 -w 5 "$IP" >/dev/null 2>&1; RESULT="$?"; echo -e "Host: $HOST ($IP) \c"; case "$RESULT" in 0) echo "is online";; 1) echo "not responding after 5 secs";; *) if [[ "$IP" == "" ]]; then echo "has no resolveable address"; else echo "not availabe due to error [$RESULT]"; fi;; esac;'
and provide outputs like:
is online
not responding
no resolveable address
not available due error [code]
I am trying to write a shell script to monitor file system. script logic is,
for each file system from df -H command, read the file system threshold file and get the critical threshold, warning threshold. Based on the condition, it will send notification.
Here is my script:
#!/bin/sh
df -H | grep -vE '^Filesystem|none|boot|tmp|tmpfs' | awk '{ print $5 " " $6 }' | while read $output
do
echo $output
fsuse=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
fsname=$(echo $output | awk '{ print $2 }' )
server=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $2}'`
fscrit=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $3}'`
fswarn=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $4}'`
serenv=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $5}'`
if [ $fsuse -ge $fscrit ]; then
message="CRITICAL:${server}:${serenv}:$fsname Is $fsuse Filled"
_notify;
elif [ $fsuse -gt $fswarn ] && [ $fsuse -lt $fscrit ]; then
message="WARNING: $fsname is $fsuse Filled"
_notify;
else
echo "File system space looks good"
fi
done
Here is /workspace/OSE/scripts/fs_alert:
/:hlpdbq001:90:80:QA:dba_mail
/dev/shm:hlpdbq001:90:80:QA:dba_mail
/boot:hlpdbq001:90:80:QA:dba_mail
/home:hlpdbq001:90:80:QA:dba_mail
/opt:hlpdbq001:90:80:QA:dba_mail
/opt/security:hlpdbq001:90:80:QA:dba_mail
/tmp:hlpdbq001:90:80:QA:dba_mail
/var:hlpdbq001:90:80:QA:dba_mail
/u01/app:hlpdbq001:90:80:QA:dba_mail
/u01/app/oracle:hlpdbq001:90:80:QA:dba_mail
/oratrace:hlpdbq001:90:80:QA:dba_mail
/u01/app/emagent:hlpdbq001:90:80:QA:dba_mail
/gg:hlpdbq001:90:80:QA:dba_mail
/workspace:hlpdbq001:90:80:QA:dba_mail
/dbaudit:hlpdbq001:90:80:QA:dba_mail
/tools:hlpdbq001:90:80:QA:dba_mail
My problem is when the script is trying to get crit_va, warn_val from the file for /u01 file system, I am getting three results. How do I get/filter one file system at a time?
$ df -H|grep /u01
/dev/mapper/datavg-gridbaselv 53G 12G 39G 24% /u01/app
/dev/mapper/datavg-rdbmsbaselv 53G 9.6G 41G 20% /u01/app/oracle
/dev/mapper/datavg-oemagentlv 22G 980M 20G 5% /u01/app/emagent
what is the best way to handle this issue?
do i need logic based on Filesystem or Mounted on.
Don't reinvent the wheel. There are tools out there that can do this for your. Try monit for example:
http://sysadminman.net/blog/2011/monit-disk-space-monitoring-1716
well, monit is fine ), if you need alternative take a look at df-check - a wrapper for df utility to verify that thresholds are not exceeded , on per partition basis. At least it seems very close to what you started to implement in your bash script, but it's written on perl and has a neat and simple installation layout. ready to use tool.
-- Regards
PS discloser - I am the tool author
I am trying to use a script to run two linux dns commands WHOIS and DIG.
So far my script is as follows:
#!/bin/bash
for i in $1
do
reg1=`whois $i`
echo "*********WHOIS Results for $i*********"
echo -e "[$i]\n$reg1"
for j in 4.2.2.3
do
reg=`dig any #$j $i `
echo -e "[$j]$reg"
done
done
Now I am looking for a command to replace the '4.2.2.3' that I can use to search the output of the previous command and return part of this line: 'Name Server: A.DNS.HOSTWAY.NET'. The 'Name Server:' is what I will search for and it should return the following text, stopping at the end of the line.
If I'm interpreting what you want to do correctly, you should be able to do something like this:
#!/bin/bash
for i in $1
do
reg1=`whois $i`
echo "*********WHOIS Results for $i*********"
echo -e "[$i]\n$reg1"
grep 'Name Server' <<< "$reg1" | awk '{print $3}' | while read j
do
echo -e "[$j]$(dig any #$j $i)"
done
done
To answer your question, you could try something like :
[ ~]$ echo "Name Server: A.DNS.HOSTWAY.NET"|egrep -o "Name Server:\ *[A-Za-z\.]*"|awk -F ": *" '{print $2}'
A.DNS.HOSTWAY.NET
But I'm not sure I understood everything, including the fact of using a for loop on a single value.
I am configuring xbindkeys to change window focus using shortcuts.
For example, I managed to create a shortcut to focus on a an application window, let's say a terminator window:
wmctrl -xa terminator
Unfortunately it focuses always at the same terminator window, preventing me to cycle through the terminator windows.
Could you suggest me a command to focus on a terminator window and, if pressed again, will cycle through all the terminator windows, please?
UPDATE 30 Mar 2013
I modified this script
http://lars.st0ne.at/blog/switch%20between%20windows%20within%20the%20same%20application
to make a script such that
script.sh NAME
focus on application NAME or cycle through all the windows of NAME if a window of it is already focused, but it doesn't work properly.
Here is the script
win_class=$1 # 'terminator' # $1
# get list of all windows matching with the class above
win_list=$(wmctrl -x -l | grep -i $win_class | awk '{print $1}' )
# get id of the focused window
active_win_id=$(xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}')
# get next window to focus on, removing id active
switch_to=$(echo $win_list | sed s/.*$active_win_id// | awk '{print $1}')
# if the current window is the last in the list ... take the first one
if [ "$switch_to" == '' ];then
switch_to=$(echo $win_list | awk '{print $1}')
fi
# switch to window
wmctrl -i -a $switch_to
The script does focus on a windows of the application, and cycle through them until it reach a window, I guess the last created. At that point, cycling doesn't work anymore.
I've found a problem in the script, if no window has focus.
May you try the following modified script:
#!/bin/bash
win_class=$1 # 'terminator' # $1
# get list of all windows matching with the class above
win_list=$(wmctrl -x -l | grep -i $win_class | awk '{print $1}' )
# get id of the focused window
active_win_id=$(xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}')
if [ "$active_win_id" == "0" ]; then
active_win_id=""
fi
# get next window to focus on, removing id active
switch_to=$(echo $win_list | sed s/.*$active_win_id// | awk '{print $1}')
# if the current window is the last in the list ... take the first one
if [ "$switch_to" == '' ];then
switch_to=$(echo $win_list | awk '{print $1}')
fi
# switch to window
wmctrl -i -a $switch_to
The script works for me.
Anyway, it seems that the script does not find the active window in you case. Therefore it manages to switch to your application but fails to cycle through. It switches to the fist window in $win_list because, the sed command fails to remove the active window ( and all list entries before ) from $win_list.
Try the the following command:
xprop -root _NET_ACTIVE_WINDOW
The output should be something like this:
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x2400005
The property "_NET_ACTIVE_WINDOW" is part of the EWMH standard. see: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html
Maybe you are using a non EWMH( Extended Window Manager Hint ) compliant window manager!
Which WM are you using?
... some window manager allow to enable EWMH compatibility via configuration or plugin.
After adapting the script by st0ne, I have a version that works generically (don't need to specify the app_name). Hope that is useful to somebody. :)
#!/bin/bash
active_win_id=`xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}' | awk -F', ' '{print $1}'`
if [ "$active_win_id" == "0" ]; then
active_win_id=""
fi
app_name=`wmctrl -lx | grep $active_win_id | awk '{print $3}'`
workspace_number=`wmctrl -d | grep '\*' | cut -d' ' -f 1`
win_list=`wmctrl -lx | grep -ri $app_name | grep " $workspace_number " | awk '{print $1}'`
# get next window to focus on, removing id active
switch_to=`echo $win_list | sed s/.*$active_win_id// | awk '{print $1}'`
# if the current window is the last in the list ... take the first one
if [ "$switch_to" == "" ];then
switch_to=`echo $win_list | awk '{print $1}'`
fi
if [[ -n "${switch_to}" ]]
then
(wmctrl -ia "$switch_to") &
else
if [[ -n "$2" ]]
then
($2) &
fi
fi
exit 0
I encountered a small issue1 with tkt028's answer, but I liked what they were doing in terms of handling any generic application. But I also liked how st0ne's answer handles cycling through the windows of a specifically named application. So I combined the approaches.
My script takes an optional first argument to specify an application whose windows should be cycled. If no such windows are found, and if the optional second argument was provided, it falls back to launching the command specified by the second argument.
If no arguments are provided at all, then it just cycles through the windows of the currently active application.
#!/bin/bash
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
echo "Cycle through windows of the active, or specified, application."
echo ""
echo "Usage: $(basename $0) [window_class_name [application_launcher]]"
echo ""
echo " window_class_name: regex string specifying an application's window name,"
echo " as specified by the third column of"
echo " 'wmctrl -l -x'"
echo " application_launcher: application to optionally launch if no windows"
echo " matching window_class_name are found"
echo ""
echo "If no arguments are specified, cycles through the windows of the active application."
exit
fi
# get ID of active window
active_win_id=`xprop -root | grep '^_NET_ACTIVE_W' | awk -F'# 0x' '{print $2}' | awk -F', ' '{print $1}'`
if [ "$active_win_id" == "0" ]; then
active_win_id=""
fi
if [[ -n "$1" ]]; then
# get app name from input argument
app_name="$1"
else
# get corresponding app name
app_name="${app_name:-$(wmctrl -lx | grep $active_win_id | awk '{print $3}')}"
fi
# get active workspace number
workspace_number=`wmctrl -d | grep '\*' | cut -d' ' -f 1`
# get list of windows corresponding to the desired app
win_list=`wmctrl -lx | grep -i $app_name | grep " $workspace_number " | awk '{print $1}'`
# get next window of app to focus on
#
# (Parses $win_list as a single string, removing everything except the token
# after the active ID. If active ID is sole token or last token, string will be
# left unmodified, producing an array from which we'll extract the first element.)
# Note: If active window was not of class app_name, then this will end up
# selecting the first window of app_name, if running. Otherwise, we'll fall
# through to launching a new instance of the app in the else of the next block.
switch_to=($(echo $win_list | sed "s/.*\<\(0x0\+\)\?$active_win_id\>\s*\(\<0x[0-9a-f]\+\>\).*/\2/"))
# if we have a valid window to switch to, do so
if [[ -n "${switch_to}" ]]; then
wmctrl -ia "${switch_to[0]}"
exit $?
else
# if the user specified a fallback application to run if target window
# was not found, try to launch it
if [[ -n "$2" ]]; then
$2 &
# check whether process corresponding to PID of background
# process we just launched is still running
ps -p $! > /dev/null
exit $?
else
exit $?
fi
fi
1 The recursive grep on this line in tkt028's answer didn't work in my environment. Maybe it's dependent on your version of grep.
win_list=`wmctrl -lx | grep -ri $app_name | grep " $workspace_number " | awk '{print $1}'`
I simply removed the r argument from the grep, and then their script worked as advertised.
win_list=`wmctrl -lx | grep -i $app_name | grep " $workspace_number " | awk '{print $1}'`