LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   echo not being execute under if in bash script (https://www.linuxquestions.org/questions/linux-newbie-8/echo-not-being-execute-under-if-in-bash-script-4175449673/)

Rohit_4739 02-11-2013 10:02 AM

echo not being execute under if in bash script
 
Hi Friends,

I am writing the following shell script but for some reason i am not able to get one particular thing as desired. I am digging on this from last 3-4 hours but i am not able to understand. Please note i am pretty new to scripting so if i have made some basic mistake or missed some very basic thing forgive me for that and do correct me. below is my script


Code:

#!/bin/bash

clear
echo -e "Do you want to see Swap Usage(1) or both Memory and Swap Usage(2) ?"
read VAL
 
for i in /proc/*
do
 
        if [ -e $i/smaps ]
        then   
                COM=`cat $i/cmdline`
                PID=`basename $i`
                if [ $VAL = 1 ]
                        then   
echo "test"   
SR="6"
echo "$SR"
                        awk  -v CMD="$COM" -v J="$PID" '/Rss/ {rss +=$2}; END { if (rss > 0 )print "PID: "J"  Process_Name  " CMD "  Rss= " rss/1024"M"}' $i/smaps
                else
                        echo "fail"
                fi             
        fi             
#done
done 2> /dev/null | sort -nr -k  6| head -10

Output for above script is

Code:

Do you want to see Swap Usage(1) or both Memory and Swap Usage(2) ?
1
PID: 4130  Process_Name  /usr/bin/Xorg:0-br-audit0-auth/var/gdm/:0.Xauth-nolistentcpvt7  Swap= 46.5938M
PID: 4334  Process_Name  /usr/bin/python-tt/usr/bin/puplet  Swap= 20.3008M
PID: 4293  Process_Name  /usr/lib/vmware-tools/sbin32/vmtoolsd-nvmusr--blockFd3  Swap= 17.9844M
PID: 4432  Process_Name  gnome-terminal  Swap= 16.8359M
PID: 4272  Process_Name  nautilus--no-default-window--sm-client-iddefault3  Swap= 14.8984M
PID: 29656  Process_Name  bash  Swap= 13.4688M
PID: 4270  Process_Name  gnome-panel--sm-client-iddefault2  Swap= 11.6562M
PID: 4393  Process_Name  /usr/libexec/mixer_applet2--oaf-activate-iid=OAFIID:GNOME_MixerApplet_Factory--oaf-ior-fd=29  Swap= 11.0352M
PID: 4365  Process_Name  /usr/libexec/wnck-applet--oaf-activate-iid=OAFIID:GNOME_Wncklet_Factory--oaf-ior-fd=19  Swap= 10.2773M
PID: 3402  Process_Name  /usr/sbin/restorecond  Swap= 10.1719M

Here is if i make little change to this

Code:

#!/bin/bash
 
clear
echo -e "Do you want to see Swap Usage(1) or both Memory and Swap Usage(2) ?"
read VAL
 
for i in /proc/*
do
 
        if [ -e $i/smaps ]
        then   
                COM=`cat $i/cmdline`
                PID=`basename $i`
                if [ $VAL = 1 ]
                        then   
                                                echo "test" 
                                                SR="6"
                                                echo "$SR"
                        awk  -v CMD="$COM" -v J="$PID" '/Rss/ {rss +=$2}; END { if (rss > 0 )print "PID: "J"  Process_Name  " CMD "  Rss= " rss/1024"M"}' $i/smaps
                else
                        echo "fail"
                fi             
        fi             
done 2> /dev/null | sort -nr -k  `echo SR`| head -10

Below is the output

Code:

Do you want to see Swap Usage(1) or both Memory and Swap Usage(2) ?
1
sort: option requires an argument -- k
Try `sort --help' for more information.


I hope by now you should have understood what is the unexpected result i am talking about, in both the cases "echo" command above "awk" didn't execute, the behavior which i am not able to understand.

However below is a little variation of the same script where the whole thing seems to works just fine.

Code:

#!/bin/bash

clear
echo -e "\n Do you want the output sorted by Memory Usage(M) or Swap Usage(S)?"
read SRT

if [ $SRT = "M" ] || [ $SRT = "m" ]
then
        SRT="6"
elif [ $SRT = "S" ] || [ $SRT = "s" ]
then
        SRT="8"
else
        echo -e "You enetered invalid response; default sort would be Memory based !! \n\n"
        SRT="6"
fi
for i in /proc/*
do 
COM=`cat $i/cmdline`
PID=`basename $i`
awk  -v CMD="$COM" -v J="$PID" '/Size/ {mem +=$2} /Swap/ {swap +=$2}; END { if (mem > 0)print "PID: "J"  Process_Name  " CMD "  Memory= " mem/1024 "M" "  Swap= " swap/1024"M"}' $i/smaps
done 2> /dev/null | sort -nr -k `echo $SRT`| head -10

And here is the output

Code:

Do you want the output sorted by Memory Usage(M) or Swap Usage(S)?
s
PID: 3830  Process_Name  sendmail: accepting connections  Memory= 9.01953M  Swap= 0M
PID: 3958  Process_Name  avahi-daemon: chroot helper  Memory= 2.53906M  Swap= 0M
PID: 3957  Process_Name  avahi-daemon: running [localhost.local]  Memory= 2.53906M  Swap= 0M
PID: 3663  Process_Name  hald-addon-storage: polling /dev/hdc  Memory= 1.92969M  Swap= 0M
PID: self  Process_Name  cat/proc/self/cmdline  Memory= 4.12891M  Swap= 0M
PID: 592  Process_Name  /sbin/udevd-d  Memory= 2.84766M  Swap= 0M
PID: 5729  Process_Name  bash  Memory= 4.5625M  Swap= 0M
PID: 4462  Process_Name  gnome-screensaver  Memory= 16.0469M  Swap= 0M
PID: 4447  Process_Name  bash  Memory= 4.5625M  Swap= 0M
PID: 4446  Process_Name  gnome-pty-helper  Memory= 2.42578M  Swap= 0M


Any help is highly appreciated.

shivaa 02-11-2013 10:23 AM

Quote:

if [ $VAL = 1 ]
Instead of this, use numaric comparision, (check man test):
Code:

if [ $VAL -eq 1 ]
Also once add debugging in the script, to check where the problem is:
Code:

#!/bin/bash
set -xv


Rohit_4739 02-11-2013 10:26 AM

Code:

if [ $VAL -eq 1 ]
if that is the problem then how awk executes below the same if statement ? And to rule out any possibility i tried it the one you just mentioned but it didn't work; same result as before no change at all !!

shivaa 02-11-2013 11:31 AM

I didn't mention that if condition is wrong, but I mentioned that you should use correct expression.

Well, problem is with following statement:
Code:

done 2> /dev/null | sort -nr -k  6| head -10
You're sorting script output on basis on 6th column of output, but there will be only one column in output of following lines while printing, so output do not print test and 6.
Code:

echo "test"   
SR="6"
echo "$SR

So just remove the sort and head part as follow, and try again:
Code:

#!/bin/bash
clear
echo -e "Do you want to see Swap Usage(1) or both Memory and Swap Usage(2) ?"
read VAL

for i in /proc/*
do
if [ -e $i/smaps ]
then   
COM=`cat $i/cmdline`
PID=`basename $i`
if [ $VAL -eq 1 ]
then   
echo "test"   
SR="6"
echo "$SR"
awk  -v CMD="$COM" -v J="$PID" '/Rss/ {rss +=$2}; END { if (rss > 0 )print "PID: "J"  Process_Name  " CMD "  Rss= " rss/1024"M"}' $i/smaps 2> /dev/null
else
echo "fail"
fi             
fi             
done


Rohit_4739 02-11-2013 11:36 AM

Quote:

Originally Posted by shivaa (Post 4889228)
I didn't mention that if condition is wrong, but I mentioned that you should use correct expression.

Well, problem is with following statement:
Code:

done 2> /dev/null | sort -nr -k  6| head -10
You're sorting script output on basis on 6th column of output, but there will be only one column in output of following lines while printing, so output do not print test and 6.
Code:

echo "test"   
SR="6"
echo "$SR

So remove the sort and head part as follow try again:
Code:

#!/bin/bash
clear
echo -e "Do you want to see Swap Usage(1) or both Memory and Swap Usage(2) ?"
read VAL

for i in /proc/*
do
if [ -e $i/smaps ]
then   
COM=`cat $i/cmdline`
PID=`basename $i`
if [ $VAL -eq 1 ]
then   
echo "test"   
SR="6"
echo "$SR"
awk  -v CMD="$COM" -v J="$PID" '/Rss/ {rss +=$2}; END { if (rss > 0 )print "PID: "J"  Process_Name  " CMD "  Rss= " rss/1024"M"}' $i/smaps 2> /dev/null
else
echo "fail"
fi             
fi             
done


Thanks !!, ok agreed with this explanation but i still see variable SR not getting set, i have requirement of sort and i want to use value of this $SR in the sort expression but that doesn't seem to get set at all.

shivaa 02-11-2013 11:47 AM

I can't see the use of SR variable in your script. You have just declared and printed it, but not used.
Code:

SR="6"
echo "$SR"

If you have to do sorting, then better put the output in some temporary file and then do sorting, as:

Code:

# echo "test"    # Comment it out, don't print
SR=6
# echo "$SR"    # Comment it out, don't print
awk  -v CMD="$COM" -v J="$PID" '/Rss/ {rss +=$2}; END { if (rss > 0 )print "PID: "J"  Process_Name  " CMD "  Rss= " rss/1024"M"}' $i/smaps > /tmp/output.txt 2>/dev/null

sort -nr -k $SR /tmp/output.txt | head -10  # Add this line


grail 02-11-2013 12:07 PM

Well the usual story would probably be, why reinvent the wheel as something like top probably already does this for you.

However, the answer to the original question is, your first choice to use SR in the output from the for loop does not work for 2 reasons:

1. If you look at the example you showed where it works just fine for the SRT value, you will notice it is set outside the loop so the value exists outside the for loop

2. When you called it you did not place the $ sign in front of the variable name and hence it should just echo the letters "SR"

Another nit pick would be that the use of echo in this instance is redundant as the variable can be used as is, hence, assuming you set it correctly you could do:
Code:

done 2> /dev/null | sort -nr -k  `echo SR`| head -10

# becomes

done 2> /dev/null | sort -nr -k $SR | head -10


Rohit_4739 02-11-2013 09:43 PM

Thanks Grail for the explaination. I have some questions here, please forgive me if they sound silly but considering i am pretty new to scripting i hope you would answer them gentely :)

Quote:

1. If you look at the example you showed where it works just fine for the SRT value, you will notice it is set outside the loop so the value exists outside the for loop
So does that mean we can't declare a variable inside loop in scripting unlike a programming language. Or if we have to set the value of a variable like SR in my case, how would i do it; like say i want to set value of a variable inside a loop.

Meanwhile i am modifying my code accordingly. Thanks alot

grail 02-12-2013 02:34 AM

The issue you face here is that the variable does not survive the pipes you are passing through. I would also point out that in this current example it
does not seem to serve any purpose to set this variable inside the loop.

Variables can exist and be updated in a loop and be used outside but as indicated, changing this one inside serves no real purpose and I see no reason why you would not simply
set it outside.

You may also wish to look at ** expansion or using find to feed a while loop as opposed to the current for loop scenario.

Rohit_4739 02-12-2013 05:55 AM

Thanks all for all your reposnses. I finally solved my issue using fuctions and it worked just fine. Appreciate all your inputs.


All times are GMT -5. The time now is 10:41 AM.