LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices

Reply
 
Search this Thread
Old 02-23-2010, 02:41 PM   #1
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Rep: Reputation: 1
Yet Another Bash Quotes Within Quotes Issue


This one's... perplexing.

I've got a simple script that I'm trying to email error messages from. I want to do something like this:

MAIL="/bin/mailx -s Error from $(basename $0) root"
/bin/umount /data_backup||{ echo "backup unmount failed"|$MAIL;exit 1; }

but of course that won't work, because it'll try to mail a message with the subject 'Error' to the user 'from', 'daily_backups', and 'root'. So the question is how to get quotes around the subject.

The obvious is to escape a quote or double-quote. But that gives me:

MAIL="/bin/mailx -s \'Error from $(basename $0)\' root"

which the shell expands to

+ /bin/mailx -s '\'\''Error' from 'daily_file_backup\'\''' root

which doesn't work, or

MAIL="/bin/mailx -s \"Error from $(basename $0)\" root"

expanding to

+ /bin/mailx -s '"Error' from 'daily_file_backup"' root
[root@dg scripts]# daily_file_backup"... Unbalanced '"'

I've tried replacing the whole subject with another variable, i.e.

SUBJ="Error from $(basename $0)"
MAIL="/bin/mailx -s "$SUBJ" root"

with no luck. Various combinations of quotes and escapes fail miserably with that, also:

MAIL="/bin/mailx -s /"$SUBJ/" root"
+ /bin/mailx -s '"Error' from 'daily_file_backup"' root
[root@dg scripts]# daily_file_backup"... Unbalanced '"'

Now the strange part is - with debugging on, the string _looks_ like it's OK:

+ SUBJ='Error from daily_file_backup'
+ MAIL='/bin/mailx -s "Error from daily_file_backup" root'

which is exactly what I want $MAIL to be. But further on, when it actually executes:

+ /bin/mailx -s '"Error' from 'daily_file_backup"' root

Driving me nuts. Any pointers in the right direction appreciated.
 
Old 02-23-2010, 03:57 PM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
Sorry, but I can't follow all that.

