Shell Script: Speed of transfer of a hop using command Ping - bash

Create a shell script that relates the speed of transfer of a HOP between the machine and the IP chosen. Use the PING command and express the result in kB/sec.
!/bin/bash
I create a temporary file
touch info.txt;
I take the second line of command PING stopped after two seconds
I post the results in the file.
ping -t 2 $1 | head -2 | tail -1 > info.txt;
I take bytes
cut -c -2 info.txt;
I take ms
cut -c 53-59 info.txt;
Now, how to make transformations in KB and in Sec?
Show result
echo "Result: .....";
I delete the file.
rm file.txt;

You can do:
bytes=$(cut -c -2 info.txt)
ms=$(cut -c 53-59 info.txt)
echo "KiB: "$(($bytes/1024))
echo "Sec: "$(($ms/1000))
speed=$((1000*$bytes*1000/1024/$ms))
speed=$(echo $speed|sed -r 's/^(.*)(.{3})$/\1.\2/')
echo "Speed: $speed KiB/s"
This is of course considering 1 KiB = 1024 bytes, where KiB is usually used for KB.

RESULT=$(ping -t 2 -c 2 $1 | grep 'time=' | head -1 | sed 's/([0-9][0-9]).(time=)(.)(ms)/\1:\3/g')
echo "BYTES = ${RESULT%:}"
echo "SPEED = ${RESULT#:}"
For the conversion part you might need to use python or perl. In bash it is not possible to calculate fractional numbers.

Thank you all! WORK!
touch info.txt;
ping -t 2 $1 | head -2 | tail -1 > info.txt;
bytes=$(cut -c -2 info.txt);
ms=$(cut -c 53-59 info.txt);
KB=$(echo "scale=5; $bytes /1024" | bc);
Sec=$(echo "scale=5; $ms /1000" | bc);
Speed=$(echo "scale=5; $KB/$Sec" | bc);
echo "Speed of HOP: $Speed KB/sec.";
rm info.txt;

Related

bash send mail when threshold is exceeded in three successive runs

I have a bash script that does a pretty decent job on reporting CPU level above 95%. The issue I am running into is it will report on even "spikes". This script runs every 10 minutes and checks all of my servers. Is there a way to only report if the server reports a level above 95% for 3 iterations? say after the 3rd time it runs, i.e 30 min.
12:00 - 1st report - 98%
12:10 - 2nd report - 99%
12:20 - 3rd report - 98% (now alert the admin)
here is the section of the script:
for sn in $(cat /tmp/hosts |grep -v "#"); do
cpuuse=$(ssh -qn -o ConnectTimeout=15 -oStrictHostKeyChecking=no -o BatchMode=yes $sn "top -b -n2 -p 1 | fgrep \"Cpu(s)\" | tail -1 | awk -F'id,' -v prefix=\"\$prefix\" '{ split(\$1, vs, \",\"); v=vs[length(vs)]; sub(\"%\", \"\", v); printf \"%s%.1f%%\n\", prefix, 100 - v }' | rev | cut -c 4- | rev")
if [[ "$cpuuse" -ge 95 ]]; then
echo "CPU Alert!! $sn CPU is high - $cpuuse%" | mailx -s "CPU Alert on $sn" admin#sample.com
fi
done
AFAIK There isn't really a bash trick. You just need to store a counter somewhere. Something like this could do the trick:
for sn in $(cat /tmp/hosts |grep -v "#"); do
cpuuse=$(ssh -qn -o ConnectTimeout=15 -oStrictHostKeyChecking=no -o BatchMode=yes $sn "top -b -n2 -p 1 | fgrep \"Cpu(s)\" | tail -1 | awk -F'id,' -v prefix=\"\$prefix\" '{ split(\$1, vs, \",\"); v=vs[length(vs)]; sub(\"%\", \"\", v); printf \"%s%.1f%%\n\", prefix, 100 - v }' | rev | cut -c 4- | rev")
counter_file=/tmp/my-counter-file-$sn # separate counter file for each server
if [[ "$cpuuse" -ge 95 ]]; then
date >> $counter_file # just add a line to the counter file
if [[ $(wc -l $counter_file) -ge 3 ]]; then
echo "CPU Alert!! $sn CPU is high - $cpuuse%" | mailx -s "CPU Alert on $sn" admin#sample.com
rm $counter_file # message was sent, reset counter
fi
else
rm $counter_file # below limit, reset counter
fi
done
The trick here is to store a counter in a file. The number of lines in the file is your counter value.

WICD-CLI Script: How i read variable from the list of wireless networks

