Need help using GeekTool with system_profiler and networksetup - terminal

Aloha everyone,
I have created a small bash shell script which I wanted to use with GeekTool, but I have experienced different results using the same script on my iMac (11,1) and my MacBook Pro (8,3). I'm pulling network data using both networksetup and system_profiler. What I have thus far are several calls to both, but would like to consolidate it to one call to each process creating variables to use in my script. Here is my script thus far:
# Get Ethernet and Wi-Fi information and display it for GeekTool
WiFi=$(networksetup -getairportnetwork en1 | awk '{print $4 " " $5 " " $6 " " $7 " " $8}')
WiFi_IP=$(networksetup -getinfo Wi-Fi | grep -v IPv6 | awk '/IP address/ {print $3}')
SubMask=$(networksetup -getinfo Wi-Fi | awk '/Subnet mask/ {print $3}')
S2N=$(system_profiler SPAirPortDataType | awk '/Noise/ {print $4 " " $5 " " $6 " " $7 " " $8}')
TRate=$(system_profiler SPAirPortDataType | awk '/Rate/ {print $3 " Mbps"}')
echo -e "\033[4;33m" AirPort
if [ "$WiFi_IP" = "" ];
then echo "Not connected to wireless AP."
else echo -e "Wi-Fi AP: " $WiFi "\nIP Address: " $WiFi_IP "\nSubnet Mask: " $SubMask "\nTransmit Rate: " $TRate
fi
EthIP=$(networksetup -getinfo Ethernet | grep -v IPv6 | awk '/IP address/ {print $3}')
EthSubMask=$(networksetup -getinfo Ethernet | grep -v IPv6 | awk '/Subnet mask/ {print $3}')
echo -e "\033[4;33m" "\nEthernet"
if [ "$EthIP" = "" ];
then echo "Not connected to wired network."
else echo -e "IP Address: " $EthIP "\nSubnet Mask: " $EthSubMask
fi
When I create a shell in GeekTool and enter the path to my script, everything works fine on my MacBook Pro, but on my iMac, GeekTool displays the results fine once, then upon the refresh (I had it set for 15s), the result disappear and never returns to the screen. While I know that what I have works, it makes too many calls to both processes and I would like to consolidate it to one call per process, extracting the desired information into a container such as an array from which I can access said desired information.
In other words, does anyone know how I can make just one call to networksetup to get all the information gathered from both -getairportnetwork en1 and -getinfo Wi-Fi as well as system_profiler SPAirPortDataType (which takes the longest - around 5-8 seconds each time)?

