- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - Linux
- >
- double vs single brackets in shell script tests
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Forums
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 09:22 AM
тАО05-30-2007 09:22 AM
double vs single brackets in shell script tests
Here is the code snippet that raised this issue for me:
#!/usr/bin/sh
if [[ $DEVICE = 'ftp' ]]
then continue
fi
if [[ $USER = 'reboot' ]]
then continue
fi
if [[ $USER = 'root' ]]
then continue
fi
if [[ $USER = 'wtmp' || $USER < 'a' ]]
then break
fi
if [[ $USER = 'cduser' && $DEVICE = 'ftp' ]]
then continue
fi
if [[ $DEVICE = 'console' ]]
then continue
fi
When I trace the code I get:
+ [[ remshd = ftp ]]
+ [[ root = reboot ]]
+ [[ root = root ]]
+ [[ root = wtmp ]]
+ [[ root < a ]]
+ [[ root = cduser ]]
+ [[ remshd = console ]]
I would have expected the third line should have been true. (The trailing spaces are odd).
If I change some of the double brackets to single brackets as follows:
#!/usr/bin/sh
if [[ $DEVICE = 'ftp' ]]
then continue
fi
if [ $USER = 'reboot' ]
then continue
fi
if [ $USER = 'root' ]
then continue
fi
if [[ $USER = 'wtmp' || $USER < 'a' ]]
then break
fi
if [[ $USER = 'cduser' && $DEVICE = 'ftp' ]]
then continue
fi
if [ $DEVICE = 'console' ]
then continue
fi
Then the code runs fine:
+ [[ remshd = ftp ]]
+ [ root = reboot ]
+ [ root = root ]
But I don't understand why.
I did try to change all the double bracket tests to single brackets, but then the shell objected on the compound conditions.
I would very very grateful to anyone could clear up why this happens and perhaps explain in simpler terms than I have
been able to find on how to decide which form to use.
Scott
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 09:35 AM
тАО05-30-2007 09:35 AM
Re: double vs single brackets in shell script tests
I guess double brackets is ksh style but you are using sh. check the man pages for each shell.
Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 09:36 AM
тАО05-30-2007 09:36 AM
Re: double vs single brackets in shell script tests
The main gotcha is that the syntax for the logical operators are different in the two version
if [[ "${A}" = "Hook" && "${B}" = "Smee" ]]
is equivalent to:
if [ "${A}" = "Hook" -a "${B}" = "Smee" ].
Similarly:
if [[ "${A}" = "Hook" || "${B}" = "Smee" ]]
is equivalent to:
if [ "${A}" = "Hook" -o "${B}" = "Smee" ].
It is always a very good idea to enclose the tested variables inside double quotes because should the instantiated variables happen to be null and not enclosed within quotes then a syntax error results. Moreover, without quotes white space is not preserver and that is probably your fundamental problem in your example.
- Tags:
- quoting
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 09:43 AM
тАО05-30-2007 09:43 AM
Re: double vs single brackets in shell script tests
I have read the man page and unfortunately it makes no sense on this subject. It talks about word splitting, etc but does not have anything (at least that I understand) that helps me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 09:46 AM
тАО05-30-2007 09:46 AM
Re: double vs single brackets in shell script tests
Let me try quoting the variable names and see what happens. (That's just not something I am used to having to do in other languages I have used).
Scott
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 09:50 AM
тАО05-30-2007 09:50 AM
Re: double vs single brackets in shell script tests
man test is more detailed how clay mentioned.
Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-30-2007 07:42 PM - edited тАО09-25-2011 07:50 PM
тАО05-30-2007 07:42 PM - edited тАО09-25-2011 07:50 PM
Re: double vs single brackets in shell script tests
>It talks about word splitting, etc but does not have anything (at least that I understand)
I think this is exactly your problem. See "Blank Interpretation". For [[ ]] the trailing blanks in $USER are not split.
Note also [[ = ]] is NOT a test for string equality but pattern matching.
Assuming that USER="root ", these are all true:
[[ $USER = r* ]]
[[ $USER = root* ]]
>Clay: you should always use double brackets because they are internal to the shell and thus more efficient
Using tusc, I seen no evidence that test(1) is executed for [ ], both are real shell builtins.
In fact, /usr/bin/test just invokes the Posix shell builtin.
>It is always a very good idea to enclose the tested variables inside double quotes
It appears you don't have to do that for [[ ]]. But still a very good idea.
BUT you must NOT use "" or "" quoting if you want pattern matching.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-31-2007 03:07 AM
тАО05-31-2007 03:07 AM
Re: double vs single brackets in shell script tests
I changed the third "if" as you suggested and still get the same results:
if [[ "${USER}" = 'root' ]]
then continue
fi
+ [[ remshd = ftp ]]
+ [ root = reboot ]
+ [[ root = root ]]
I also change the single quotes around 'root' to double quotes but this does not seem to have any effect:
if [[ "${USER}" = "root" ]]
then continue
fi
+ [[ remshd = ftp ]]
+ [ root = reboot ]
+ [[ root = root ]]
I am curious, the first if looks like this and seems to work OK:
if [[ $DEVICE = 'ftp' ]]
then continue
fi
+ [[ remshd = ftp ]]
(Note the lack of padding on the right of "remshd").
I can get this to work just by changing to single brackets, but am hoping this will be a good learning opportunity for ma and anyone else reading this thread.
Scott
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-31-2007 03:12 AM
тАО05-31-2007 03:12 AM
Re: double vs single brackets in shell script tests
>I think this is exactly your problem. >See "Blank Interpretaion". For [[ ]] the >trailing blanks in $USER are not split.
>Note also [[ = ]] is NOT a test for string >equality but pattern matching.
I guess I am being dense here, but I've never worked in a language where xxx
So what do I do if I want string equality and not pattern matching?
Scott
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО05-31-2007 04:57 AM
тАО05-31-2007 04:57 AM
Re: double vs single brackets in shell script tests
then use [ .. ] - you know the side effects much better than in [[ .. ]] so leave it at old style (IMHO).
mfG Peter