LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   bash scripting Q (https://www.linuxquestions.org/questions/linux-newbie-8/bash-scripting-q-942977/)

grimx 05-02-2012 03:16 PM

bash scripting Q
 
Just wanted to know what the difference is between
if() and if[]

Tinkster 05-02-2012 03:17 PM

() wraps up a sub-shell, [ ] is an alias for 'test'.

grimx 05-02-2012 03:19 PM

So, is it best to use [] instead of (), when test for a condition??

Tinkster 05-02-2012 03:47 PM

It depends on what you're testing ...

chrism01 05-02-2012 07:49 PM

You might also want to look at this page http://tldp.org/LDP/abs/html/testcon...ml#DBLBRACKETS

David the H. 05-03-2012 07:21 AM

First of all, please use [code][/code] tags around your code and data, to preserve formatting and to improve readability. Please do not use quote tags, colors, or other fancy formatting.

Here are a few useful bash scripting references:
http://mywiki.wooledge.org/BashGuide
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
http://www.linuxcommand.org/index.php
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/index.html
http://www.gnu.org/software/bash/manual/bashref.html
http://wiki.bash-hackers.org/start
http://ss64.com/bash/

The first link in particular will cover all the scripting basics you need to know. It's important to understand and use the exact syntax as described in the documentation, as everything has very precise meanings.

That said, there are several intricacies involved here.

Code:

foo() { text="This is a function called foo." ; echo "$text" ;}

$ foo
This is a function called foo.

$ echo foo()
bash: syntax error near unexpected token `('

When parentheses are placed immediately after a command word (i.e. only at the beginning of the line), it starts a function definition. Otherwise it just results in a syntax error.

Code:

$ ( text="This is an echo command running in a subshell." ; echo "$text" )
This is an echo command running in a subshell.

$ echo "$text"
                        #outputs a blank line

When parentheses are placed around a command or set of commands, it splits off a subshell to execute the contents in. This can have many uses, such as not having them affect the main shell's environment.


Code:


x=100 y=99

if [ "$x" > "$y" ]; then echo "$x is greater than $y" ; else echo "$y is greater than $x" ; fi
if [[ $x > $y ]]; then echo "$x is greater than $y" ; else echo "$y is greater than $x" ; fi

if [ "$x" -gt "$y" ]; then echo "$x is greater than $y" ; else echo "$y is greater than $x" ; fi
if [[ $x -gt $y ]]; then echo "$x is greater than $y" ; else echo "$y is greater than $x" ; fi

if (( x > y )); then echo "$x is greater than $y" ; else echo "$y is greater than $x" ; fi

"[" is a synonym for the test command, with arguments following them. Note that spaces between the elements are important, and quotes should be used around variables. "[[" is a newer bash-specific keyword, which both replaces test and adds new features, including not needing to quote variables.

Pay attention to how the comparisons work in the above examples. Inside the square brackets, ">,<,=", etc. are considered string comparisons, and so 99 can indeed be "greater than" 100, depending on the sorting order set in your locale. To do numeric comparisons, use "-gt,-lt,-eq", etc.

Even better, use "((..))" which is a bash keyword structure for evaluating arithmetic operations (integer only).

Finally...

Code:

x=foo
if grep -q "$x" file.txt ; then echo "File contains [$x]." ; fi

if ( x=foo ; grep -q "$x" file.txt ) ; then echo "File contains [$x]." ; fi

Constructs like if aren't limited to just "[/[[/((". They can check the status of any command (grep, in this case). If the command exits successfully, the subcommands will run. Note that the only difference in the above two examples is that the second one runs in a subshell, as explained before, and so "$x" will disappear after the command is run. The exit status of a subshell is usually the status of the final command in it.


So to sum it up, when using bash (or ksh), integer comparisons should be done with "((..))" and string and file comparisons with "[[..]]". Only use "[..]" if you need posix compliance, which for the average user is rarely. And "()" itself is for other purposes and isn't directly used in tests.


Here are few more links concerning conditional expressions:
http://mywiki.wooledge.org/ArithmeticExpression
http://mywiki.wooledge.org/BashFAQ/031
http://wiki.bash-hackers.org/commands/classictest
http://wiki.bash-hackers.org/syntax/...nal_expression

chrism01 05-03-2012 07:08 PM

Quote:

"[[" is a newer bash-specific keyword,
Actually, I first got taught about them in a ksh course :)
As advised on the course, I always use them in ksh (or bash), instead of [ ] or 'test'.

David the H. 05-04-2012 11:07 AM

Yes, of course it's in ksh too. I believe they probably even initiated it. In fact, quite a few ksh innovations have been subsequently adopted by bash, and vice-versa. There's a lot of similarity between the two shells due to this.

When I said "bash-specific", what I really meant was that it wasn't a posix-compliant or otherwise universally-available feature, and that you can't just assume it being there if you use another shell. But since the topic question was about bash specifically, I didn't want to further clutter up my post with relatively unimportant details like that. Even so, I did mention it in passing in my final paragraph.

Thanks for allowing the clarification. :hattip:

chrism01 05-07-2012 08:07 PM

No worries :)
Actually, the course was so long ago, Linux had barely made it out of Finland :)
I was working on Sequent (later IBM) https://en.wikipedia.org/wiki/Non-Uniform_Memory_Access systems.


All times are GMT -5. The time now is 12:33 PM.