I am trying to get the total disk usage of my machine. Below is the script code:
#!/bin/sh
totalUsage=0
diskUse(){
df -H | grep -vE '^Filesystem|cdrom' | awk '{ print $5 " " $1 }' | while read output;
do
diskUsage=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
totalUsage=$((totalUsage+diskUsage))
done
}
diskUse
echo $totalUsage
While totalUsage is a global variable, I have tried to sum the individual disk usage to totalUsage in the line:
totalUsage=$((totalUsage+diskUsage))
An echo of totalUsage between do and done shows the correct value,
but when I try to echo it after my call diskUse, it stills prints a 0
Can you please help me, what is wrong here?
The variable totalUsage in a sub-shell doesn't change the value in the parent shell.
Since you tagged bash, you can use here string to modify your loop:
#!/bin/bash
totalUsage=0
diskUse(){
while read output;
do
diskUsage=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
totalUsage=$((totalUsage+diskUsage))
done <<<"$(df -H | grep -vE '^Filesystem|cdrom' | awk '{ print $5 " " $1 }')"
}
diskUse
echo $totalUsage
I suggest to insert
shopt -s lastpipe
as new line after
#!/bin/bash
From man bash:
lastpipe: If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.
Related
I am getting an issue where if I call this function below, I get the error line 89: syntax error at line 117: 'df' unexpected.
If I take the code out of the function it works fine.
Is there any reason for the error above?
This is a bash script on RHEL.
function testr{
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read output;
do
usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1)
partition=$(echo $output | awk '{ print $2 }')
(.. Sends alert via mail after)
done
}
Maybe a little easier to read this way?
testr_zsh () {
# This (only) works with zsh.
for usep partition in $( df -H | awk 'NR>1 && !/tmpfs|cdrom/{print $5,$1}' | sed -n '/%/s/%//p' )
do
echo "\$usep: $usep, \$partition: $partition"
done
}
testr () {
for fs in $( df -H | awk 'NR>1 && !/tmpfs|cdrom/{print $5"|"$1}' | sed -n '/%/s/%//p' )
do
usep="$(echo "${fs}" | sed 's/|.*//' )"
partition="$(echo "${fs}" | sed 's/.*|//' )"
echo "\$usep: $usep, \$partition: $partition"
done
}
On my computer not all lines that pass through the awk filter have % in them hence adding the sed filter. zsh allows two vars in the for loop which is pretty slick.
This question already has an answer here:
Executing ssh command in a bash shell script within a loop [duplicate]
(1 answer)
Closed 9 years ago.
I am Oracle DBA and i am doing some scripting to check if database is live or not on our large number of servers.
I am trying to set value to variable in ssh -X e.g
[oracle#proddb02]$ DB_STAT=`ssh -X proaddb01 'ps -ef | grep pmon | grep -v grep' | awk '{ print $8 }'`
[oracle#proddb02]$ echo $DB_STAT
ora_pmon_pconn01
Above example works perfectly but as i am using ssh command i cannot loop using while as it exit at the first line file which include list of the servers.
so i have to add /dev/null to the command so that it should not exit the loop. but this does not set the variable value.
When i echo the variable it gives nothing.
[oracle#proddb02]$ DB_STAT=`ssh -X proddb01 'ps -ef | grep pmon | grep -v grep' | awk '{ print $8 }'</dev/null`
[oracle#proddb02]$ echo $DB_STAT
[oracle#proddb02]$ echo $DB_STAT
The loop code is
[oracle#proddb02]$cat test.sh
while read line
do
INST_VAR=`echo $line | awk '{ print $1 }'`
HOST_VAR=`echo $line | awk '{ print $2 }'`
SERVER_NAME=$HOST_VAR
INSTANCE_NAME=$INST_VAR
DB_STAT=`ssh -X proaddb01 'ps -ef | grep pmon | grep -v grep' | awk '{ print $8 }'`
echo $DB_STAT
done < host_list.lst
Any help would be much appreciated.
Just do:
DB_STAT=`ssh -X proaddb01 "ps -ef | awk '/[p]mon/'{ print $8 }"`
Here you use:
// to filter the input stream (like grep but witj awk);
the trick with [p]grep to exclude the same line from ps (because [p]grep string will not be found with [p]grep template).
I have a command I'm using to get the hostname.localdomain:
dig axfr #dc1.localdomain.com localdomain.com | grep -i Lawler | awk '{ getline ; $1=substr($1,1,length($1)-1); print $1 ; exit }'
This nicely returns a result like:
michael.lawler.localdomain.com
I'd like to further use that result as a variable in a Bash script.
It seems I'm having trouble getting past the first pipe.
If I VAR="dig axfr #dc1.localdomain.com localdomain.com | grep -i Lawler | awk '{ getline ; $1=substr($1,1,length($1)-1); print $1 ; exit }'"
...I get back the entire zone transfer. I've also tried many minor changes, adding $ before the dig command, without quotes, but nothing seems to work. How can I fix this?
VAR=$( dig axfr #dc1.localdomain.com localdomain.com |
grep -i Lawler |
awk '{ getline ; $1=substr($1,1,length($1)-1); print $1 ; exit }' )
Use backtics instead of quotes:
VAR=`dig axfr #dc1.localdomain.com localdomain.com | grep -i Lawler | awk '{ getline ; $1=substr($1,1,length($1)-1); print $1 ; exit }'`
Backtics actually mean "run whatever is in here and return standard out as the expression's value", but quotes don't do that.
My bash script is:
output=$(curl -s http://www.espncricinfo.com/england-v-south-africa-2012/engine/current/match/534225.html | sed -nr 's/.*<title>(.*?)<\/title>.*/\1/p')
score=echo"$output" | awk '{print $1}'
echo $score
The above script prints just a newline in my console whereas my required output is
$ curl -s http://www.espncricinfo.com/england-v-south-africa-2012/engine/current/match/534225.html | sed -nr 's/.*<title>(.*
?)<\/title>.*/\1/p' | awk '{print $1}'
SA
So, why am I not getting the output from my bash script whereas it works fine in terminal am I using echo"$output" in the wrong way.
#!/bin/bash
output=$(curl -s http://www.espncricinfo.com/england-v-south-africa-2012/engine/current/match/534225.html | sed -nr 's/.*<title>(.*?)<\/title>.*/\1/p')
score=$( echo "$output" | awk '{ print $1 }' )
echo "$score"
Score variable was probably empty, since your syntax was wrong.
I'm trying to pass a variable to nawk in a bash script, but it's not actually printing the $commentValue variable's contents. Everything works great, except the last part of the printf statement. Thanks!
echo -n "Service Name: "
read serviceName
echo -n "Comment: "
read commentValue
for check in $(grep "CURRENT SERVICE STATE" $nagiosLog |grep -w "$serviceName" | nawk -F": " '{print $2}' |sort -u ) ; do
echo $check | nawk -F";" -v now=$now '{ printf( "[%u]=ACKNOWLEDGE_SVC_PROBLEM;"$1";"$2";2;1;0;admin;$commentValue"\n", now)}' >> $nagiosCommand
done
$commentValue is inside an invocation to nawk, so it is considered as a variable in nawk, not a variable in bash. Since you do not have such a variable in nawk, you won't get anything there. You should first pass the variable "inside" nawk using the -v switch just like you did for the now variable; i.e.:
... | nawk -F";" -v now=$now -v "commentValue=$commentValue"
Note the quotes - they are required in case $commentValue contains whitespace.