(if server shows time like 08:14 - then print server is up but if server shows date like Nov13 - print server is not up and send an alert message)
#!/bin/ksh
var1="$(ps -ef | grep 'abc' | grep -v 'grep' | tr -s " " | cut -d ' ' -f5)"
var2="$(date "+%H:%M")"
date="$(date "+%b%d")"
if [ "$var1" == "$var2" ]; then
echo "Server has been bounced" > final.txt
echo " Success"
elif expr "$var1" ">" "$var2" >/dev/null; then
echo "Server has been bounced" > final.txt
echo " Success" > final.txt
elif [ "$var1" == "$date" ]; then
echo "Server is not bounced" > final.txt
echo " Failure" > final.txt
mail -s " Failure, Server is not bounced " final.abc#acb.com
fi
I tried to take the output of var1 with this following command of the server 5th column to check server is bounced or has been up or not
var1=echo "ps -ef | grep 'abc' | grep -v 'grep' | tr -s " " | cut -d ' ' -f5"
var1 output will be either date or time depends on if the server is bounced or not, if bounced shows time if not then shows date
var2=echo "date "+%H:%M" "
var2 output will be today's time.
Keeping in mind that time can be different also not on real time it is checking so if var1 output shows 03:14 and current time is 05:16 then also need to show server is up which i am trying with this
else if expr "$var1" ">" "$var2" >/dev/null
and then this command
date=echo "date "+%b%d" "
date output will be just a format like (Nov15) if the var1 output will be in the format of date variable then have to show server is not bounced and not up
but if var1 output will show time like 02:12 then have to compare with format of var2 and show server is bounced and up
stuck with the script in middle time script is working but date one is not giving the output
With the following you could get the amount of seconds since midnight:
$(($(date '+(%H*60+%M)*60+%S')))
Using -o etimes in ps you can get the amount of seconds since the process is running.
If you know the PID, you can do: ps -p <pid> -o etimes=. If you do not know the PID, you can use grep as you were already doing:
ps -e -o etimes,command|grep abc|awk '{print $1}'
Once you have both values, you can compare if the process running time is greater than amount of seconds since midnight.
Related
I have this script :
#!/bin/bash
ps -eo lstart,pid,cmd --sort lstart | while read line 2> /dev/null
do
if [ "$(date -d "${line::24}" "+%Y%m%d%H%M%S")" -gt "$(date -d "Thu Apr 7 00:55:38" "+%Y%m%d%H%M%S")" ] 2> /dev/null
then echo "Date : $(date -d "${line::24}" "+%d/%m/%Y %H:%M:%S") | PID & CMD : ${line:25:29}" >> process.log 2> /dev/null
fi 2> /dev/null
done
sort process.log | uniq > process.log
#sort process.log | uniq -u | tee process.log
My script runs automatically every 10 seconds, so I would like the identical lines to be deleted. As you can see, I tried with uniq but it doesn't work. I would like all lines in my file to be deleted if they are identical.
As I did, the second time the script is executed, there is nothing in the output file and I don't understand why.
I would also like nothing to be displayed in my terminal when the script runs. I used tee but when executing the uniq command, it returns an output in my terminal... How to remove it?
I thank you in advance for your help and wish you a good day
Thanks a lot
You should not parse ps output ever, especially not of lstart. Also, you are running date in the loop all the time, again and again.
I think something along this would be better to do:
some_date=$(date -d "Thu Apr 7 00:55:38" +%s)
now=$(date +%s)
how_much_time_ago=$(( now - some_date ))
ps -eo etimes,pid,cmd --sort etimes |
awk -v v="$how_much_time_ago" '$1 > v' |
while IFS=' ' read line etimes pid cmd; do
printf "Date : %s | PID & CMD : %s %s\n" \
"$(date -d "$((now - etimes))" "+%d/%m/%Y %H:%M:%S")" \
"$pid" "$cmd"
done |
sort |
uniq > process.log
Note that you can pipe the output of a while .... done | stuff loop to another thing normally. Instead of sprinkling 2>/dev/null everywhere, try to actually solve the issue, not hide the error.
I want store the output of my script in a file, but can't.
This is:
#!/bin/bash
if [ "$1" == "" ]
then
echo "Te falta especificar una dirección ip"
echo "Syntax esperado: ./hostDiscovery.sh <ip>"
else
for ip in `seq 1 254`; do
ping -c 1 $1.$ip | grep "64 bytes" | cut -d " " -f 4 | tr -d ":" | tee ip.txt &
done
fi
The problem is that the file that was created has no data. It is blank.
To quickly answer your question, simply replace your last pipe ... -d ":" | tee ip.txt & with ... -d ":" >> ip.txt &
The >> syntax will append to ip.txt. You can also use tee -a to append but that will also print to stdout.
If you want to make sure that file is cleared each time you run the script you will want to: > ip.txt at the top of your script to clear ip.txt.
Here is what your new script might look like:
#!/bin/bash
if [ "$1" == "" ]; then
echo "Te falta especificar una dirección ip"
echo "Syntax esperado: ./hostDiscovery.sh <ip>"
else
> ip.txt
for ip in `seq 1 254`; do
ping -c 1 $1.$ip | grep "64 bytes" | cut -d " " -f 4 | tr -d ":" | tee -a ip.txt &
done
fi
I have a lot to say about this script though. It looks like you are trying to ping all ip addresses within a range to test to see if they are up/alive. You may want to look into nmap
e.g. nmap -sP 192.168.1.1-254
You are overwriting ip.txt on each call to tee.
Try calling tee -a to append.
man tee for details
This is my Linux script, I want to ask the user from outside what date is needed, then save that date and run the script for that date.
#/bin/bash
cDt=$(date +"%Y%m%d")
cd /home/dwh_landing/temp
echo 'Process_Date,Outfile,Outpath,Process_hour,Process_Minutes,Infile' > ccn_daily_${cDt}.csv
cd /home/dwh_landing/etl_scripts/etl_logs/
awk -F',' '{print $1 "," $2 "," $5}' *ccn-json*${cDt}* | grep 'creditControl.json' | awk -F '/' '{print $0 "," $5}' | awk 'match($0, /(\s\S*k)/ , a ) {print $0 "," a[1]}' >> /home/dwh_landing/temp/ccn_daily_${cDt}.csv
cd /home/dwh_landing/temp
cat ccn_daily_${cDt}.csv | wc -l >> ccn_daily_${cDt}.csv
now currently this script generate a csv for the current date files, I want to run this for a user request date, can I pass parameters from outside?
any help could be useful.
What do you mean by outside? Do you want to pass parameters when running the script? If so, you can run the script with
./myscript $(date +"%Y%m%d")
and use this argument with
#!/bin/bash
cDt="$1"
...
This is parameter number one, since the null parameter is the name of the script.
Also, you can validate a date string with
if ! date +"%Y%m%d" -d "$cDt" &> /dev/null; then
echo "$1 - invalid date string"
exit
fi
YOu can use a while loop to read a date off the user until the date is compliant (date returns a code 0) at which point we break from the loop and execute your script (in this case myscript), passing the read date variable dat as a parameter:
while true;
do read -p "Please enter a date in the format i.e. 20210201" dat;
if date -d "$dat" +"%Y%m%d";
then
break;
fi;
done
myscript "$dat"
Then in your script, amend the line:
cDt=$(date +"%Y%m%d")
to:
cDt="$1" # SEt cDt to the first passed parameter
I am trying to make a bash script that will calculate the time difference between the users' first logon and the users most recent logon. Any help is appreciated :)
This is what I have so far:
read -p "Enter a user ID: " ID
echo "You entered the following ID(s): $ID"
#/bin/egrep -i "^$ID" /etc/passwd
echo -n "The users real name is: "
/bin/grep "^$ID" /etc/passwd | cut -f5 -d :
echo -n "$ID's first login time is: "
l1=`last "$ID" | tail -n 1`
echo -n "$ID's last login time is: "
l2=`last "$ID" | head -n 1`
echo $l1
echo $l2
echo -n "The time difference is $(l1-l2) "
This is based off the assumption you want to provide a username and not an ID.
Firstly, you want to perform your captures correctly
l1=$(last "$ID" | tail -n 1)
l2=$(last "$ID" | head -n 1)
in my instance left
l1="wtmp begins Sun Nov 9 07:32:12 2014"
l2="graham pts/11 :0 Sat Nov 29 22:13 still logged in"
which is no good since we need only dates
So let's fix that. Here's some hacky parsing to get only times:
l1=$(last -RF | grep $ID | tail -n 1 | tr -s ' ' | cut -d ' ' -f 3,4,5,6)
l2=$(last -RF "$ID" | head -n 1 | tr -s ' ' | cut -d ' ' -f 3,4,5,6)
I grep for l1 because last leaves the last logged in, but for consistency, I just grab the last row. last -RF removes the host (-R), since we're not interested and makes the time a bit nicer (-F). tr trims all additional spaces and cut, delimited by a blank, grabs the date.
We want to compute the time between, so let's change both to datetime strings and subtract:
a=$(date -ud "$l2" +"%s")
b=$(date -ud "$l1" +"%s")
d=$(( a-b ))
Finally let's print
echo "$ID's last login time is: $l1"
echo "$ID's first login time is: $l2"
echo "The time difference is $d seconds"
Your script seems to contain a number of errors.
/bin/grep "^$ID" /etc/passwd | cut -f5 -d :
This matches the /etc/passwd file at the start (^) for the uid, AFAIK, the passwd file always starts with the username, not the uid.
Perhaps you are confused about what a user id means; in UNIX, a user id always refers to the numerical ID every user has; a username refers to the loginname that you type when you login.
In any case, using getent is a more reliable method; we could grep for :$uid:, but that might break if a group id is the same as a user id (among other scenarios). getent will also work with both a user id, and a user name.
Also, using /bin/grep is almost always a bad idea; lookups in $PATH are almost always better (so just use grep).
l1=`last "$ID" | tail -n 1`
last expects a username, not a user id; perhaps there is a flavour that also accepts a uid (?); in any case, using the username is more reliable.
echo -n "The time difference is $(l1-l2)"
The dates from last are in a string format (Sat Nov 1 00:39); you can't just subtract those as integers, you first need to parse them with date.
Here is what a working version might look like; I've also made some other (minor) improvements that could be useful for you:
#!/bin/sh
# Keep asking for the uid until *something* is entered
while :; do
read -p "Enter a user ID: " uid
[ -n "$uid" ] && break
done
# Get line from /etc/passwd
passwd=$(getent passwd "$uid")
# Exit code was non-zero; the uid is unknown
if [ $? -ne 0 ]; then
echo "User id '$uid' is unknown"
exit 1
fi
# Get data from passwd
username=$(echo "$passwd" | cut -d: -f1)
realname=$(echo "$passwd" | cut -d: -f5)
# Get info from last, strip last 2 lines since they're not useful for us. Use
# ISO format so that date can parse them
lastlog=$(last --time-format iso "$username" | head -n-2)
# Get first & last line; we only need the date
last_login=$(echo "$lastlog" | head -n1 | tr -s ' ' | cut -d ' ' -f 4)
first_login=$(echo "$lastlog" | tail -n1 | tr -s ' ' | cut -d ' ' -f 4)
# Parse dates with date, output time in seconds since 1-1-1970 ('epoch')
diff=$(( $(date --date "$last_login" +%s) - $(date --date "$first_login" +%s) ))
# Format the date
diff_fmt=$(date --date #$diff +'%d days %H hours %M minutes %S seconds')
# Output info
echo "Found user $username ($realname) for userid $uid"
echo "First recorded login: $first_login"
echo "Last recorded login: $last_login"
echo "Difference: $diff_fmt (total of $diff seconds)"
Unfortunately, this will only work on Linux systems; making work on all UNIX flavours required a bit more work (shell scripting is often difficult to do portable)
Example output:
[~]% sh test.sh
Enter a user ID: 1001
Found user martin (Martin Tournoij) for userid 1001
First recorded login: 2014-11-01T00:13:28+0100
Last recorded login: 2014-11-30T06:08:54+0100
Difference: 30 days 06 hours 55 minutes 26 seconds (total of 2526926 seconds)
Below is my shell script that is working fine.
#!/bin/bash
DATE_YEST_FORMAT2=`perl -e 'use POSIX qw(strftime); print strftime "%Y%m%d",localtime(time()- 3600*96);'`
echo $DATE_YEST_FORMAT2
QUERY1=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT SUM(total_items_purchased), SUM(total_items_missingormismatch) from lip_data_quality where dt='$DATE_YEST_FORMAT2';`
QUERY2=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT 100 * SUM(total_items_missingormismatch*1.0) / SUM(total_items_purchased) FROM lip_data_quality where dt='$DATE_YEST_FORMAT2';"`
echo "Total items purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2"
I am running the above shell script like this below-
sh -x test.sh
Problem Statement:-
From the above shell script, I am getting below three things from the last three echo statements-
Total items purchased
Total Items MissingorMismatch
Error Percentage
I need to send all these above three things in an email to our email group we have DL-host#company.com by using that shell script above or suppose if I have 10 email list to which I need to send email with the same contents and subjects, then I think, I can store all these 10 emails list in some variable and just read it from there and keep on sending, right?. Is this possible to do it? I was thinking email structure like this below, just making very simple.
Subject
Test Data
Mail Body
Total items purchased:- Some Number
Total Items MissingorMismatch:- Some Number
Error Percentage:- Some Number
Any thoughts will be appreciated.
Update, After trying larsks suggestions, I am getting only last echo statement in an email meaning only the error percentage one, not all three in a single email:-
#!/bin/bash
DATE_YEST_FORMAT2=`perl -e 'use POSIX qw(strftime); print strftime "%Y%m%d",localtime(time()- 3600*96);'`
echo $DATE_YEST_FORMAT2
QUERY1=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT SUM(total_items_purchased), SUM(total_items_missingormismatch) from lip_data_quality where dt='$DATE_YEST_FORMAT2';`
QUERY2=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT 100 * SUM(total_items_missingormismatch*1.0) / SUM(total_items_purchased) FROM lip_data_quality where dt='$DATE_YEST_FORMAT2';"`
echo "Total items purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2" | mail -s "Test Data" rj#host.com
You typically use the /bin/mail program to send email from a shell script. You provide a subject and recipients on the command line and the message body on stdin. For example, inside your script you could do something like this:
{
echo "Total items purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2"
} | mail -s "Test Data" DL-host#company.com
You can also pipe the output of an existing script into mail (if you don't want to modify the script, or if you only want to send mail somtimes):
<your script> | mail -s "Test Data" DL-host#company.com
You can specify multiple recipients on the command line, so:
... | mail -s "Test Data" address1#company.com address2#company.com
and so forth.