Unix/Linux Go Back    


Shell Programming and Scripting BSD, Linux, and UNIX shell scripting — Post awk, bash, csh, ksh, perl, php, python, sed, sh, shell scripts, and other shell scripting languages questions here.

pipe to grep doesn't work in bash script

Shell Programming and Scripting


Tags
bash pipe script grep

Closed    
 
Thread Tools Search this Thread Display Modes
    #1  
Old Unix and Linux 02-11-2012
kcstrom kcstrom is offline
Registered User
 
Join Date: Feb 2012
Last Activity: 19 April 2012, 9:30 PM EDT
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
pipe to grep not working in bash script

Hi,

I'm trying to write a script that checks gvfs to see if a mount exists so I can run it from network-manager's status hooks. I thought I'd pipe the output of gvfs-mount -l to grep for the particular mounts I care about. When I do this in a bash script:


Code:
cmnd="gvfs-mount -l | grep -i '${mount}'"
dastring=`${cmnd}` #remove me
ret=$?
echo "Output from ${cmnd}" #remove me
echo "$dastring"

$dastring looks like the output from gvfs-mount (although it's detailed as if I gave it the -i option in addition to -l).

If I copy and paste the ${cmnd} (from where I echo it) and run it directly from the terminal, it display the line of text I'm looking for with grep.

Can anyone help me figure out why the pipe works directly in the terminal but does not appear to be doing so in the script?

Thanks in advance.

Last edited by kcstrom; 02-11-2012 at 11:39 AM..
Sponsored Links
    #2  
Old Unix and Linux 02-11-2012
Scrutinizer's Unix or Linux Image
Scrutinizer Scrutinizer is offline Forum Staff  
Moderator
 
Join Date: Nov 2008
Last Activity: 24 June 2017, 3:40 AM EDT
Location: Amsterdam
Posts: 11,451
Thanks: 493
Thanked 3,299 Times in 2,911 Posts
You can either do this:

Code:
eval dastring=\`${cmnd}\`

or do this for example:

Code:
dastring=$(gvfs-mount -l | grep -i "${mount}")

-or with back ticks:-

Code:
dastring=`gvfs-mount -l | grep -i "${mount}"`

Sponsored Links
    #3  
Old Unix and Linux 02-11-2012
kcstrom kcstrom is offline
Registered User
 
Join Date: Feb 2012
Last Activity: 19 April 2012, 9:30 PM EDT
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Quote:
Originally Posted by Scrutinizer View Post

Code:
eval dastring=\`${cmnd}\`

Thanks Scrutinizer - this is what I needed as I want to keep cmnd around for print out later in the script.

I don't understand why backticks in


Code:
dastring=`${cmnd}`

didn't run the command and assign the output to dastring. It must be that dastring equaled that string including the backticks - but it doesn't quite make sense. Could you explain what's going on here?

Thanks a bunch!
    #4  
Old Unix and Linux 02-11-2012
agama agama is offline Forum Advisor  
Always Learning
 
Join Date: Jul 2010
Last Activity: 7 April 2014, 3:02 PM EDT
Location: earth>US>UTC-5
Posts: 1,466
Thanks: 110
Thanked 511 Times in 490 Posts
When the shell expands the variable holding the command, it recognises that the pipe symbol is special, and quotes it. If you consider this example:



Code:
cmd="echo  foo | awk '{print \"bar \"; print }'"
data=`$cmd`

you would expect that when $cmd is executed the string "bar foo" would be assigned to data. However, the string assigned to data is actually:

Code:
foo | awk '{print "bar "; print }'

If you execute it with -x you'll see in the trace the quotes that the shell adds and that the pipe symbol is being passed to echo (along with everything else past it), and not interpreted by the shell. The output when I ran it was:



Code:
+ cmd=$'echo  foo | awk \'{print "bar "; print }\''
+ echo foo '|' awk $'\'{print' '"bar' '";' print $'}\''
+ data=$'foo | awk \'{print "bar "; print }\''
+ echo $'foo | awk \'{print "bar "; print }\''
foo | awk '{print "bar "; print }'

Notice in the second line the '|' is the clue that the shell has treated the contents of the variable as a single string and has not parsed it as a command.


When you add the eval in front of the expansion, the shell expands the variable and then parses it as a command. The result is that the pipe is then recognised as you intended and both commands are executed as expected.


In your case, the whole string would have been passed to the gvfs-mount command and as that string contained -i, it would have listed details. I suspect it might have also complained about the pipe and/or grep but that would have been to stderr and not captured in your variable.

When things seem strange, I usually put a set -x before the statement that isn't working and set +x ater it to get the details of how the shell is interpreting my code. The output is usually enough to clear up the confusion.


Hope this helps
Sponsored Links
    #5  
Old Unix and Linux 02-11-2012
kcstrom kcstrom is offline
Registered User
 
Join Date: Feb 2012
Last Activity: 19 April 2012, 9:30 PM EDT
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Quote:
Originally Posted by agama View Post
When things seem strange, I usually put a set -x before the statement that isn't working and set +x ater it to get the details of how the shell is interpreting my code. The output is usually enough to clear up the confusion.
Hope this helps
Thanks agama! Being a bash newb still, I didn't know about the +/-x - that will come in very handy in the future I think. Thanks for that and the detailed explanation regarding pipe!
Sponsored Links
Closed

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Linux More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Bash Script Help...search then read from file: change text and pipe back... serverfull Shell Programming and Scripting 1 09-22-2011 10:04 AM
Creating script - grep wont work? Prantare Solaris 2 08-28-2010 01:23 PM
cant get a counter to work in bash scipt, this is calling expect script melvin Shell Programming and Scripting 1 04-13-2010 10:15 PM
two grep in one script doesn't work? monkey77 Shell Programming and Scripting 2 03-11-2010 06:11 PM
Open and work on a .doc file with bash script bobbasystem Shell Programming and Scripting 3 10-23-2009 08:52 PM



All times are GMT -4. The time now is 09:45 AM.