LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 05-02-2013, 10:29 AM   #1
keif
Member
 
Registered: Apr 2013
Posts: 80

Rep: Reputation: Disabled
awk not working when setting command as variable


Hello everyone.

The problem I have today is setting a variable for a command.

In the "get_percentage" variable I'm trying to set, for some reason the awk section is getting ignored when I run the script:

Code:
#!/bin/sh
for STORE in lf0005
do
get_percentage="df | grep usr1 | awk '{print $4}'"
        touch /home/techs/lf-df-usr1-check
        echo $STORE >> /home/techs/lf-df-usr1-check
        ssh root@$STORE $get_percentage >> /home/techs/lf-df-usr1-check
        echo ========================------------======================= >> /home/techs/lf-df-usr1-check
done
mail -s "Lowes Disk space for usr1" myemail@hostname < /home/techs/lf-df-usr1-check
rm -f /home/techs/lf-df-usr1-check
Here is the output that results in ignoring the awk command:

Code:
lf0005
/dev/mapper/SYSTEM-usr1
                       2064208    704816   1254536  36% /usr1
========================------------=======================

But when I run the script without assigning the variable, the out put is fine:

Code:
#!/bin/sh
for STORE in lf0005
do
        touch /home/techs/lf-df-usr1-check
        echo $STORE >> /home/techs/lf-df-usr1-check
        ssh root@$STORE df | grep usr1 | awk '{print $4}' >> /home/techs/lf-df-usr1-check
        echo ========================------------======================= >> /home/techs/lf-df-usr1-check
done
mail -s "Lowes Disk space for usr1" myemail@hostname < /home/techs/lf-df-usr1-check
rm -f /home/techs/lf-df-usr1-check
Here is the output that shows what the script is supposed to do when working correctly:

Code:
lf0005

36%
========================------------=======================
I suspect that the dollar sign after the awk command is the cause of the problem, but I don't know for sure (Nor do I know how to get around that).

Thanks for checking.
 
Old 05-02-2013, 10:48 AM   #2
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,489

Rep: Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891
Actually you might wish to look up your scripting reference on how to set the output of a command to a variable in a shell script. I'll give you a tip it is not "".

I presume you also have a reason for using sh instead of something like bash.

Note: My bad, you can ignore above as I did not read the question properly ... sorry

Last edited by grail; 05-02-2013 at 07:41 PM.
 
Old 05-02-2013, 12:31 PM   #3
smallpond
Senior Member
 
Registered: Feb 2011
Location: Massachusetts, USA
Distribution: Fedora
Posts: 1,487

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
In the variable case you are passing the whole pipeline through ssh so running grep and awk as root on $STORE.
In the non-variable case you are running grep and awk locally on the df output you get back from ssh.

Also, df can be funny when it wraps long lines. It might be better to use the output of tune2fs -l.
 
Old 05-03-2013, 12:34 AM   #4
cfajohnson
LQ Newbie
 
Registered: Aug 2012
Posts: 13

Rep: Reputation: Disabled

Use the -P option:
Code:
get_percentage="df -P  | grep usr1 | awk '{print $4}'"
 
Old 05-03-2013, 01:52 AM   #5
pan64
Senior Member
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 4,645

Rep: Reputation: 1250Reputation: 1250Reputation: 1250Reputation: 1250Reputation: 1250Reputation: 1250Reputation: 1250Reputation: 1250Reputation: 1250
yes, grail told you, in this line:
get_percentage="df | grep usr1 | awk '{print $4}'"
$4 will be evaluated, you would try '. And also avoid using grep <pattern> | awk <command>, you can solve it with a single awk:
awk '/usr1/ {print $4}'
furthermore a pipe in a variable will not work as pipe, you can try the following:
Code:
$ echo asdf | grep a
asdf
$ p='|'
$ echo asdf $p grep a
asdf | grep a
for me $5 should be used for % or $(NF-1)
Finally something like this may work:
Code:
get_percentage='awk /usr1/{print$(NF-1)}'
ssh root@$STORE df | $get_percentage
although I do not like this solution
 
Old 05-03-2013, 02:59 AM   #6
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 651

Rep: Reputation: 269Reputation: 269Reputation: 269
Quote:
Originally Posted by pan64 View Post
Code:
get_percentage='awk /usr1/{print$(NF-1)}'
ssh root@$STORE df | $get_percentage
although I do not like this solution
Perhaps putting it in a function instead would be slightly better:

Code:
get_percentage() { awk '/usr1/{print$(NF-1)}'; }
ssh root@$STORE df | get_percentage
 