I modified my geek tool script a little bit and omitted the Signal to Noise ration thing. Here is what the new AirportStatus.sh file looks like:
#! /bin/bash
# echo -e "\033[0;30m" echo in black
# echo -e "\033[0;31m" echo in red
# echo -e "\033[0;32m" echo in green
# echo -e "\033[0;33m" echo in yellow
# echo -e "\033[0;34m" echo in blue
# echo -e "\033[0;35m" echo in magenta
# echo -e "\033[0;36m" echo in cyan
# echo -e "\033[0;37m" echo in white
# echo -e "\033[4;37m" echo in white underlined
echo -e "\033[4;33m" "Airport"
# Get Airport status from OS X
Status=$(ifconfig en1 | awk '/status/ {print $2}')
if [ "$Status" = "inactive" ];
then echo -e "\033[0;31m" "Status: " $Status "\nNot connected to wireless AP."
else echo -e "\033[0;32m" "Status" $Status
# Get wireless stats from OS X
WiFi=$(networksetup -getairportnetwork en1 | awk '{print $4 " " $5 " " $6 " " $7 " " $8}')
WiFi_IP=$(networksetup -getinfo Wi-Fi | grep -v IPv6 | awk '/IP address/ {print $3}')
SubMask=$(networksetup -getinfo Wi-Fi | awk '/Subnet mask/ {print $3}')
TRate=$(system_profiler SPAirPortDataType | awk '/Transmit/' | sed 's/[^0-9]//g')
# Get bytes in/out
# get the current number of bytes in and bytes out
myvar1=$(netstat -ib | grep -e en1 -m 1 | awk '{print $7}') # bytes in
myvar3=$(netstat -ib | grep -e en1 -m 1 | awk '{print $10}') # bytes out
#wait one second
sleep 1
# get the number of bytes in and out one second later
myvar2=$(netstat -ib | grep -e en1 -m 1 | awk '{print $7}') # bytes in again
myvar4=$(netstat -ib | grep -e en1 -m 1 | awk '{print $10}') # bytes out again
# find the difference between bytes in and out during that one second
subin=$(($myvar2 - $myvar1))
subout=$(($myvar4 - $myvar3))
# convert bytes to megabytes
mbin=$(echo "scale=2 ; $subin/1048576;" | bc)
mbout=$(echo "scale=2 ; $subout/1048576 ; " | bc)
usedMB=$(echo "scale=2 ; $mbin+$mbout ; " | bc)
AvailBW=$(echo "scale=2 ; $TRate-$usedMB ; " | bc)
echo -e "\033[0;37m" "Wi-Fi AP: " "\033[0;36m" $WiFi "\033[0;37m" "\nIP Address: " "\033[0;36m" $WiFi_IP $3 "\033[0;37m" "\nSubnet Mask: " "\033[0;36m" $SubMask "\033[0;37m" "\nTransmit Rate: " "\033[0;36m" $TRate " Mbps\n" "\033[0;37m" "Data In: " "\033[0;36m" $mbin "Mbps" "\n" "\033[0;37m" "Data Out: " "\033[0;36m" $mbout "Mbps\n" "\033[0;37m" "Available Bandwidth: " "\033[0;36m" $AvailBW " Mbps"
fi
I checked the for active status, assuming that it was initially inactive. If not, then I put in the massive if statement where all the variables are initialized and the computations are done. There is only one call to system_profiler, the one that retrieves the transmission rate, but I wanted to see the "line speed" of my wireless network. This works, not as well as I would have liked, but it was still a good exercise in learning a little bit about where to get information on my Mac, and how to use both awk and see. I still have a lot to learn, but this has been exciting thus far.

Related

Variable works outside function, inside function give syntax error

I've been trying to get this function to work. I'm on a 17" MacBook Pro Early 2011. Setting all the variables under "else" work great if you run them separately, they also echo properly. For some reason when I put them in the function… I get a syntax error on line 12 and
battery ()
{
BATTERYISPRESENT=`ioreg -l | grep Cycle`
if [[ $BATTERYISPRESENT != *'Cycle' ]]
then
echo "No Battery Present, Probably a desktop Mac."
else
BATTERYCYCLES=`system_profiler SPPowerDataType | grep "Cycle Count" | awk '{print $3}'`
BATTCURRCAP=`pmset -g batt | sed -n '2 p' | awk '{ print $2 }' | sed 's/;//g'`
BATTERYCHARGESTATUS=`system_profiler SPPowerDataType | grep "Charging" | awk '{ print $2 }'`
BATTERYISCHARGING=`system_profiler SPPowerDataType | grep -A 4 "AC Charger Information" | grep "Connected: " | awk '{ print $2 }'`
CHARGERISCONNECTED=`system_profiler SPPowerDataType | grep -A 4 "AC Charger Information" | grep "Connected: " | awk '{ print $2 }'`
echo $BATTERYCYCLES
echo $BATTCURRCAP
echo $BATTERYISCHARGING
echo $CHARGERISCONNECTED
}
The output reads:
line 12: unexpected EOF while looking for matching ``'
line 18: syntax error: unexpected end of file
Any assistance would be greatly appreciated.
A fi upon you — you're missing the fi at the end of the else.

how to create multi user paramerter in zabbix from a script

