openSUSE Forums > Archives > SF Archives > ARCHIVES - Programming & Scripting » Bash Experts: Test And Comparisons Questions

Go Back   openSUSE Forums > Archives > SF Archives > ARCHIVES - Programming & Scripting
Forums FAQ Members List Search Today's Posts Mark Forums Read


ARCHIVES - Programming & Scripting A place to discuss website design, programming, shell scripts, etc

 
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 21-Feb-2008, 01:00
suseforumsnet42
Guest
 
Posts: n/a
Default

Just trying to clear up some confusion on current Bash syntax. I've viewed the man page, reference and a couple of other sources, along with egrepping init.d. Any other suggestions that clarify these issues would be appreciated.

1. What's the difference between test's -a and &&, or test's -o and ||?

As an example, the statement below is from init.d. They seemed to use both, -a and &&. Why not just use &&? It seems &&/|| can be both used in arithmetic and string statements.

if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1

2. What's the difference between [ and [[, besides one being builtin and the other a keyword :-) It
seems one could always use [[]] and have better productivity.

[ "abc" \< "def" ];echo $?

Don't need the escape if using [[]]. Also sometimes when using -a to &&, [[ has no problem, but [ does.

[[ "abc" < "def" ]];echo $?

[ ! -d "${aFile}" -a ${aFile##*/} != "index" ] verses [[ ! -d "${aFile}" && ${aFile##*/} != "index"* ]]

It seems numeric comparisons (-eq -gt -lt -ne -ge -le) can be replaced with = < > !=, etc.

[ 3 > 4 ]; echo $?

It seems = is equivalent to == per Bash reference. One less thing to remember :-)

Can it be summarized:
1) Use && ||. Forget -a -o.
2) Use = > < >= <= !=. Forget -eq -gt -lt -ne -ge -le.
3) Use [[]]. Forget [].

4. Does this change anything if /proc/acpi is quoted? Whether they are single or double shouldn't change
the response because there is nothing to expand. My brain says that is a string and needs quotes, but it doesn't, and that is because.....? :-)

if [ ! -d /proc/acpi ]; verses if [ ! -d '/proc/acpi'];


Thank you.
  #2 (permalink)  
Old 21-Feb-2008, 01:36
ken_yap
Guest
 
Posts: n/a
Default

Quote:
Just trying to clear up some confusion on current Bash syntax. I've viewed the man page, reference and a couple of other sources, along with egrepping init.d. Any other suggestions that clarify these issues would be appreciated.

1. What's the difference between test's -a and &&, or test's -o and ||?

As an example, the statement below is from init.d. They seemed to use both, -a and &&. Why not just use &&? It seems &&/|| can be both used in arithmetic and string statements.

if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1
[/b]
&& and || are not part of test. && and || are for flow control in commands invoked by the shell. In fact the line consists of two commands:

if
test ...
&&
stty ...

Meaning that if the test succeeds, run the stty.