My whole script is:
#!/bin/bash
while /bin/true; do
if ! [ "$(ping -c 1 google.com)" ]; then
echo "Warning: connection lost at $(date) -- restart"
wicd-cli --wireless -x
sleep 5
wicd-cli --wireless -cn 1
sleep 60
if ! [ "$(ping -c 1 google.com)" ]; then
echo "Waiting for connection going up at $(date)"
sleep 60
else
echo "Connection on at $(date)"
fi
# else
# echo "Connection OK on $(date)"
fi
sleep 60
done
And I need read value from the list:
wicd-cli --wireless -l
# BSSID Channel ESSID
0 00:1D:0F:EA:51:02 9 Liho
1 5C:6A:80:4C:67:BB 13 Heidrovi
2 F4:F2:6D:14:87:61 7 InternetNASA
3 00:23:F8:06:10:99 1 TP-LINK
4 D8:FE:E3:19:F8:C3 3 D-Link
5 C4:F0:81:24:15:1F 10 HUAWEI-B315-151F
6 40:A5:EF:2A:B5:2C 7 InternetNASA-plus
7 50:C7:BF:11:E7:9E 4 MAXXNET.cz-pravda2
8 20:2B:C1:96:15:10 1 Internet
for example ESSID D-Link has now connection number 4
I know this:
wicd-cli --wireless -l | grep 'D-Link'
4 D8:FE:E3:19:F8:C3 3 D-Link
My friend advice me this cmd:
w
icd-cli --wireless -l | grep 'D-Link' | cut -d' ' -f1
still output is this:
4 D8:FE:E3:19:F8:C3 3 D-Link
wicd-cli --wireless -l | grep 'D-Link' | cut -d'' -f1
cut: oddělovač musí být jediný znak
Více informací získáte příkazem „cut --help“.
(Czech Language- Translation to English)
cut: the separator must be the only character
For more information, go to the command „cut --help“.
But works for my purpose cmd:
wicd-cli --wireless -l | grep 'D-Link' | cut -c1
4
I can also use file for number of wifi by the list...
wicd-cli --wireless -l | grep 'D-Link' | cut -c1 > wifi_number
ao#ROUTER ~ $ cat wifi_number
4
And i need to change script like this:
#!/bin/bash
while /bin/true; do
if ! [ "$(ping -c 1 google.com)" ]; then
echo "Warning: connection lost at $(date) -- restart"
wicd-cli --wireless -x
sleep 5
wicd-cli --wireless -cn ***"READ_NUMBER FROM CMD:***"wicd-cli --
wireless -l | grep 'D-Link' | cut -c1 ***(Which is 4 for
NOW...Its changing during day...)***
***OR (My OR, not the logic OR, like i have second idea how to do it,
but still dont know how to read character from file)***
wicd-cli --wireless -l | grep 'D-Link' | cut -c1 > wifi_number
wicd-cli --wireless -cn ***(READ_NUMBER_FROM_FILE=wifi_number) (I
dont know how)***
***(OR DIRECTLY SOME CMD LIKE THIS:)
(HOW TO READ WRITE THIS CMD)***
wicd-cli --wireless -cn | wicd-cli --wireless -l | grep 'D-Link' | cut -c1
***(THIS SEQUENCE GIVES ME THIS:)***
wicd-cli --wireless -cn | wicd-cli --wireless -l | grep 'D-Link' | cut -c1
Usage: wicd-cli.py [options]
wicd-cli.py: error: -n option requires an argument
4
sleep 60
if ! [ "$(ping -c 1 google.com)" ]; then
echo "Waiting for connection going up at $(date)"
sleep 60
else
echo "Connection on at $(date)"
fi
# else
# echo "Connection OK on $(date)"
fi
sleep 60
done
DESIRED OUTPUT IS CHOICE I MANUALLY SELECT ESSID (e.g. ESSID: Horak_LazNet.cz) WHICH HAS DURING DAY DIFFERENT VALUES IN THE LIST:
wicd-cli -l --wireless
# BSSID Channel ESSID
0 00:1D:0F:EA:51:02 9 Liho
1 5C:6A:80:4C:67:BB 13 Heidrovi
2 E4:BE:ED:05:67:98 10 CZNetFreeSromovi
3 E4:BE:ED:7E:71:80 6 Horak_LazNet.cz
4 F4:F2:6D:14:87:61 7 InternetNASA
5 C4:F0:81:24:15:1F 10 HUAWEI-B315-151F
6 D8:B6:B7:86:DD:AD 10 Internet_AC
7 40:A5:EF:2A:B5:2C 7 InternetNASA-plus
8 50:C7:BF:11:E7:9E 4 MAXXNET.cz-pravda2
9 20:2B:C1:96:15:10 1 Internet
10 5C:F4:AB:00:CF:AB 8 Internet_A8
11 E4:BE:ED:B9:18:10 2 MAXXNET.cz-kuznikova1
NOW IS THE NUMBER 3 for CMD IN SCRIPT:
(wicd-cli --wireless -cn *"NUMBER"*) <<<----THIS I Dont know to set up like this pattern <<<----
wicd-cli --wireless -cn 3
Before i Found these script i use cmds in script:
ifconfig wlxd46e0e1576c6 down
ifconfig wlxd46e0e1576c6 up
-DOWN- works but -UP- does not work
And when I use these new script with number, for time that number fitz to my network (e.g.: D-Link) these script works well, with schedule in crontab to run every minute.
When i run script from terminal when i am disconnect or in DEAD STATE, like connection EXISTs but connection to Internet does not works then This Script with Right Number of Wifi works excellent.
I am apologizing for text bad formating, but this is My First post/question here. I read out first quick "manual" how This site works, and I tried to find answer by search engine, but I was unsucesfull.
For clarification, i am using Linux Mint 18.2 Sonya 64bit (Mate version).
And I am using together default Network Manager and WICD, because, default network manager i have configured for Access Point Hot Spot for my own personnal Wireless and WICD I use for connecting to Wireless connected to Internet. I find out that WICD work much better for LOW signal Wireless and keep that connection more Stable than original network manager. But i do not find out how to configure Access Point and Connection to Wireless connected to Internet togetger in WICD. There is only posibility to select device (My is wlxd46e0e1576c6 for Wireless with Internet, and another one in default network manager for Access Point for My Own purpose.
If you want a quick one-liner, you can use:
wicd-cli --wireless -cn `wicd-cli -l --wireless | grep 'D-Link' | cut -c1`
You can also introduce a new variable, say, NET_NUM to make the code more readable.
NET_NUM=$(wicd-cli -l --wireless | grep 'D-Link' | cut -c1)
wicd-cli --wireless -cn $NET_NUM
Or even a bash function to make it more general.
switch_net() {
[[ $# != 2 ]] && echo "usage: switch_net <ssid_regexp> && exit 1
SSID=$1
NET_NUM=$(wicd-cli -l --wireless | grep $SSID | cut -c1)
wicd-cli --wireless -cn $NET_NUM
}
and use it later on with:
switch_net "D-Link"

BASH, read first column in file in loop

Here is what I am trying to do. I would like to catch the top 10 cpu consuming PID's and find the program name. Then display the program name and % CPU in file.
CPU_per=$(sar 1 1 | tail -1 | awk '{print 100 - $5}')
echo $CPU_per
if [ $CPU_per -gt 80 ]
(prstat -u user -n 900 0 1 | grep Type | head -n 10 | awk '{print $1 " " $9}') >> /tmp/PID
for i in $(cat /tmp/PID)
do
(awk '{print $1 } | ps -p $PID -o args | tail -1 | cut -d \ -f 2)
I would like output to look like
Process %CPU
Program1 5%
Program2 9%
Program3 12%
Like this ?
echo -e "COMMAND\t\t%CPU"; ps -eo "%c %C%%" --sort pcpu | tail -n10

connections duration calculation process time

I am using the following code in bash linux to extract time duration for each connection
for a in folder/*.pcap
do
difference=$(echo $(tshark -r $a -T fields -e frame.time_epoch | tail -n 1) - $(tshark -r $a -T fields -e frame.time_epoch | head -n 1) | bc)
echo $difference
done
However, the process time is very high (1 minute for 100 pcaps). Any ideas how to improve process time?
Would this work:
myfun() {
a=$1
difference=$(echo $(tshark -r $a -T fields -e frame.time_epoch | tail -n 1) - $(tshark -r $a -T fields -e frame.time_epoch | head -n 1) | bc)
echo $difference
}
export -f myfun
parallel myfun ::: folder/*.pcap
You can install GNU Parallel simply by:
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
Watch the intro videos to learn more: http://pi.dk/1
10 seconds installation:
wget pi.dk/3 -qO - | sh -x

Bash script checking cpu usage of specific process

First off, I'm new to this. I have some experience with windows scripting and apple script but not much with bash. What I'm trying to do is grab the PID and %CPU of a specific process. then compare the %CPU against a set number, and if it's higher, kill the process. I feel like I'm close, but now I'm getting the following error:
[[: 0.0: syntax error: invalid arithmetic operator (error token is ".0")
what am I doing wrong? here's my code so far:
#!/bin/bash
declare -i app_pid
declare -i app_cpu
declare -i cpu_limit
app_name="top"
cpu_limit="50"
app_pid=`ps aux | grep $app_name | grep -v grep | awk {'print $2'}`
app_cpu=`ps aux | grep $app_name | grep -v grep | awk {'print $3'}`
if [[ ! $app_cpu -gt $cpu_limit ]]; then
echo "crap"
else
echo "we're good"
fi
Obviously I'm going to replace the echos in the if/then statement but it's acting as if the statement is true regardless of what the cpu load actually is (I tested this by changing the -gt to -lt and it still echoed "crap"
Thank you for all the help. Oh, and this is on a OS X 10.7 if that is important.
I recommend taking a look at the facilities of ps to avoid multiple horrible things you do.
On my system (ps from procps on linux, GNU awk) I would do this:
ps -C "$app-name" -o pid=,pcpu= |
awk --assign maxcpu="$cpu_limit" '$2>maxcpu {print "crappy pid",$1}'
The problem is that bash can't handle decimals. You can just multiply them by 100 and work with plain integers instead:
#!/bin/bash
declare -i app_pid
declare -i app_cpu
declare -i cpu_limit
app_name="top"
cpu_limit="5000"
app_pid=`ps aux | grep $app_name | grep -v grep | awk {'print $2'}`
app_cpu=`ps aux | grep $app_name | grep -v grep | awk {'print $3*100'}`
if [[ $app_cpu -gt $cpu_limit ]]; then
echo "crap"
else
echo "we're good"
fi
Keep in mind that CPU percentage is a suboptimal measurement of application health. If you have two processes running infinite loops on a single core system, no other application of the same priority will ever go over 33%, even if they're trashing around.
#!/bin/sh
PROCESS="java"
PID=`pgrep $PROCESS | tail -n 1`
CPU=`top -b -p $PID -n 1 | tail -n 1 | awk '{print $9}'`
echo $CPU
I came up with this, using top and bc.
Use it by passing in ex: ./script apache2 50 # max 50%
If there are many PIDs matching your program argument, only one will be calculated, based on how top lists them. I could have extended the script by catching them all and avergaing the percentage or something, but this will have to do.
You can also pass in a number, ./script.sh 12345 50, which will force it to use an exact PID.
#!/bin/bash
# 1: ['command\ name' or PID number(,s)] 2: MAX_CPU_PERCENT
[[ $# -ne 2 ]] && exit 1
PID_NAMES=$1
# get all PIDS as nn,nn,nn
if [[ ! "$PID_NAMES" =~ ^[0-9,]+$ ]] ; then
PIDS=$(pgrep -d ',' -x $PID_NAMES)
else
PIDS=$PID_NAMES
fi
# echo "$PIDS $MAX_CPU"
MAX_CPU="$2"
MAX_CPU="$(echo "($MAX_CPU+0.5)/1" | bc)"
LOOP=1
while [[ $LOOP -eq 1 ]] ; do
sleep 0.3s
# Depending on your 'top' version and OS you might have
# to change head and tail line-numbers
LINE="$(top -b -d 0 -n 1 -p $PIDS | head -n 8 \
| tail -n 1 | sed -r 's/[ ]+/,/g' | \
sed -r 's/^\,|\,$//')"
# If multiple processes in $PIDS, $LINE will only match\
# the most active process
CURR_PID=$(echo "$LINE" | cut -d ',' -f 1)
# calculate cpu limits
CURR_CPU_FLOAT=$(echo "$LINE"| cut -d ',' -f 9)
CURR_CPU=$(echo "($CURR_CPU_FLOAT+0.5)/1" | bc)
echo "PID $CURR_PID: $CURR_CPU""%"
if [[ $CURR_CPU -ge $MAX_CPU ]] ; then
echo "PID $CURR_PID ($PID_NAMES) went over $MAX_CPU""%"
echo "[[ $CURR_CPU""% -ge $MAX_CPU""% ]]"
LOOP=0
break
fi
done
echo "Stopped"
Erik, I used a modified version of your code to create a new script that does something similar. Hope you don't mind it.
A bash script to get the CPU usage by process
usage:
nohup ./check_proc bwengine 70 &
bwegnine is the process name we want to monitor 70 is to log only when the process is using over 70% of the CPU.
Check the logs at: /var/log/check_procs.log
The output should be like:
DATE | TOTAL CPU | CPU USAGE | Process details
Example:
03/12/14 17:11 |20.99|98| ProdPROXY-ProdProxyPA.tra
03/12/14 17:11 |20.99|100| ProdPROXY-ProdProxyPA.tra
Link to the full blog:
http://felipeferreira.net/?p=1453
It is also useful to have app_user information available to test whether the current user has the rights to kill/modify the running process. This information can be obtained along with the needed app_pid and app_cpu by using read eliminating the need for awk or any other 3rd party parser:
read app_user app_pid tmp_cpu stuff <<< \
$( ps aux | grep "$app_name" | grep -v "grep\|defunct\|${0##*/}" )
You can then get your app_cpu * 100 with:
app_cpu=$((${tmp_cpu%.*} * 100))
Note: Including defunct and ${0##*/} in grep -v prevents against multiple processes matching $app_name.
I use top to check some details. It provides a few more details like CPU time.
On Linux this would be:
top -b -n 1 | grep $app_name
On Mac, with its BSD version of top:
top -l 1 | grep $app_name

Resources