RFE: allow double quotes to group multi-words be treated as 1 arg, w/DQ's stripped off -- including RH =~
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 =~
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 =~
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 =~
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 =~
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
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
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 =~
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
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
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
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)
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)
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)
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)
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)
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
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
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
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 =~
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/