There are two secrets to quoting:
1. The "hard quote" (') protects everything inside, whereas the "soft" quote ("), allows certain things--eg variables-- to be expanded by the shell.

2. Quotes behave like "toggles" so, to turn off quoting for part of an expression, you just do as follows:
'stuff and 'unquoted stuff' more quoted stuff' ("unquoted stuff" might look like it was being quoted doubly, but it's just being UN-quoted.

Beyond this, I've never had any luck with anything except trial and error.
 
Old 02-23-2010, 10:14 PM   #3
Elv13
Member
 
Registered: Apr 2006
Location: Montreal,Quebec
Distribution: Gentoo
Posts: 825

Rep: Reputation: 128Reputation: 128
Cheapest last ressort solution:

VAR="cmd1 $1 `echo -n 'my text'`"

but normally, just going in and out of quotation work

VAR=$VAR2"some text "$VAR3'some more text'
 
Old 02-23-2010, 10:59 PM   #4
dive
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,203

Rep: Reputation: 292Reputation: 292Reputation: 292
I think using vars like that you are just overcomplicating things.

/bin/umount /data_backup || echo "backup unmount failed" | /bin/mailx -s "Error from $(basename $0)" root
 
Old 02-24-2010, 07:00 AM   #5
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
>> I think using vars like that you are just overcomplicating things.

>> /bin/umount /data_backup || echo "backup unmount failed" | /bin/mailx -s "Error from $(basename $0)" root

Yeah, you'd think so, wouldn't you? But it doesn't work:

root@dg ~]# /bin/umount /data_backup || echo "backup unmount failed" | /bin/mailx -s "Error from $(basename $0)" root
umount: /data_backup: device is busy
umount: /data_backup: device is busy
basename: invalid option -- b
Try `basename --help' for more information.

and the email comes back with the subject "Error from ".

I can do a plain $0 in there, and it works - and that's my workaround, I guess.
 
Old 02-24-2010, 07:36 AM   #6
Skaperen
Senior Member
 
Registered: May 2009
Location: WV, USA
Distribution: Slackware, CentOS, Ubuntu, Fedora, Timesys, Linux From Scratch
Posts: 1,777
Blog Entries: 20

Rep: Reputation: 115Reputation: 115
You used:
Code:
MAIL="/bin/mailx -s \'Error from $(basename $0)\' root"
However, you don't need to escape a different kind of quote. You don't need to escape single quotes inside double quotes. So try:
Code:
MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
That will give you something like:
Code:
/bin/mailx -s 'Error from foo' root
as the string value in variable MAIL. The $(basename $0) part will be interpreted at the time of assignment to MAIL (e.g. using $0 from the command that did this assignment). If that's what you want, you should be good to go with this.
 
Old 02-24-2010, 07:42 AM   #7
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
Quote:
Originally Posted by Skaperen View Post
You used:
Code:
MAIL="/bin/mailx -s \'Error from $(basename $0)\' root"
However, you don't need to escape a different kind of quote. You don't need to escape single quotes inside double quotes. So try:
Code:
MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
That will give you something like:
Code:
/bin/mailx -s 'Error from foo' root
as the string value in variable MAIL. The $(basename $0) part will be interpreted at the time of assignment to MAIL (e.g. using $0 from the command that did this assignment). If that's what you want, you should be good to go with this.
Nope; because the single quote won't expand the $(basename $0). It comes out

MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
[root@dg scripts]# echo $MAIL
/bin/mailx -s 'Error from ' root
 
Old 02-24-2010, 08:33 AM   #8
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
I think I've determined that the only easy way to do this is split it up:

SUBJ="Error from $(basename $0)"
MAIL="/bin/mailx"

/bin/umount /data_backup|| \
{ $ECHO "backup unmount failed"|$MAIL -s "$SUBJ" root;exit 1; }


works.
 
Old 02-24-2010, 08:35 AM   #9
dive
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,203

Rep: Reputation: 292Reputation: 292Reputation: 292
Try "basename ${0/-//}"

Any good?
 
Old 02-24-2010, 09:40 AM   #10
Skaperen
Senior Member
 
Registered: May 2009
Location: WV, USA
Distribution: Slackware, CentOS, Ubuntu, Fedora, Timesys, Linux From Scratch
Posts: 1,777
Blog Entries: 20

Rep: Reputation: 115Reputation: 115
Quote:
Originally Posted by tboyer View Post
Nope; because the single quote won't expand the $(basename $0). It comes out

MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
[root@dg scripts]# echo $MAIL
/bin/mailx -s 'Error from ' root
Hmmm ... it expands it for me:
Code:
altair/phil /home/phil 141> cat /home/phil/cmd/foo
#!/bin/bash
MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
echo "MAIL='${MAIL}'" 1>&2
altair/phil /home/phil 142> /home/phil/cmd/foo
MAIL='/bin/mailx -s 'Error from foo' root'
altair/phil /home/phil 143>
Of course, if you reverse the quotes used, it will do as you describe:
Code:
altair/phil /home/phil 143> cat /home/phil/cmd/bar
#!/bin/bash
MAIL='/bin/mailx -s "Error from $(basename $0)" root'
echo "MAIL='${MAIL}'" 1>&2
altair/phil /home/phil 144> /home/phil/cmd/bar
MAIL='/bin/mailx -s "Error from $(basename $0)" root'
altair/phil /home/phil 145>
So I wonder how you are getting it to not expand if this is truly bash.
 
Old 02-25-2010, 08:31 AM   #11
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
Quote:
Originally Posted by Skaperen View Post
Hmmm ... it expands it for me:
Code:
altair/phil /home/phil 141> cat /home/phil/cmd/foo
#!/bin/bash
MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
echo "MAIL='${MAIL}'" 1>&2
altair/phil /home/phil 142> /home/phil/cmd/foo
MAIL='/bin/mailx -s 'Error from foo' root'
altair/phil /home/phil 143>
Of course, if you reverse the quotes used, it will do as you describe:
Code:
altair/phil /home/phil 143> cat /home/phil/cmd/bar
#!/bin/bash
MAIL='/bin/mailx -s "Error from $(basename $0)" root'
echo "MAIL='${MAIL}'" 1>&2
altair/phil /home/phil 144> /home/phil/cmd/bar
MAIL='/bin/mailx -s "Error from $(basename $0)" root'
altair/phil /home/phil 145>
So I wonder how you are getting it to not expand if this is truly bash.
OK, something very, very strange is going on here. Bog-standard RHEL5.4 system.

[root@dg ~]# env
HOSTNAME=dg.denmantire.com
SHELL=/bin/bash
TERM=vt220
HISTSIZE=1000
USER=root
...

so I'm using bash, right?

Watch this:

[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
basename: invalid option -- b
Try `basename --help' for more information.
[root@dg ~]# echo $MAIL
/bin/mailx -s 'Error from ' root
[root@dg ~]# /bin/bash
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
[root@dg ~]# echo $MAIL
/bin/mailx -s 'Error from bash' root
[root@dg ~]#

Not machine-specific, either. I've got a dozen systems in three locations - all do exactly the same thing. Let's assume I'm not totally p0wned...

Has to be something weird in a .profile somewhere. I'll track this down now, only because it'll drive me nuts.
 
Old 02-25-2010, 10:29 AM   #12
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,533
Blog Entries: 28

Rep: Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176Reputation: 1176
Quote:
Originally Posted by tboyer View Post
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
basename: invalid option -- b
Try `basename --help' for more information.
[root@dg ~]# echo $MAIL
/bin/mailx -s 'Error from ' root
[root@dg ~]# /bin/bash
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
[root@dg ~]# echo $MAIL
/bin/mailx -s 'Error from bash' root
Try echo $0 so we can see what it is
 
Old 02-25-2010, 10:35 AM   #13
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
Quote:
Originally Posted by catkin View Post
Try echo $0 so we can see what it is
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
basename: invalid option -- b
Try `basename --help' for more information.
[root@dg ~]# echo $0
-bash
[root@dg ~]# /bin/bash
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
[root@dg ~]# echo $0
/bin/bash

Hmmm. Never noticed that before - what's -bash?
 
Old 02-25-2010, 11:49 AM   #14
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
Quote:
Originally Posted by tboyer View Post
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
basename: invalid option -- b
Try `basename --help' for more information.
[root@dg ~]# echo $0
-bash
[root@dg ~]# /bin/bash
[root@dg ~]# MAIL="/bin/mailx -s 'Error from $(basename $0)' root"
[root@dg ~]# echo $0
/bin/bash

Hmmm. Never noticed that before - what's -bash?
Duh. That's it, of course. If my shell is -bash, basename is returning -b and seeing it as an option flag.
 
Old 02-25-2010, 11:51 AM   #15
tboyer
LQ Newbie
 
Registered: Dec 2009
Distribution: RHEL
Posts: 16

Original Poster
Rep: Reputation: 1
Quote:
Originally Posted by dive View Post
Try "basename ${0/-//}"

Any good?
Works great.

Now, tell me why.
 
  


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
howto: bash.org quotes at logon jbarelds Linux - General 6 03-26-2010 02:34 PM
Problems with quotes and double quotes Andruha Slackware 6 01-02-2010 04:44 PM
[SOLVED] Using a long Bash command including single quotes and pipes in a Bash script antcore Linux - General 9 07-22-2009 11:10 AM
Using single quotes vs double quotes in PHP strings vharishankar Programming 6 07-11-2005 11:41 AM
How to get rid of quotes in bash? CodeWarrior Slackware 7 05-21-2003 09:02 PM


All times are GMT -5. The time now is 03:46 AM.

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