Incidentally test and [ are the same. But you have to remember to have whitespace around the [ and ]. It won't work without that.

Also there is no visible difference to execution whether test/[ is builtin or not. Builtins behave as if they were external commands.

Quote:
2. What's the difference between [ and [[, besides one being builtin and the other a keyword :-) It
seems one could always use [[]] and have better productivity.

[ "abc" \< "def" ];echo $?

Don't need the escape if using [[]]. Also sometimes when using -a to &&, [[ has no problem, but [ does.

[[ "abc" < "def" ]];echo $?

[ ! -d "${aFile}" -a ${aFile##*/} != "index" ] verses [[ ! -d "${aFile}" && ${aFile##*/} != "index"* ]]
[/b]
The answer is in the man page for bash:

Word splitting and pathname expansion are not performed on the words between the [[ and ]]; ...

There may be other differences. This shows the difference:

$ var='foo bar'
$ [[ $var = 'foo bar' ]] && echo foo
foo
$ [ $var = 'foo bar' ] && echo foo
bash: [: too many arguments

Quote:
It seems numeric comparisons (-eq -gt -lt -ne -ge -le) can be replaced with = < > !=, etc.

[ 3 > 4 ]; echo $?
[/b]
No. This shows the difference:

$ [ 34 -lt 4 ] && echo wrong
$ [ 34 '<' 4 ] && echo wrong
wrong

One's a arithmetic comparison, the other is a string comparison.

Quote:
Can it be summarized:
1) Use && ||. Forget -a -o.
2) Use = > < >= <= !=. Forget -eq -gt -lt -ne -ge -le.
3) Use [[]]. Forget [].
[/b]
No.

Quote:
4. Does this change anything if /proc/acpi is quoted? Whether they are single or double shouldn't change
the response because there is nothing to expand. My brain says that is a string and needs quotes, but it doesn't, and that is because.....? :-)

if [ ! -d /proc/acpi ]; verses if [ ! -d '/proc/acpi'];
Thank you.
[/b]
No, because the string /proc/acpi contains no shell metacharacters.
  #3 (permalink)  
Old 21-Feb-2008, 02:27
suseforumsnet42
Guest
 
Posts: n/a
Default

Thank you. I'll have to sit back and digest this a bit more.

In order to do the if-statement below, I used the [[. Not being test/[ I can't use "-a" for "and",
so I used &&. So the "rule", if test/[ use -a, if not test/[[ use &&?

Code:
# Don't process directories or files beginning with the pattern "index"
#
for aFile in *; do
****if [[ ! -d "${aFile}" && ${aFile##*/} != "index"* ]]; then
******** echo ${aFile}
****fi
done

(2) Thought escaping digestion.... :-)
ARITHMETIC EVALUATION in man bash shows && ||. That's what got me confused with &&/|| used in other situations and not just flow control in commands. I thought they could be used in an if construction to replace -a and -o in certain situations. The comparisons < >, etc also appear in the precedence table. If you don't use then in conditional testing where do these get used? :-)

Further down man bash I do see:
"arg1 OP arg2
OP is one of -eq, -ne, -lt, -le, -gt, or -ge. These arithmetic binary operators return true if arg1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to arg2, respectively. Arg1 and arg2 may be positive or negative integers."

But when I look at the ARITHMETIC EVALUATION section that sort of confuses me.
  #4 (permalink)  
Old 21-Feb-2008, 02:48
ken_yap
Guest
 
Posts: n/a
Default

Quote:
Thank you. I'll have to sit back and digest this a bit more.

(1) Any thoughts why the "and" (-a) gets a syntax error in the situation below?

Code:
# Don't process directories or files beginning with the pattern "index"
#
for aFile in *; do
****[ ! -d "${aFile}" -a ${aFile##*/} != "index" ] 
****echo ${aFile}
done
[/b]
Put "s around ${aFile##*/} and it will pass. You always have to be prepared for the possibility of an expansion and substitution returning the empty string, creating a syntax error. In your case, the expanded expression became -a != "index", an error.

Quote:
(2) Thought escaping digestion.... :-)
ARITHMETIC EVALUATION in man bash shows && ||. That's what got me confused with &&/|| used in other situations and not just flow control in commands. I thought they could be used in an if construction to replace -a and -o. The comparisons < >, etc also appear in the precedence table. If you don't use then in conditional testing where do these get used? :-)
[/b]
Arithmetic evaluation only occurs inside (( )), and again has nothing to do with test/[, although they make it unnecessary to use the command expr(1) as was the case in older shells. The &&/|| in arithmetic evaluation is unrelated to the &&/|| used for command flow control.

Here's an example of && inside arithmetic evaluation:

echo $((2 < 3 && 4 > 5))

Quote:
Further down man bash I do see:
"arg1 OP arg2
OP is one of -eq, -ne, -lt, -le, -gt, or -ge. These arithmetic binary operators return true if arg1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to arg2, respectively. Arg1 and arg2 may be positive or negative integers."

But when I look at the ARITHMETIC EVALUATION section that sort of confuses me.
[/b]
Those are for use inside test, [, or [[.
  #5 (permalink)  
Old 21-Feb-2008, 14:38
suseforumsnet42
Guest
 
Posts: n/a
Default

Just wanted to make sure I thanked you for your most excellent clarification.

I found a tip over at IBM that addresses comparisons. Lots of different examples sure do help.
I just have to get it straight in my brain the test command is a COMMAND :-) and other ways for comparisons, and strings verses numerics comparisons in the Bash environment.

Bash test and comparison functions
http://www.ibm.com/developerworks/li...bash-test.html
 

Bookmarks

Thread Tools
Display Modes

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




 

Search Engine Friendly URLs by vBSEO 3.3.0 RC2