FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > ArchLinux > ArchLinux Pacman Development

 
 
LinkBack Thread Tools
 
Old 11-12-2009, 11:00 PM
Cedric Staniewski
 
Default Changing [ to [[ and ((

Isaac Good wrote:
> On Thu, Nov 12, 2009 at 10:37:31PM +0000, Cedric Staniewski wrote:
>> Isaac Good wrote:
>>> On Thu, Nov 12, 2009 at 07:16:41PM +0000, Cedric Staniewski wrote:
>>>> I hope your patch do not get lost in this thread.
>>> Erm. Yeah, I hope so too. How does it get threaded?
>>>
>> I guess you hit the reply button instead of writing a new mail to
>> pacman-dev. At least, there is the In-Reply-To header field in your mail
>> header.
>>
>>>>> @@ -345,26 +345,26 @@ handle_deps() {
>>>>> local R_DEPS_SATISFIED=0
>>>>> local R_DEPS_MISSING=1
>>>>>
>>>>> - [ $# -eq 0 ] && return $R_DEPS_SATISFIED
>>>>> + (( $# == 0 )) && return $R_DEPS_SATISFIED
>>>>>
>>>> Is there a reason why you do not use (( ! $# )) here?
>>> Some variables are used as a boolean flag in which case testing if ((VAR)) and if (( ! VAR )) reads well. The $# (and EUID) are used as integer values so it struck me as more understandable or readable in this form.
>>>
>> I am fine with that, but would it not makes sense to use (( $# > 0 ))
>> instead of just (( $# )) then?
>
> I am not sure I understand what you are saying.
> In general there are no negative values. With boolean flags either it is set or not set. So you get : if (( FLAG )) and if (( ! FLAG ))
> With $# (and EUID) the code is set up to test for zero, not non-zero. (( $# > 0 )) and (( $# )) are the reverse of what the code checks for.
> All of these do the same thing:
> $ (( $# == 0 )) && return $R_DEPS_SATISFIED
> $ (( $# > 0 )) || return $R_DEPS_SATISFIED
> $ (( ! $# )) && return $R_DEPS_SATISFIED
> $ (( $# )) || return $R_DEPS_SATISFIED
>
> I left the test as && because there was no compelling reason to change it. That aside, I am in favor of either of the first two for $# as opposed to the latter two for boolean flags.
>

Sorry, I meant another line from your patch where you use (( $# )).

> }
>
> check_deps() {
> - [ $# -gt 0 ] || return
> + (( $# )) || return
>
> pmout=$(pacman $PACMAN_OPTS -T "$@")
> ret=$?
> - if [ $ret -eq 127 ]; then #unresolved deps
> + if (( ret == 127 )); then #unresolved deps
> echo "$pmout"
> - elif [ $ret -ne 0 ]; then
> + elif (( ret )); then
> error "$(gettext "Pacman returned a fatal error (%i): %s")" "$ret" "$pmout"
> exit 1
> fi

ret is another non-boolean variable by the way. I think some kind of
code style guide is a good idea.
 
Old 11-13-2009, 12:23 AM
Isaac Good
 
Default Changing [ to [[ and ((

On Thu, Nov 12, 2009 at 11:52:31PM +0000, Cedric Staniewski wrote:
> Allan McRae wrote:
> > Cedric Staniewski wrote:
> >> We could remove the quotes here, too.
> >>
> >
> > Hmmm... can we. I know we can when there are spaces in a single
> > variable, but for some reason I thought quotes were needed when joining
> > multiple variables like that. I could be wrong...
> >
>
> [[ behaves quite different compared to [ in this aspect, but as far as I
> know, you do not need quotes to join variables as long as there are no
> spaces between the variables . There are several exceptions though,
> like cd for example, which require quotes even for single variables when
> they contain spaces. I think this has something to do with the type of
> the command. Builtins/external commands (usually) need quotes whereas
> everything else should work without.
> In my opinion, it is often not obvious whether they are required or not
> which is why I tended to use more quotes than actually were needed. I am
> fairly familiar with quoting by now and can use both "quoting styles",
> but I think it would probably be a good idea to decide for one. Using
> just as much quotes as required would be a little bit shorter, but using
> quotes `where possible` may be a little bit more foolproof.
>
> $ a=" a d"
> $ b=" e"
> $ c=$a:$b
> $ echo "$c"
> a d: e
> $
> $
> $ filename="a d e"
> $ suffix=".f"
> $ [ -e ${filename}${suffix} ] && echo 1
> bash: [: too many arguments
> $ [[ -e ${filename}${suffix} ]] && echo 1
> $ touch "${filename}${suffix}"
> $ [[ -e ${filename}${suffix} ]] && echo 1
> 1
> $ [[ -e a d e.f ]] && echo 1
> bash: syntax error in conditional expression
> bash: syntax error near `d'
> $ [[ -e "a d e.f" ]] && echo 1
> 1
>

The [[ ]] and (( )) are the exception to everything else in bash (cd, [, touch, grep). I know of nothing else that acts like it (except array indices).
With all bash commands, the variable is expanded early enough that a space will split the result into multiple parameters (aka word splitting). Ergo these two are the same:
$ cd a b
$ var="a b"; cd $var
cd will see two arguments. Compare to this, which has one parameter:
$ cd "a b"
$ var="a b"; cd "$var"

The same applies to [, which can make stuff fun, eg:
$ [ -n a -a -z a ] -> returns false because the second condition is false and there is an and (-a)
$ var="a -a -z a"; [ -n $var ] -> false, too! Go figure...

$ var="a -a -z a"; [ -n "$var" ] -> works right

The [[ and (( are "special". Word splitting will not occur inside. (Array indices are computed in arithmetic mode, ie like inside ((: ${arr[stuff]}).
The entire parsing is set up different. Word splitting does not occur. And (mostly as an aside,) bash parses them over double as fast.

Concatenating variables has no special rules. It acts identical to one variable with both the contents. Assuming there is no whitespace between them, it is just like one variable. Whitespace inside causes word splitting but not in (( and [[.

Once discussing word splitting, this also applies to arrays, specifically in this context:
$ for var in ${arr[@]} ; do

Without quotes, elements with a space will be turned into multiple elements for the loop.

- Isaac
 
Old 11-13-2009, 11:28 AM
Jeff
 
Default Changing [ to [[ and ((

On Thu, Nov 12, 2009 at 06:29:11PM -0500, Isaac Good wrote:
>
> I left the test as && because there was no compelling reason to change
> it.

I've been reading the various [ ( vs [[ (( threads and still cannot find
a compelling reason for any of it. It makes the code much less readable
to the people who have been writing portable or semi-portable scripts
for years. Makepkg doesn't require sh portability, but seeing all the
back and forth questions, I'd say it doesn't require the extra confusion
and opacity. It seems clear that even the majority of respondents have
different ideas of what the proper syntax should be whereas with the old
way, people read it and just know what it is doing. If I am missing
something, could someone please enlighten me? Thanks!


--
Jeff

My other computer is an abacus.
 

Thread Tools




All times are GMT. The time now is 07:17 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org