This is a shell script return 2 values one for packet loss percentage and another for True or False :
SERVER_IP=$1
checkip=`ping -c 2 -W 2 $SERVER_IP | grep "packet loss" | cut -d " " -f 6 | cut -d "%" -f1`
test1=$?
echo $checkip
if [ $test1 -eq 0 ]; then
echo "1"
else
echo "0"
fi
in zabbix when you create an item you enter only one parameter with value but i have 2 values one packet loss and second for ping result (0 and 1)
how can i create two items 1 for packet lost percentage and second for ping health check with only this script? i dont want to create another one
Thanks to Andre
try this script this will guide you to what exactly you want :
#!/bin/bash
case $1 in
packetloss) ping -c2 -W1 -q 8.8.8.8 | grep -oP '\d+(?=% packet loss)' ;;
timeout) ping -c2 -q 8.8.8.8 | grep 'time' | awk -F',' '{ print$4}' | awk '{print $2}' | cut -c 1-4 ;;
*) echo "Use: packetloss , timeout";;
esac
try (im in zsh):
zabbix_agentd -t ping.loss\[timeout\]
ping.loss[timeout] [t|1000]
or in zabbix server use get ( im also in zsh here too):
zabbix_get -s 172.20.4.49 -k ping.loss\[timeout\]
1001
now create items with these keys.
UserParameter=key[*],/path_of_script.sh $1
At the GUI:
Key: key[Server_IP]
Another example:
UserParameter=general[*],/usr/local/etc/scripts/general.sh $1 $2 $3 $4 $5 $6 $7 $8 $9
$ cat general.sh
#!/bin/bash
case $1 in
ddate) ddate;;
minute) echo "`date +%M`%2" | bc;;
files) ls -l $2 | grep ^- | wc -l;;
size.dir) du -s $2 | cut -f1;;
script) /bin/bash /usr/local/etc/scripts/script.sh;;
*) echo "Use: ddate, minute, files <parameters>, size.dir <parameters> or script";;
esac
$ zabbix_get -s Server_IP -k general[minute]

A generic script for checking the health of application

I have written one shell script (Health_app.sh) which checks the health of the application. And for that it takes the name of the processes from App_Details file and checks for PID (whether it is running or not) and if it is not running and grep for that process in logs (field 3) and send email to the email id mentioned in the App_Details file (field 4).
App_Details is having records like:
process_Name|Process_description|logfile_path|email
abcd|main proceess to invoke the
dataready|/123/456/log|vikas#yahoo.com
pqrs|2nd
process..........................|/123/456/log|vikas#yahoo.com
Here is how my script looks like:
export App_Details=/home/123/sanity/App_Details
while read line
do
export procname=$(echo $line | cut -d " " -f1)
export PROCDES=$(echo $line | cut -d " " -f2)
#if ps -ef |grep [`echo $procname|awk '{print substr($0,1,1)}'`] [`echo $procname|awk '{print substr($0,2,length($0))}'`]> /dev/null
if ps -ef |grep -q [`echo $procname|awk '{print substr($0,1,1)}'`] `echo $procname|awk '{print substr($0,2,length($0))}'`
then
export part1=[`echo $procname|awk '{print substr($0,1,1)}'`]
export part2=`echo $procname|awk '{print substr($0,2,length($0))}'`
export PROCID=`ps -ef |grep $part1$part2|awk -F ' ' '{print $2}'`
else
export PROCID="OFFLINE"
trace_path=$(echo $line | cut -d " " -f3)
export mail=$(echo $line | cut -d " " -f4)
file_name=`ls -rt $trace_path/$procname*.trc 2>/dev/null | tail -1`
#export PROCDES=$(echo `tail -10 $file_name`)
(echo `tail -10 $file_name`) >> send.txt
mailx -s "Please find the alerts for your application OFFLINE services" vikas#domain.com < send.txt
fi
echo $PROCID|awk '{ printf("%-20s", $0)}'
echo $procname|awk '{ printf("%-20s", $0)}'
echo $PROCDES|awk '{ printf("%-20s\n", $0)}'
done<$App_Details
Now the issue is that grep -q is illegal for solaris and it is not working in solaris server.

Shell Scripting command not found Error

I'm new to programming with shell and want to ask what is wrong with my code?
#!/bin/bash
#DHT11
SCRIPT="/var/www/ErnestynoFailai/scripts/DHT 11 4"
#DHT22
#SCRIPT="/root/to/folder/DHT 22 4"
#AM2302
#SCRIPT="/root/to/folder/DHT 2302 4"
HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`
#-a = AND = &&
while [ $HUMIDITY=="" -a $TEMPRATURE=="" ]
do
$HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
$TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`
done
echo "$HUMIDITY"
echo "$TEMPRATURE"
I'm getting:
line 14 or 15 =26: or =: command not found...
There are two problems:
These lines are not returning anything, or at least a string:
HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`
This is causing =: command not found errors.
Your while condition needs to be
while [[ $HUMIDITY == "" && $TEMPRATURE == "" ]]
Finally, while not causing problems, TEMPERATURE is misspelled, which might cause you grief later on.
Variables have to be assigned without leading $:
HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`

