LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-19-2011, 03:20 PM   #1
veeruk101
Member
 
Registered: Mar 2005
Distribution: Ubuntu 12.04 LTS
Posts: 249

Rep: Reputation: 16
Bash scripting general questions about quotation marks


I've been learning about bash scripting and have been reading about the different ways that quotation marks affect variable 'expansion' and things like that, but it's a little confusing for me so I decided to look through some scripts and ask specific questions about them.

Sometimes I see an echo printed as follows:
Quote:
echo $"Usage: $0 {halt|reboot|shutdown}"
Just wondering why is it not the following?
Quote:
echo Usage: $0 {halt|reboot|shutdown}
This command actually caused my laptop to reboot on me! And I'm not sure exactly why from a bash point of view.


My next question is in the above statements, because it is an error situation, often followed by 'exit 1', why is the output not redirected to stderr? Meaning why isn't it the following:
Quote:
echo $"Usage: $0 {halt|reboot|shutdown}" 1>&2

Finally, in bash scripts why is it 'case "$1" in' rather than 'case $1 in'?

Thanks.
 
Old 10-19-2011, 10:45 PM   #2
hapihakr
LQ Newbie
 
Registered: Jul 2011
Location: San Antonio, TX, USA
Distribution: Linux Mint 9 Isadora LXDE
Posts: 8

Rep: Reputation: Disabled
echo Usage: $0 {halt|reboot|shutdown}

This caused your machine to reboot, because the | is a command line operator that the output of the previous command should be fed as input for the next command. Thus the shell interpreted the above command as:

command 1: echo Usage: $0 {halt
the output of which is piped to
command 2: reboot
the output of which never gets piped to
command 3: shutdown}
because the machine rebooted with the 2nd command

The quotes are necessary to prevent the shell from interpreting the pipe operators (|).

echo $"Usage: $0 {halt|reboot|shutdown}" 1>&2

This would be a valid command and maybe in some circumstances desirable; however, standard error often is routed to a log file and since this is a usage message clearly intended for the user, then it should go to standard output, not standard error.

Hope I got all this right and I hope it clarifies things for you.

Good luck.
 
Old 10-19-2011, 10:58 PM   #3
hapihakr
LQ Newbie
 
Registered: Jul 2011
Location: San Antonio, TX, USA
Distribution: Linux Mint 9 Isadora LXDE
Posts: 8

Rep: Reputation: Disabled
...why is it 'case "$1" in' rather than 'case $1 in'?

Again, the quotes prevent unintended consequences, when expanding the variable. Imagine if a user called the command with:

COMMAND |reboot

Then 'case "$1" in' would become 'case |reboot in' and your machine would reboot. Or...

COMMAND |bash

would give the user a shell with the same privileges as the running script.

It is good practice to quote your variable expansions and always look for unintended consequences.
 
Old 10-19-2011, 11:06 PM   #4
hapihakr
LQ Newbie
 
Registered: Jul 2011
Location: San Antonio, TX, USA
Distribution: Linux Mint 9 Isadora LXDE
Posts: 8

Rep: Reputation: Disabled
Hmmmmm... on second thought, my last example was not well thought out... it wouldn't actually happen that way and the user would already have access to the shell, but it illustrates the principle: variable expansion can have unintended consequences and you should use quotes. Sorry if I caused any confusion.
 
Old 10-20-2011, 12:21 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,243

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
I think the explanations above are clear enough so this link may also shed some light for you.
 
1 members found this post helpful.
Old 10-20-2011, 04:23 AM   #6
SecretCode
Member
 
Registered: Apr 2011
Location: UK
Distribution: Kubuntu 11.10
Posts: 562

Rep: Reputation: 102Reputation: 102
I had not taken note of the $"..." usage before - I was expecting just
Code:
echo "Usage: $0 {halt|reboot|shutdown}"
Turns out that $"..." invokes localisation support, i.e. translation into local languages, and therefore a good thing for a program that's going to be distributed.
Code:
echo $"Usage: $0 {halt|reboot|shutdown}"
More here

Interesting!
 
1 members found this post helpful.
Old 10-20-2011, 01:37 PM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Quote:
Originally Posted by hapihakr View Post
...why is it 'case "$1" in' rather than 'case $1 in'?

Again, the quotes prevent unintended consequences, when expanding the variable. Imagine if a user called the command with:

COMMAND |reboot

Then 'case "$1" in' would become 'case |reboot in' and your machine would reboot.
You're certainly right about unintended consequences as a general principle, but you aren't quite correct in this specific situation.

In general, once a character is inside a variable it loses it's special meaning. It's only when the string is re-expanded, and again interpreted by the shell, that it becomes special again. How it's interpreted depends on the context it's used in, however, and some shell built-ins in particular have their own processing rules.

In the case of the case keyword, the contents of the variable aren't interpreted as commands, so any shell-reserved characters such as pipes inside them remain safe. Even whitespace is ok, since word-breaking doesn't occur either. case only views the contents as a literal string to match against.

So case $1 in and case "$1" in are exactly the same syntax-wise. The quotes don't help, but they don't hurt either. When in doubt, always quote.

Understanding how quotes work is vital, and I applaud the OP for taking the time to study it. If he hasn't seen these links before, I recommend them now (in addition to the "quotes" link given above):

http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting

BTW, the [[..]] test keyword is another place where quoting isn't necessary, at least for the left side of the equation. They can be important on the right side if you're doing globbing or regex matches.

http://mywiki.wooledge.org/BashFAQ/031

Last edited by David the H.; 10-20-2011 at 01:39 PM. Reason: minor rewording for clarity
 
1 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
BASH variables, quotation marks and cURL struggles matthias_k Programming 13 01-27-2013 05:56 PM
can not input double quotation marks(invalid quotation key) wangzhilife Linux - Hardware 2 09-18-2009 07:44 AM
Use of quotation marks in bash dunryc Programming 2 06-08-2008 03:24 PM
no quotation marks jdoe9898 Linux - Newbie 1 10-12-2005 04:07 AM
Quotation marks and strings - in C lazyuser Programming 5 01-25-2005 09:14 AM


All times are GMT -5. The time now is 12:50 AM.

Main Menu
Advertisement
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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration