RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Linda Walsh


On 8/1/2010 8:11 PM, Chris F.A. Johnson wrote:
 On Sun, 1 Aug 2010, Linda Walsh wrote:
 
 I have:

 w=/home/law/bin/package: line 5: type: xx: not found

 The =~ operator is suppose to use the RH Expr as a ext.-regex.

 So why doesn't this match and print not found?

 if [[ $w =~ .*not found.* ]]; then echo not found; fi

 It prints nothing.  Seems like such a basic concept.   Sorry, this newbie
 needs help on such trivial matters. :-(
 
 When quoted, the right-hand argument is matched as a string, not an
 expression.
 

So that's how it is...

Aren't single quotes reserved for making things literal, while
double quotes are used for grouping, yet interpreting what is between them 
(expansions and such).

Is there a reason RH =~ was made inconsistent regarding this practice?

I might note: the man page makes no reference to such heinous behavior, leading 
one
me to think I'd use single quotes if I didn't want the contents to be 'active'  
Though
to tell the truth.  Technically, it says:

An additional binary operator, =~, is available, with  the  same
precedence  as  ==  and  !=.  When it is used, the string to the
right of the operator is considered an extended regular  expres-
sion and matched accordingly (as in regex(3)).

I don't see anything about quotes making the =~ operator behave like
the == operator.   I'm not sure I see the usefulness in that.
If there is, then is it necessary to  reserving both single and double quotes
to make =~ behave like ==?

Therefore:
RFE:
Please make double quotes a grouping operator to group multiple words (as in 
separated by spaces) 
together -- even if it is on the RH of  =~.  Let single quotes be the 'do not 
interpret this' 
signifier.  Otherwise there's no nice way to group together patterns that have 
spaces in them.
Inserting '\' before every space isn't my idea of nice: Ick!

p.s. -- why do you want to have =~ behave like ==?  I.e. why these special 
cases to
deactivate regex?  Isn't the whole point of =~ to use the RH as an regex?  Why 
have 
syntax to disable it?

I.E  -- please consider another possibility:
Using double quotes would first do a variable substitution pass, while 
using
single quotes would not -- but use the literal string as a regex.

Why throw away useful functionality of quotes with a new operator?







Re: RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Davide Brini
On Wednesday 04 Aug 2010 09:06:16 Linda Walsh wrote:
 On 8/1/2010 8:11 PM, Chris F.A. Johnson wrote:
  On Sun, 1 Aug 2010, Linda Walsh wrote:
  I have:
  
  w=/home/law/bin/package: line 5: type: xx: not found
  
  The =~ operator is suppose to use the RH Expr as a ext.-regex.
  
  So why doesn't this match and print not found?
  
  if [[ $w =~ .*not found.* ]]; then echo not found; fi
  
  It prints nothing.  Seems like such a basic concept.   Sorry, this
  newbie needs help on such trivial matters. :-(
  
  When quoted, the right-hand argument is matched as a string, not an
  expression.
 
 So that's how it is...
 
 Aren't single quotes reserved for making things literal, while
 double quotes are used for grouping, yet interpreting what is between them
 (expansions and such).
 
 Is there a reason RH =~ was made inconsistent regarding this practice?
 
 I might note: the man page makes no reference to such heinous behavior,
 leading one me to think I'd use single quotes if I didn't want the
 contents to be 'active'  Though to tell the truth.  Technically, it says:
 
 An additional binary operator, =~, is available, with  the  same
 precedence  as  ==  and  !=.  When it is used, the string to the
 right of the operator is considered an extended regular  expres-
 sion and matched accordingly (as in regex(3)).
 
 I don't see anything about quotes making the =~ operator behave like
 the == operator.   I'm not sure I see the usefulness in that.
 If there is, then is it necessary to  reserving both single and double
 quotes to make =~ behave like ==?

From the Changelog:

This document details the changes between this version, bash-3.2-alpha,
and the previous version, bash-3.1-release.
...
3.  New Features in Bash
...
f.  Quoting the string argument to the [[ command's  =~ operator now forces
string matching, as with the other pattern-matching operators.


From the file COMPAT:

33. Bash-3.2 adopts the convention used by other string and pattern matching
operators for the `[[' compound command, and matches any quoted portion
of the right-hand-side argument to the =~ operator as a string rather
than a regular expression.

34. Bash-4.0 allows the behavior in the previous item to be modified using
the notion of a shell `compatibility level'.



Finally, to set a given compatibility level, one uses 

shopt -s compat31

This is in the man page:

compat31
If set, bash changes its behavior to that of version 3.1 with respect
to quoted arguments to the conditional command's =~ operator.

So your example would have worked with shopt -s compat31.

-- 
D.



Re: RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Linda Walsh
Oi vey.

Is that the only thing that will be affected by shopt -s compat31?
Or perhaps that shopt needs to be a bit more specific.



 So your example would have worked with shopt -s compat31.
 


From the file COMPAT:

33. Bash-3.2 adopts the convention used by other string and pattern matching
operators for the `[[' compound command, and matches any quoted portion
of the right-hand-side argument to the =~ operator as a string rather
than a regular expression.


...
Other string operators?  What other ones operate this way?

This is what I'm referring to:

a=hi
if [[ hi == $a ]]; then echo this matches; fi
if [[ 'hi' == '$a' ]] then echo this doesn't; fi

I would prefer this work:

a=h.

if [[ hi =~ $a ]];

That would make sense though I'm not sure what other string operators we
are trying to be consistent with.

Foolish consistency is the hobgoblin of small minds.




Re: RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Andreas Schwab
Linda Walsh b...@tlinx.org writes:

 I would prefer this work:

 a=h.

 if [[ hi =~ $a ]];

This works (both with and without compat31):

[[ hi =~ $a ]]  echo matches

(It doesn't matter how you quote the lhs, anyway.)

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.



Re: RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Marc Herbert
Le 04/08/2010 09:27, Davide Brini a écrit :

 From the Changelog:
 
 This document details the changes between this version, bash-3.2-alpha,
 and the previous version, bash-3.1-release.
 ...
 3.  New Features in Bash
 ...
 f.  Quoting the string argument to the [[ command's  =~ operator now forces
 string matching, as with the other pattern-matching operators.

Yet on 3.2.39 (Fedora 10) the old quoted regex behaviour was still there:

echo $BASH_VERSION 
shopt  compat31
w=/home/law/bin/package: line 5: type: xx: not found
[[ $w =~ .*not found.* ]]  echo match


3.2.39(1)-release
compat31off
match





Re: Issues when func name is the same with an alias

2010-08-04 Thread Marc Herbert
Le 04/08/2010 11:39, Clark J. Wang a écrit :

 Seems like I must explicitly use the `function' keyword to define foo() for
 this scenario. Is that the correct behavior?

The correct behaviour is simply not to use aliases, since they bring nothing
to the table compared to functions. Have a look at this:
http://thread.gmane.org/gmane.comp.shells.bash.bugs/13865/focus=13901


About the function keyword have a look at the discussion two days ago.





Re: Issues when func name is the same with an alias

2010-08-04 Thread Bernd Eggink

Am 04.08.2010 12:39, schrieb Clark J. Wang:

I was testing the precedence between functions and aliases so I tried like
this (with bash 4.1.5):

$ cat rc
alias foo='echo this is the alias'

foo()
{
 builtin echo 'this is the function'
}

foo
$ source rc
bash: confusing-aliases-2.sh: line 4: syntax error near unexpected token `('
bash: confusing-aliases-2.sh: line 4: `foo()'
$

Seems like I must explicitly use the `function' keyword to define foo() for
this scenario. Is that the correct behavior?


The man page says The first word of a simple command, if unquoted, is 
checked to see if has an alias. Therefore 'foo' in your function 
declaration is replaced by 'echo this is the alias'. Unfortunately, you 
can't quote the function name in the declaration, so you have to either 
use 'function' or say unalias foo first.


Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Greg Wooledge
On Wed, Aug 04, 2010 at 02:02:39AM -0700, Linda Walsh wrote:
 Other string operators?  What other ones operate this way?
 
 This is what I'm referring to:
 
 a=hi
 if [[ hi == $a ]]; then echo this matches; fi
 if [[ 'hi' == '$a' ]] then echo this doesn't; fi

You are misunderstanding the role of quotes.  Double quotes and single
quotes have some things in common:

 * They cause the content inside of them to be treated as a single word,
   instead of potentially multiple words.

 * They cause shell/pattern metacharacters such as space, asterisk,
   parentheses, braces, brackets, etc. to be treated as literal.

And one thing different:

 * Double quotes permit `...` and $ substitutions to occur.  Single do not.

In your examples, '$a' is matched as the literal string dollar-sign a.
$a is matched as a *string* (not a pattern) whose value is the content
of the variable a.

The example you did NOT show is:

  if [[ hi == $a ]]; then ...

In that one, the $a is matched as a *pattern* (not a string) whose value
is the content of the variable a.  That is the significance of the double
quotes, or their lack.

In action:

  imadev:~$ a='*a'
  imadev:~$ if [[ baa = $a ]]; then echo yes; else echo no; fi
  no
  imadev:~$ if [[ baa = $a ]]; then echo yes; else echo no; fi
  yes

 I would prefer this work:
 
 a=h.
 
 if [[ hi =~ $a ]];

Quoting the right hand side makes bash treat the contents of a as a
string rather than a pattern.  If you want the contents treated as a
pattern (or in this case, an ERE) then remove the quotes.

  a='^h.$'
  if [[ hi =~ $a ]]; ...

In fact, putting the ERE-pattern you want to match against into a variable
and then using =~ $variable *is* the recommended practice, if you need to
use =~ at all.  It is the only way to get consistent results among all
the different releases of bash that have =~, since the behavior changed
multiple times during the 3.x series.

In this particular case, I would use a glob rather than an ERE, because
h? is much simpler than ^h.$.



Re: Issues when func name is the same with an alias

2010-08-04 Thread Eric Blake
On 08/04/2010 05:03 AM, Marc Herbert wrote:
 Le 04/08/2010 11:39, Clark J. Wang a écrit :
 
 Seems like I must explicitly use the `function' keyword to define foo() for
 this scenario. Is that the correct behavior?
 
 The correct behaviour is simply not to use aliases, since they bring nothing
 to the table compared to functions.

Not _quite_ true - there are a few things aliases can do that functions
cannot, and when combined, you can get some cool interactive effects
(although I don't recommend relying on this in scripts):
http://www.chiark.greenend.org.uk/~sgtatham/aliases.html

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: Issues when func name is the same with an alias

2010-08-04 Thread Bernd Eggink

Am 04.08.2010 15:13, schrieb Eric Blake:

On 08/04/2010 05:03 AM, Marc Herbert wrote:

Le 04/08/2010 11:39, Clark J. Wang a écrit :


Seems like I must explicitly use the `function' keyword to define foo() for
this scenario. Is that the correct behavior?


The correct behaviour is simply not to use aliases, since they bring nothing
to the table compared to functions.


Not _quite_ true - there are a few things aliases can do that functions
cannot, and when combined, you can get some cool interactive effects
(although I don't recommend relying on this in scripts):
http://www.chiark.greenend.org.uk/~sgtatham/aliases.html


Interesting article. One thing not mentioned there is declarations.

alias assoc='declare -A '
assoc x y z

Not particularly useful, but you can't replace that with a function (as 
long as there is no 'global' option for declare).


Bernd

--
Bernd Eggink
http://sudrala.de



Re: Issues when func name is the same with an alias

2010-08-04 Thread Clark J. Wang
On Wed, Aug 4, 2010 at 7:03 PM, Marc Herbert marc.herb...@gmail.com wrote:

 Le 04/08/2010 11:39, Clark J. Wang a écrit :

  Seems like I must explicitly use the `function' keyword to define foo()
 for
  this scenario. Is that the correct behavior?

 The correct behaviour is simply not to use aliases, since they bring
 nothing
 to the table compared to functions. Have a look at this:
 http://thread.gmane.org/gmane.comp.shells.bash.bugs/13865/focus=13901

 I do not agree. Aliases are much simpler to use than functions. I use
almost all (51 out of 52) the single letters ([:alpha:]) to define aliases.
I would not like a shell which has no aliases support.


 About the function keyword have a look at the discussion two days ago.



The usage of [[ (not with if)

2010-08-04 Thread Peng Yu
Hello All,

I have the following script and output. The man page says Return  a
status  of  0 or 1 depending on the evaluation of the conditional
expression expression. Therefore, I thought that the two printf
statements should print 1 and 0 respectively. But both of them print
0. I'm wondering what [[ should return if it is not used with a if
statement.

$ cat main.sh
#!/usr/bin/env bash

printf '%d\n' `[[ 10 -gt 1 ]]`
printf '%d\n' `[[ 1 -gt 10 ]]`
if [[ 10 -gt 1 ]]
then
  echo xxx
fi
$ ./main.sh
0
0
xxx

-- 
Regards,
Peng



Re: The usage of [[ (not with if)

2010-08-04 Thread Davide Brini
On Wednesday 04 Aug 2010 16:03:25 Peng Yu wrote:
 
 I have the following script and output. The man page says Return  a
 status  of  0 or 1 depending on the evaluation of the conditional
 expression expression. Therefore, I thought that the two printf
 statements should print 1 and 0 respectively. But both of them print
 0. I'm wondering what [[ should return if it is not used with a if
 statement.
 
 $ cat main.sh
 #!/usr/bin/env bash
 
 printf '%d\n' `[[ 10 -gt 1 ]]`
 printf '%d\n' `[[ 1 -gt 10 ]]`
 if [[ 10 -gt 1 ]]
 then
   echo xxx
 fi
 $ ./main.sh
 0
 0
 xxx

You're confusing return value of the command with output of the command.

-- 
D.



Re: The usage of [[ (not with if)

2010-08-04 Thread Bob Proulx
Peng Yu wrote:
 I have the following script and output. The man page says Return  a
 status  of  0 or 1 depending on the evaluation of the conditional
 expression expression. Therefore, I thought that the two printf
 statements should print 1 and 0 respectively. But both of them print
 0. I'm wondering what [[ should return if it is not used with a if
 statement.

The problem is that you have confused the character output to stdout
with the exit code status return of the program.

 $ cat main.sh
 #!/usr/bin/env bash
 
 printf '%d\n' `[[ 10 -gt 1 ]]`
 printf '%d\n' `[[ 1 -gt 10 ]]`

The backticks invoke the command, save the character output to stdout,
replace the backticks with that output.  The exit code is not used in
your example.  The output of those is nothing.  When printf evaluates
nothing as an integer it resolves to 0 and therefore 0 is output.

Look at this:

  $ [[ 10 -gt 1 ]]
  $ [[ 1 -gt 10 ]]

Neither of those produce any output.

  $ printf '%d\n' 
  0

To print the exit code you would need something like this:

  $ [[ 10 -gt 1 ]] ; echo $?
  0
  $ [[ 1 -gt 10 ]] ; echo $?
  1

Bob



Re: The usage of [[ (not with if)

2010-08-04 Thread Andreas Schwab
Bob Proulx b...@proulx.com writes:

 Neither of those produce any output.

   $ printf '%d\n' 
   0

Since the command substitution is not quoted the result of the expansion
is subject to field splitting, thus expands to nothing at all instead of
a single empty argument.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.



Re: The usage of [[ (not with if)

2010-08-04 Thread Bob Proulx
Andreas Schwab wrote:
 Bob Proulx writes:
  Neither of those produce any output.
 
$ printf '%d\n' 
0
 
 Since the command substitution is not quoted the result of the expansion
 is subject to field splitting, thus expands to nothing at all instead of
 a single empty argument.

Ah, yes, you are right of course.  I should have said:

  $ printf '%d\n'
  0

Thanks!
Bob



Re: Issues when func name is the same with an alias

2010-08-04 Thread Bernd Eggink

Am 04.08.2010 16:38, schrieb Clark J. Wang:

On Wed, Aug 4, 2010 at 8:27 PM, Bernd Egginkmono...@sudrala.de  wrote:


Am 04.08.2010 12:39, schrieb Clark J. Wang:

  I was testing the precedence between functions and aliases so I tried like

this (with bash 4.1.5):

$ cat rc
alias foo='echo this is the alias'

foo()
{
 builtin echo 'this is the function'
}

foo
$ source rc
bash: confusing-aliases-2.sh: line 4: syntax error near unexpected token
`('
bash: confusing-aliases-2.sh: line 4: `foo()'
$

Seems like I must explicitly use the `function' keyword to define foo()
for
this scenario. Is that the correct behavior?



The man page says The first word of a simple command, if unquoted, is
checked to see if has an alias. Therefore 'foo' in your function
declaration is replaced by 'echo this is the alias'. Unfortunately, you
can't quote the function name in the declaration, so you have to either use
'function' or say unalias foo first.


Function definitions are not simple commands. Actually, func definition
syntax is listed under the *Compound Commands* section in bash2.05b's man
page and in bash3+ it's been moved to a separate section.


The function *body* as part of the definition is a compound command. The 
definition as a whole constitutes a simple comand. You can see that 
function definitions are not listed under compound commands, but 
adhere to the definition of simple commands:


A  simple  command is a sequence of optional variable assignments 
followed by blank-separated words and redirections, and terminated by a 
control operator.


Some lines above '(' is listed as a control operator.

The only questionable term is ...a sequence of optional variable 
assignments followed by..., as it appears that variable assignments are 
not allowed before a function definition.


I suppose that is just a documentation issue. Can anybody comment on this?

Regards,
Bernd

--
Bernd Eggink
http://sudrala.de



Re: Bad performance for substring replacement by pattern

2010-08-04 Thread Chet Ramey
On 8/3/10 5:23 PM, Eric Blake wrote:

 But why not teach the matcher the difference between a fixed-length
 pattern, vs. one that has * or other extended globbing that would cause
 a variable length match?  That is, since you know that [^;] can match at
 most one character, there is no need to search from the current position
 to the end of the string on each iteration - just search the first byte
 of the string.

I could do that, and that's probably the best way to approach this, but
it doesn't exist in the current implementation.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: Issues when func name is the same with an alias

2010-08-04 Thread Chet Ramey
On 8/4/10 10:38 AM, Clark J. Wang wrote:

 Function definitions are not simple commands. Actually, func definition
 syntax is listed under the *Compound Commands* section in bash2.05b's man
 page and in bash3+ it's been moved to a separate section.

While technically true, that doesn't enter into the issue.  At the time
a word is read, the parser can't tell whether or not it introduces a
simple command or function definition.  Posix, for instance, explicitly
notes that alias expansion is performed before examining any grammar rules,
and certainly without performing any lookahead.  I probably cribbed the
simple command language from Posix, which doesn't allow reserved words,
which introduce compound commands, to be aliased.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~

2010-08-04 Thread Chet Ramey
On 8/4/10 8:31 AM, Greg Wooledge wrote:

 In fact, putting the ERE-pattern you want to match against into a variable
 and then using =~ $variable *is* the recommended practice, if you need to
 use =~ at all.  It is the only way to get consistent results among all
 the different releases of bash that have =~, since the behavior changed
 multiple times during the 3.x series.

All this is true (as is the text I removed), except that the behavior
changed only once: to make quoted text remove any special meaning of
the quoted characters to the regular expression matcher.

Backwards compatibility, of course, means never having to say you're sorry,
but it also means that you never get to fix anything.  The behavior change
fixed a problem, as I saw it, with the initial implementation.  Without
this change, there is no clean way to match a literal character that has a
special meaning as a regexp operator.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/