Bash - Memory usage

I have a problem that I can't solve, so I've come to you.
I need to write a program that will read all processes and a program must sort them by users and for each user it must display how much of a memory is used.
For example:
user1: 120MB
user2: 300MB
user3: 50MB
total: 470MB
I was thinking to do this with ps aux command and then get out pid and user with awk command. Then with pmap I just need to get total memory usage of a process.
it's just a little update, users are automatically selected
#!/bin/bash
function mem_per_user {
# take username as only parameter
local user=$1
# get all pid's of a specific user
# you may elaborate the if statement in awk obey your own rules
pids=`ps aux | awk -v username=$user '{if ($1 == username) {print $2}}'`
local totalmem=0
for pid in $pids
do
mem=`pmap $pid | tail -1 | \
awk '{pos = match($2, /([0-9]*)K/, mem); if (pos > 0) print mem[1]}'`
# when variable properly set
if [ ! -z $mem ]
then
totalmem=$(( totalmem + $mem))
fi
done
echo $totalmem
}
total_mem=0
for username in `ps aux | awk '{ print $1 }' | tail -n +2 | sort | uniq`
do
per_user_memory=0
per_user_memory=$(mem_per_user $username)
if [ "$per_user_memory" -gt 0 ]
then
total_mem=$(( $total_mem + $per_user_memory))
echo "$username: $per_user_memory KB"
fi
done
echo "Total: $total_mem KB"
Try this script, which may solve your problem:
#!/bin/bash
function mem_per_user {
# take username as only parameter
local user=$1
# get all pid's of a specific user
# you may elaborate the if statement in awk obey your own rules
pids=`ps aux | awk -v username=$user '{if ($1 == username) {print $2}}'`
local totalmem=0
for pid in $pids
do
mem=`pmap $pid | tail -1 | \
awk '{pos = match($2, /([0-9]*)K/, mem); if (pos > 0) print mem[1]}'`
# when variable properly set
if [ ! -z $mem ]
then
totalmem=$(( totalmem + $mem))
fi
done
echo $totalmem
}
total_mem=0
for i in `seq 1 $#`
do
per_user_memory=0
eval username=\$$i
per_user_memory=$(mem_per_user $username)
total_mem=$(( $total_mem + $per_user_memory))
echo "$username: $per_user_memory KB"
done
echo "Total: $total_mem KB"
Best regards!
You can access the shell commands in python using the subprocess module. It allows you to spawn subprocesses and connect to the out/in/error. You can execute the ps -aux command and parse the output in python.
check out the docs here
Here is my version. I think that Tim's version is not working correctly, the values in KB are too large. I think the RSS column from pmap -x command should be used to give more accurate value. But do note that you can't always get correct values because processes can share memmory. Read this A way to determine a process's "real" memory usage, i.e. private dirty RSS?
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "WARNING: you have to run as root if you want to see all users"
fi
echo "Printing only users that current memmory usage > 0 Kilobytes "
all=0
for username in `ps aux | awk '{ print $1 }' | tail -n +2 | sort | uniq`
do
pids=`ps aux | grep $username | awk -F" " '{print $2}'`
total_memory=0
for pid in $pids
do
process_mem=`pmap -x $pid | tail -1 | awk -F" " '{print $4}'`
if [ ! -z $process_mem ]
then #don't try to add if string has no length
total_memory=$((total_memory+$process_mem))
fi
done
#print only those that use any memmory
if [ $total_memory -gt 0 ]
then
total_memory=$((total_memory/(1024)))
echo "$username : $total_memory MB"
all=$((all+$total_memory))
fi
done
echo "----------------------------------------"
echo "Total: $all MB"
echo "WARNING: Use at your own risk"

Resources