Old 05-06-2013, 07:54 AM   #7
keif
Member
 
Registered: Apr 2013
Posts: 80

Original Poster
Rep: Reputation: Disabled
Thank you everyone for the replies. I learned a lot in this thread.

I ended up getting an output that worked for what I needed to accomplish:

Code:
#!/bin/sh
for STORE in `grep ^lf0 /etc/storelist | awk '{print $1}'`
do
        touch /home/techs/lf-df-usr1-check
        echo $STORE >> /home/techs/lf-df-usr1-check
get_percentage='awk /usr1/{print$(NF-1)}'
ssh root@$STORE df | $get_percentage >> /home/techs/lf-df-usr1-check
        echo ========================------------======================= >> /home/techs/lf-df-usr1-check
done
mail -s "usr1 disk space for Lowes stores" myemail@hostname < /home/techs/lf-df-usr1-check
rm -f /home/techs/lf-df-usr1-check
Thanks everyone.

Keif
 
Old 05-06-2013, 11:28 AM   #8
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,489

Rep: Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891Reputation: 1891
As with your get_percentage awk, your awk feeding the loop does also not require the use of grep.
 
Old 05-07-2013, 02:13 PM   #9
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947Reputation: 1947
Code:
#!/bin/sh
If you want to use bash (and I recommend it if at all possible), then your shebang needs to be #!/bin/bash. /bin/sh is the posix-compatible script interpreter, which is much more limited.

Code:
for STORE in `grep ^lf0 /etc/storelist | awk '{print $1}'`
do
DO NOT READ LINES WITH FOR! When parsing the output of a command or file, always use a while+read loop. read also has a benefit of being able to split lines for you, eliminating the need for awk.

Useless Use Of Grep too, and $(..) is highly recommended over `..`.

Code:
#revised
while read -r STORE _ ; do
    ....
done < <( grep '^lf0' /etc/storelist )

Code:
touch /home/techs/lf-df-usr1-check
Good coding practice says you shouldn't hard-code filenames and other data in the script. Set the ouput file in a variable at the top of script and use that.

Code:
#revised
outfile='/home/techs/lf-df-usr1-check'
touch "$outfile"
Your "/etc/storelist" file should be treated the same way.

Code:
echo $STORE >> /home/techs/lf-df-usr1-check
get_percentage='awk /usr1/{print$(NF-1)}'
ssh root@$STORE df | $get_percentage >> /home/techs/lf-df-usr1-check
echo ========================------------======================= >> /home/techs/lf-df-usr1-check

Now you appear to be using millgates function suggestion without actually defining the function. It all depends on whether you want to do the awk filtering on the remote machine or the local one. If you want to do it locally, use the function. If remotely, then try storing the whole command in the variable.

With a bit of reorganizing and command grouping, this can be made cleaner as well. And don't forget to quote all of your variables!

Code:
#revised

#for sending the whole command to the remote server:
get_percentage='df | awk /usr1/{ print $NF-1 }'

{
    echo "$STORE"
    ssh "root@$STORE" "$get_percentage"
    echo ========================------------======================= 
} >> "$outfile"
Code:
mail -s "usr1 disk space for Lowes stores" myemail@hostname < /home/techs/lf-df-usr1-check
rm -f /home/techs/lf-df-usr1-check
Again, use variables to define data separately.

Code:
#revised
mailaddress='myemail@hostname'  #put this at the top of the script.

mail -s "usr1 disk space for Lowes stores" $mailaddress" < "$outfile"
rm -f "$outfile"
You could probably even just stick the mail command at the end of the loop to capture it's entire output, and skip the intermediate file.

Code:
mailaddress='myemail@hostname'
subline='usr1 disk space for Lowes stores'
infile='/etc/storelist'

while read -r STORE _ ; do
    ....
done < <( grep '^lf0' "$infile" ) | mail -s "$subline" $mailaddress"
 
2 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Awk: How to pass/store a command output in variable? shivaa Linux - Newbie 8 01-05-2013 12:30 PM
[SOLVED] How-to include a variable's name in a regex in awk to spot command names in absolute paths Didier Spaier Programming 3 09-14-2012 04:05 AM
[SOLVED] variable defined in awk, not working. !!! Sha_unix Solaris / OpenSolaris 15 09-23-2011 05:06 AM
How to express built-In variable, RS in awk command corone Linux - Software 1 04-26-2011 04:25 AM
Pass a shell variable to an AWK command chogall Programming 1 12-23-2010 10:12 AM


All times are GMT -5. The time now is 09:52 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration