Development version of bash is very slow in running autoconf-generated scripts
Compared with Bash 4.2, the development version of bash is very slow in running autoconf-generated configure scripts (or, to be more precise, that's where I noticed the slowness; it might very well be more generalized, but I haven't checked for that). Some numbers: $ /bin/bash -c 'echo $BASH_VERSION' 4.2.45(1)-release $ time CONFIG_SHELL=/bin/bash /bin/bash \ ./configure CONFIG_SHELL=/bin/bash ... real 1m10.935s user 0m29.738s sys 0m12.669s $ $HOME/bleeding/bin/bash -c 'echo $BASH_VERSION' 4.3.0(1)-alpha $ time CONFIG_SHELL=$HOME/bleeding/bin/bash $HOME/bleeding/bin/bash \ ./configure CONFIG_SHELL=$HOME/bleeding/bin/bash ... real 4m45.671s user 4m22.744s sys 0m17.753s Four times slower, yikes. Any idea where these numbers might be coming from? Regards, Stefano
Re: Development version of bash is very slow in running autoconf-generated scripts
On 05/06/2013 12:33 PM, Andreas Schwab wrote: Stefano Lattarini stefano.lattar...@gmail.com writes: Four times slower, yikes. Any idea where these numbers might be coming from? Try building without debugging options (make DEUBG= MALLOC_DEBUG=) Thanks! This solved the issue (after s/DEUBG/DEBUG/). So it was a PEBKAC after all :-) Best regards, Stefano
Re: Regression in development version of bash w.r.t. associative hashes
On 05/06/2013 10:00 PM, Chet Ramey wrote: On 5/3/13 5:48 AM, Stefano Lattarini wrote: [+cc bug-gnulib, see below for a reason] Minimal reproducer of the regression: $ cat foo.bash echo $BASH_VERSION declare -A hash echo ${hash[a/b]} echo $? $ /bin/bash foo.bash 4.2.45(1)-release 0 $ ~/bleeding/bin/bash foo.bash 4.3.0(1)-alpha foo.bash: line 3: a/b: division by 0 (error token is b) 1 Notice that the new behaviour breaks the gnulib-tool script (that's how I noticed this regression). You're just not bleeding-edge enough. :-) That problem was fixed several weeks ago as part of the ongoing cleanup of `invisible placeholder' variables (variables with attributes but no values, which are technically unset). Indeed, I had forgotten to git pull. Everything seems to work fine with the latest 'devel' branch. Thanks, and sorry for the noise, Stefano
Regression in development version of bash w.r.t. associative hashes
[+cc bug-gnulib, see below for a reason] Minimal reproducer of the regression: $ cat foo.bash echo $BASH_VERSION declare -A hash echo ${hash[a/b]} echo $? $ /bin/bash foo.bash 4.2.45(1)-release 0 $ ~/bleeding/bin/bash foo.bash 4.3.0(1)-alpha foo.bash: line 3: a/b: division by 0 (error token is b) 1 Notice that the new behaviour breaks the gnulib-tool script (that's how I noticed this regression). Regards, Stefano
Re: weird problem -- path interpretted/eval'd as numeric expression
On 03/29/2013 12:57 PM, Greg Wooledge wrote: On Fri, Mar 29, 2013 at 12:41:46AM -0700, Linda Walsh wrote: include was designed to search the path for functions that are relative paths. While the normal sourcepath allows searching for filenames on the search path, I don't believe (please correct if I am wrong and this works now, as it would make life much simpler) that the PATH will be searched if you give it something like: source lib/Util/sourcefile.shh Is that all you want? Here: include() { local paths dir IFS=: read -ra paths $PATH for dir in ${paths[@]}; do if [[ -r $dir/$1 ]]; then source $dir/$1 return fi done echo could not find '$1' in PATH 2 return 1 } AFAIK, this won't work if the sourced file contains declarations like 'declare -a foo=(1 2)'; those variables will be made local to the 'include' function. Perhaps an alias could work better (but writing it might involve some unpleasant tricks with eval etc.) Regards, Stefano
Re: Question about the return value of 'local'
On 12/14/2012 06:07 PM, Bill Gradwohl wrote: I'm not trying to start a war, but ... Has anyone entertained the idea of getting rid of the man pages and the info system? Those are relics of the tty era. Don't make the error of confusing the texinfo system with just the info format. I, for one, *never* read pages in the info format. However, I never had any problem reading the official documentation of GNU packages -- I just read the HTML version that is generated by exactly the same texinfo sources used to generate the info pages (as well as the PDF manuals for printing are). [SNIP] A WIKI set up could allow people to augment the docs with some authority then editing the content to keep it up to some standard. Greg's site is excellent, as are several others, and that's the issue. There is no one authoritative place to go to get the OFFICIAL docs in a modern form. What's wrong with http://www.gnu.org/software/bash/manual/bashref.html? Or, if you want a local version, just install the 'bash-doc' package on Debian (or the equivalent package that surely comes with other distros). Who wants to learn how to write and submit man or info docs when the future is clearly html, especially when neither man nor info has the rendering capability html has? Nobody writes info directly; one writes Texinfo, and that can be automatically translated to info, html, PDF (and PostScript and DVI too, not that it matters today). And I must say that I find the HTML generated from texinfo sources of high quality (nor perfect, granted, but definitely good enough). Writing something directly in HTML seems absurd today, IMHO. We want higher-level languages, and Texinfo is an excellent example of such a language, at least for most technical manuals. If the Linux community as a whole missed one technical release cycle to instead concentrate on properly documenting what already exists, the effort would pay off in spades for all future releases. I don't see how HTML-only documentation would be an improvement; it would be a huge step back, actually. Regards, Stefano
Re: Question about the return value of 'local'
On 12/14/2012 06:58 PM, Bill Gradwohl wrote: My point was to DESIGN for html and the rich environment it offers, not to try to convert a Model T into a Mercedes. I'm not wild about a wiki either, if its a free for all. If on the other hand, it is a submission platform that gets reviewed and edited by the developers then it's possibly of benefit, especially for examples. The best technical document I ever encountered was the DOS C compiler from Microsoft over 20 years ago. At about 1.5 thick, the book that came with it was excellent. I kept the book long after I ditched the compiler. Every item listed in the index had sample code associated with it that not only showed how to use the item, but also provided examples for the boundary conditions that reinforced what the documentation said. AFAICS, there's nothing in Texinfo preventing a developer from writing such an excellent documentation; what prevents it is typically the fact that writing good documentation is hard, subtly complex, time consuming, and tiring. No silver bullet for that; a tool or a format can only remove the non-essential, mundane difficulties, not the intrinsic ones. Absolutely excellent documentation. It used the KR style but applied it to the entire subroutine library. Regards, Stefano
documentation bug (uid resetting in posix mode)
From experimenting, I've found out that bash (4.2.20), when invoked as sh, doesn't reset the effective user id to the real user id, even if called *without* the '-p' option. This behaviour seems consistent with that of other POSIX shells like dash (0.5.7) and ksh (JM 93u+ 2012-02-29), so I believe bash is correct here. However, I couldn't find mention of such behaviour in the manual, which is rather confusing. Am I missing something, or have I found a bug in the manual? Regards, Stefano
Re: documentation bug (uid resetting in posix mode)
On 10/30/2012 06:28 PM, Andreas Schwab wrote: Stefano Lattarini stefano.lattar...@gmail.com writes: $ ./system-suid [8204] ruid = 1000, euid = 0, suid = 0 Looks like your /bin/sh is broken. How broken exactly? Honest question. Anyway, my /bin/sh is bash ... $ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Jul 8 2010 /bin/sh - bash $ /bin/sh --version GNU bash, version 4.2.20(1)-release (i486-pc-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. I'm on Debian Unstable BTW (sorry for not specifying that earlier). Let me know if you need more information. Regards, Stefano
Re: documentation bug (uid resetting in posix mode)
Hi Bob, thanks for the tips. However ... On 10/30/2012 07:37 PM, Bob Proulx wrote: Stefano Lattarini wrote: Anyway, my /bin/sh is bash ... $ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Jul 8 2010 /bin/sh - bash I'm on Debian Unstable BTW (sorry for not specifying that earlier). Let me say this aside on the issue since there is opportunity for some confusion. On Debian the default for new installations is that /bin/sh is a symlink to dash. But existing systems that are upgraded will not get this change automatically and will remain as a symlink to bash. It must be specifically selected if desired. ... I'm not so sure all of scripts on my system are exempt from bashisms; so rather than risking obscure bugs, I'll keep bash as my system shell (for the current system, at least). If it ain't broken, don't fix it ;-) Best regards, Stefano
[PATCH 1/3] build: use configure.ac, not configure.in
Support for the latter name will soon start to cause warnings in Autoconf and Automake, and will likely be later removed altogether in future versions of those packages. For more reference, see: https://lists.gnu.org/archive/html/autoconf-patches/2012-05/msg4.html https://lists.gnu.org/archive/html/automake-patches/2012-06/msg4.html Copyright-paperwork-exempt: yes Signed-off-by: Stefano Lattarini stefano.lattar...@gmail.com --- INSTALL | 4 ++-- MANIFEST | 2 +- Makefile.in | 4 ++-- configure.in = configure.ac | 0 doc/bashref.texi | 4 ++-- support/mkconffiles | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename configure.in = configure.ac (100%) diff --git a/INSTALL b/INSTALL index 16fa685..05e741c 100644 --- a/INSTALL +++ b/INSTALL @@ -47,8 +47,8 @@ out how `configure' could check whether or not to do them, and mail diffs or instructions to bash-maintain...@gnu.org so they can be considered for the next release. -The file `configure.in' is used to create `configure' by a program -called Autoconf. You only need `configure.in' if you want to change it +The file `configure.ac' is used to create `configure' by a program +called Autoconf. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of Autoconf. If you do this, make sure you are using Autoconf version 2.50 or newer. diff --git a/MANIFEST b/MANIFEST index 11fd275..200e09c 100644 --- a/MANIFEST +++ b/MANIFEST @@ -51,7 +51,7 @@ READMEf RBASH f AUTHORSf Y2Kf -configure.in f +configure.ac f configure f 755 Makefile.inf config-top.h f diff --git a/Makefile.in b/Makefile.in index 9f9276d..04901a7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,6 +1,6 @@ # Makefile for bash-4.2, version 4.4 # -# Copyright (C) 1996-2010 Free Software Foundation, Inc. +# Copyright (C) 1996-2012 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -710,7 +710,7 @@ pathnames.h:Makefile $(srcdir)/pathnames.h.in @${RM} pathnames.tmp # comment out for distribution -$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4 $(srcdir)/config.h.in +$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4 $(srcdir)/config.h.in cd $(srcdir) autoconf # for chet diff --git a/configure.in b/configure.ac similarity index 100% rename from configure.in rename to configure.ac diff --git a/doc/bashref.texi b/doc/bashref.texi index ae982d5..5448302 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -7232,9 +7232,9 @@ to do them, and mail diffs or instructions to @email{bash-maintainers@@gnu.org} so they can be considered for the next release. -The file @file{configure.in} is used to create @code{configure} +The file @file{configure.ac} is used to create @code{configure} by a program called Autoconf. You only need -@file{configure.in} if you want to change it or regenerate +@file{configure.ac} if you want to change it or regenerate @code{configure} using a newer version of Autoconf. If you do this, make sure you are using Autoconf version 2.50 or newer. diff --git a/support/mkconffiles b/support/mkconffiles index 9eb2231..59e4c0f 100755 --- a/support/mkconffiles +++ b/support/mkconffiles @@ -1,7 +1,7 @@ #! /bin/sh # # mkconffiles - create _distribution and _patchlevel files in preparation -# for recreating `configure' from `configure.in' +# for recreating `configure' from `configure.ac' # # options: # -s srcdir directory where `configure' resides (defaults to `.') -- 1.7.12
[PATCH 3/3] docs: regenerate text documentation (but not PDF, DVI nor PostScript)
Signed-off-by: Stefano Lattarini stefano.lattar...@gmail.com --- doc/bash.html| 54 ++--- doc/bashref.html | 28 +++-- doc/bashref.info | 329 --- 3 files changed, 227 insertions(+), 184 deletions(-) diff --git a/doc/bash.html b/doc/bash.html index d1b6489..2f88c4e 100644 --- a/doc/bash.html +++ b/doc/bash.html @@ -42,7 +42,7 @@ bash - GNU Bourne-Again SHell H3COPYRIGHT/H3 -Bash is Copyright #169; 1989-2010 by the Free Software Foundation, Inc. +Bash is Copyright #169; 1989-2011 by the Free Software Foundation, Inc. A NAME=lbAEnbsp;/A H3DESCRIPTION/H3 @@ -1907,7 +1907,6 @@ this instance of The values assigned to the array members are as follows: P DL COMPACTDTDD - DL COMPACT DTBBASH_VERSINFO[/B0] @@ -1936,7 +1935,6 @@ The value of FONT SIZE=-1BMACHTYPE/B. /FONT - /DL/DL DTBBASH_VERSION/B @@ -2917,6 +2915,7 @@ If this variable is not set, Bbash/B acts as if it had the value B$aq\nreal\t%3lR\nuser\t%3lU\nsys %3lSaq/B. If the value is null, no timing information is displayed. A trailing newline is added when the format string is displayed. + DTBTMOUT/B DD @@ -3138,6 +3137,10 @@ option to specify an indexed array and a B-A/B option to specify an associative array. +If both options are supplied, +B-A/B + +takes precedence. The Bread/B @@ -3432,7 +3435,7 @@ a level of variable indirection is introduced. expanded and that value is used in the rest of the substitution, rather than the value of Iparameter/I itself. This is known as Iindirect expansion/I. -The exceptions to this are the expansions of ${B!\fPfIprefix/BB*/B} and +The exceptions to this are the expansions of ${B!/BIprefix/IB*/B} and ${B!/BIname/I[I@/I]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection. @@ -3741,8 +3744,6 @@ array in turn, and the expansion is the resultant list. ICommand substitution/I allows the output of a command to replace the command name. There are two forms: -P - DL COMPACTDTDD P @@ -5455,7 +5456,6 @@ arguments, if any. The shell has an Iexecution environment/I, which consists of the following: - DL COMPACT DT*DD open files inherited by the shell at invocation, as modified by @@ -9276,12 +9276,12 @@ with the exceptions that B+a/B may not be used to destroy an array variable and B+r/B will not remove the readonly attribute. When used in a function, makes each -Iname/I local, as with the +Iname/I local, as with the Blocal/B command, -unless the B-gP option is supplied, -If a variable name is followed by =/BIvalue/I, the value of +unless the B-g/B option is supplied, +If a variable name is followed by =Ivalue/I, the value of the variable is set to Ivalue/I. The return value is 0 unless an invalid option is encountered, an attempt is made to define a function using @@ -9990,11 +9990,14 @@ Display the description of each Ipattern/I in a manpage-like format DD Display only a short usage synopsis for each Ipattern/I -/DL/DL +/DL +P The return status is 0 unless no command matches Ipattern/I. +/DL + DTBhistory [/BIn/I]DD DTBhistory/B B-c/BDD @@ -10695,7 +10698,7 @@ times out (in which case the return code is greater than 128), or an invalid file descriptor is supplied as the argument to B-u/B. /DL -DTBreadonly/B [B-aApf/B] [Iname/I[=Iword/I] ...]DD +DTBreadonly/B [B-aAf/B] [B-p/B] [Iname/I[=Iword/I] ...]DD The given Inames/I are marked readonly; the values of these @@ -10715,6 +10718,10 @@ option restricts the variables to indexed arrays; the B-A/B option restricts the variables to associative arrays. +If both options are supplied, +B-A/B + +takes precedence. If no Iname/I @@ -10722,6 +10729,8 @@ arguments are given, or if the B-p/B option is supplied, a list of all readonly names is printed. +The other options may be used to restrict the output to a subset of +the set of readonly names. The B-p/B @@ -11432,7 +11441,6 @@ and the effect of interrupting a command list. DTBcompat41/B DD -@item compat41 If set, Bbash/B, @@ -11441,6 +11449,19 @@ parameter expansion as a special character. The single quotes must match (an even number) and the characters between the single quotes are considered quoted. This is the behavior of posix mode through version 4.1. The default bash behavior remains as in previous versions. +DTBdirexpand/B + +DD +If set, +Bbash/B + +replaces directory names with the results of word expansion when performing +filename completion. This changes the contents of the readline editing +buffer. +If not set, +Bbash/B + +attempts to preserve what the user typed. DTBdirspell/B DD @@ -11562,7 +11583,7 @@ This option is enabled by default. DD If set, the pattern B**/B used in a pathname expansion context will -match a files and zero or more directories and subdirectories. +match all files and zero or more directories and subdirectories. If the pattern is followed
Re: cd // produces unexpected results
On 06/22/2012 09:47 PM, Chet Ramey wrote: By accident I keyed in : cd // and noticed that my prompt included both slashes. Posix says shells have to leave two leading slashes in a pathname alone. Three or more can be collapsed to one, but two have to stay unchanged. This has come up multiple times in the past. A little more info, quoting from the Autoconf manual: POSIX lets implementations treat leading // specially, but requires leading /// and beyond to be equivalent to /. Most Unix variants treat // like /. However, some treat // as a super-root that can provide access to files that are not otherwise reachable from /. The super-root tradition began with Apollo Domain/OS, which died out long ago, but unfortunately Cygwin has revived it. HTH, Stefano
Re: Determine if a file is a valid Bash script
On 03/19/2012 08:54 PM, Lane Schwartz wrote: Hi, If I have a file that contains a bash script, is there any straightforward way of determining whether that script can be parsed successfully as a Bash script, without actually running the file? Yes: the -n option. Simple examples: $ echo 'if :; then echo not seen; fi' | bash -n; echo status: $? status: 0 $ echo 'if :; then echo not seen' | bash -n; echo status: $? bash: line 2: syntax error: unexpected end of file status: 2 The bash manual should provide more details. HTH, Stefano
Re: bash 4.2 breaks source finding libs in lib/filename...
On 03/03/2012 08:28 AM, Pierre Gaston wrote: On Fri, Mar 2, 2012 at 9:54 AM, Stefano Lattarini wrote: Or here is a what it sounds as a marginally better idea to me: Bash could start supporting a new environment variable like BASHLIB (a' la' PERL5LIB) or BASHPATH (a' la' PYTHONPATH) holding a colon separated (or semicolon separated on Windows) list of directories where bash will look for sourced non-absolute files (even if they contain a pathname separator) before (possibly) performing a lookup in $PATH and then in the current directory. Does this sounds sensible, or would it add too much complexity and/or confusion? It could be even furthermore separated from the traditional source and a new keyword introduced like require This might be a slightly better interface, yes. a la lisp which would be able to do things like: 1) load the file, searching in the BASH_LIB_PATH (or other variables) for a file with optionally the extension .sh or .bash 2) only load the file if the feature as not been provided, eg only load the file once These sound good :-) 3) maybe optionally only load the definition and not execute commands (something I've seen people asking for on several occasions on IRC), for instance that would allow to have test code inside the lib file or maybe print a warning that it's a library not to be executed. (No so important imo) ... and even python don't do that! If people care about making the test code in the module automatically executable when the module is run as a script, they could use an idiom similar to the python one: # For python. if __name__ == __main__: test code ... i.e.: # For bash. if [[ -n $BASH_SOURCE ]]; then test code ... fi I think this would benefit the bash_completion project and help them to split the script so that the completion are only loaded on demand. (one of the goal mentionned at http://bash-completion.alioth.debian.org/ is make bash-completion dynamically load completions) My understanding is that the http://code.google.com/p/bash-completion-lib/project did something like this but that it was not working entirely as they wanted. (I hope some of the devs reads this list) On the other hand, there is the possibility to add FPATH and autoload like in ksh93 ... I haven't think to much about it but my guess is that it would really be easy to implement a module system with that. my 2 centsas I don't have piles of bash lib. Same here -- it was more of a theoretical suggestion, in the category of hey, you know what would be really cool to have? :-) But I don't deeply care about it, personally. Regards, Stefano
Re: bash 4.2 breaks source finding libs in lib/filename...
On 03/02/2012 02:50 AM, Chet Ramey wrote: On 2/29/12 2:42 PM, Eric Blake wrote: In the middle of the histrionics and gibberish, we have the nugget of an actual proposal (thanks, Eric): [to allow `.' to look anchored relative pathnames up in $PATH] About the best we can do is accept a patch (are you willing to write it? if not, quit complaining) that would add a new shopt, off by default, to allow your desired alternate behavior. Maybe we can have a rational discussion about that. Or here is a what it sounds as a marginally better idea to me: Bash could start supporting a new environment variable like BASHLIB (a' la' PERL5LIB) or BASHPATH (a' la' PYTHONPATH) holding a colon separated (or semicolon separated on Windows) list of directories where bash will look for sourced non-absolute files (even if they contain a pathname separator) before (possibly) performing a lookup in $PATH and then in the current directory. Does this sounds sensible, or would it add too much complexity and/or confusion? Regards, Stefano
Re: Bash git repository on savannah
Hello everybody. Just my 2 cents about this ... On Monday 28 November 2011, Chet Ramey wrote: On 11/28/11 4:48 AM, Roman Rakus wrote: On 11/28/2011 06:28 AM, Mike Frysinger wrote: I don't think I'll push every change to git as soon as it happens, but I'm thinking about fairly frequent commits to a `bash-devel' sort of tree. The question is whether or not enough people would be interested in that to make the frequency worth it. i would;) -mike me too OK, that's three. :-) I can't say I'd be really interested, but I surely would be curious, and would greatly appreciate the possibility of peeking into the bash developement process. Apart from that, having a proper, faithful and easily avaiable VCS history would surely help future (so far only hypotetical) maintainers or co-maintainers of Bash. I can say this from experience, since my work as (relatively recent) automake co-maintainer has been and continues to be greatly helped and by the well preserved and fairly complete history in its source repository (history that, BTW, has been successfully preserved in the transition from CVS to git). Regards, Stefano
Re: exit status issue
On Wednesday 23 November 2011, Andreas Schwab wrote: Steven W. Orr ste...@syslang.net writes: I think we're beating this one to death, but I have point out that telling perl to run a print command whose output is redirected by bash is not the same as telling bash to run a builtin echo command that is redirected as an integral operation of the same interpreter. They are really the same, but even if you change it bash still wins: $ bash -c 'echo hello' /dev/full bash: line 0: echo: write error: No space left on device IMO this is not really perl's fault, but rather the programmer's fault, since he has forgotten to check for possible errors. If did, he would get: $ perl -e 'print hello; close(STDOUT) or die $!\n;' /dev/full No space left on device $ echo $? 28 Something similar happens with C, of course, if you forget to check error conditions: $ cat foo.c 'END' #include stdio.h int main (void) { printf(hello\n); return 0; } END $ gcc foo.c $ ./a.out /dev/null # Oops, no error reported. $ cat foo.c 'END' #include stdio.h int main (void) { printf(hello\n); if (fclose(stdout) != 0) perror(Write error); return 0; } END $ gcc foo.c $ ./a.out /dev/null # Error will be reported now. Write error: No space left on device More modern languages, with built-in exception handling, are somewhat better in this regard: $ python3 -c 'print(foo)' /dev/full Exception IOError: (28, 'No space left on device') in ... ignored Just my 2 cents. Regards, Stefano
Re: conditional aliases are broken
Hi Eric. On Thursday 18 August 2011, Eric Blake wrote: On 08/18/2011 08:44 AM, Eric Blake wrote: how do I write a function that would print the same as $ \ls | cat Useless use of cat. This can be done with \ls -1. f(){ for a in $@; do echo $a; done; } Or skip the loop altogether: f(){ printf %s\\n %@; } I think you've made a typo here; it should have been: f () { printf %s\\n $@; } I guess that's what you meant, right? BTW, is this behaviour truly portable to other shells and/or printf utilities? POSIX seems to require it to portable, but you never know ... Regards, Stefano
Re: conditional aliases are broken
On Thursday 18 August 2011, Stefano Lattarini wrote: Hi Eric. On Thursday 18 August 2011, Eric Blake wrote: On 08/18/2011 08:44 AM, Eric Blake wrote: how do I write a function that would print the same as $ \ls | cat Useless use of cat. This can be done with \ls -1. f(){ for a in $@; do echo $a; done; } Or skip the loop altogether: f(){ printf %s\\n %@; } I think you've made a typo here; it should have been: f () { printf %s\\n $@; } I guess that's what you meant, right? BTW, is this behaviour truly portable to other shells and/or printf utilities? POSIX seems to require it to portable, but you never know ... Sorry, I've seen Roman's answer just now; feel free to ignore my mail. Sorry for the noise, Stefano
Re: inconsistent exit status of ((count++))
At Thursday 29 July 2010, Andrew Benton wrote: andy:~$ count=0 andy:~$ ((count++)) andy:~$ echo $? 1 andy:~$ ((count++)) andy:~$ echo $? 0 I don't think it's a bug, it's just an effect of: 1. `((EXPR))' returning a non-zero exit status iff EXPR evaluates to zero, and 2. `var++' being a *post-increment* (i.e. the increment of `var' takes place after its previous value has been substituted in the expression). You can verify this with: $ i=0 $ echo $((i++)) 0 $ echo $i 1 $ echo $((++i)) 2 $ echo $i 2 Fix: This isn't a fix but I can work around this bug if I use ((++count)) Yes, because here `count' is incremented before its value is substituted into the expression. andy:~$ count=0 andy:~$ ((++count)) andy:~$ echo $? 0 andy:~$ HTH, Stefano
Re: inconsistent exit status of ((count++))
At Friday 30 July 2010, Andrew Benton wrote: On 30/07/10 19:55, Stefano Lattarini wrote: At Thursday 29 July 2010, Andrew Benton wrote: andy:~$ count=0 andy:~$ ((count++)) andy:~$ echo $? 1 andy:~$ ((count++)) andy:~$ echo $? 0 I don't think it's a bug, it's just an effect of: 1. `((EXPR))' returning a non-zero exit status iff EXPR evaluates to zero, and BTW, this behaviour is documented here, in the entry `((...))': http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs That makes no sense to me. Why would evaluating an expression have a non-zero exit status if there was no error? It can be very useful for use in conditional or looping constructs, e.g.: if ((verbosity 1)); then echo blah blah... fi Also, non-zero exit status does not necessary indicate a true error in the Unix world (the `grep' utility is a noteworthy and outstanding example). That makes the exit status no use at all for evaluating whether an error has occurred. How can I check for errors if I can't rely on the exit status? How can that not be a bug? It's somewhat of a trade-off; and I hope that my explanation makes it clear that it's a good tradeoff. But then, maybe an exit status of `2' instead of `1' in case of errors in ((...)) would be helpful -- currently the exit status is still `1' also if a real error is present: $ ((1+)); echo \$?=$? bash: ((: 1+: syntax error: operand expected (error token is +) $?=1 Regards, Stefano
Re: inconsistent exit status of ((count++))
At Friday 30 July 2010, Greg Wooledge wrote: On Fri, Jul 30, 2010 at 09:49:22PM +0200, Stefano Lattarini wrote: But then, maybe an exit status of `2' instead of `1' in case of errors in ((...)) would be helpful -- currently the exit status is still `1' also if a real error is present: $ ((1+)); echo \$?=$? bash: ((: 1+: syntax error: operand expected (error token is +) $?=1 Most syntax errors cause the shell to abort right then and there, when in non-interactive mode. Syntax errors inside an arithmetic context don't, which is already weird. If I were going to ask for a change, Well, I wasn't really advocating a change here, since I've never had problems with the current behaviour; I was just pointing out that it is suboptimal. it would be to make them crash the script instead of letting bash continue. This makes sense; now I think that, if there's going to be a change, it should be on the lines proposed by you. Regards, Stefano
Re: bash 3.2.51, ERR traps and subshells
At Tuesday 22 June 2010, Andres P wrote: Bash 4.1 does not set the ERR trap: $ env -i HOME=$HOME TERM=$TERM bash3 \! set -o errexit set -o errtrace TRIGGERED_ERR() { return $?; } trap 'TRIGGERED_ERR' ERR set -o xtrace var=$(false) || true Here, the subshell has (correctly) no way to know that there is a `||' after the command substitution, so it acts like a bare `false' command was used, and the ERR trap is correctly triggered *in the subshell*. echo $? var=$(false || true) # only way of not triggering it... echo $? ! ++ false # Subshell false +++ TRIGGERED_ERR # Ignores outer || true No, it doesen't even see it; the script seen by the subshell consists just of the string false, so there is no `||' the subshell can see. And this seems IMHO quite natural if you remember that the parent shell and the subshell are run in two different proceses. +++ return 1 + var= + true + echo 0 0 # But the entire command line does # not set off errexit ++ false ++ true# Predictable second subshell... + var= + echo 0 0 Before I write a patch, is this bug documented? I could not find it in the archives. Is it a bug at all or is it expected behaviour? I think it's definitely expected behaviour. According to the man page, it is not: The ERR trap is not executed if the failed command is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of a or ⎪⎪ list, But your `false' command is *not* part of such a list: it's part of a *command substitution* that is part of a variable assignement that is part of a `||' list. And is the failure returned by this assingnement that is being ignored thanks to the trailing `|| true'. In fact, if you leave that assingnement alone: var=$(false) you'll see that the ERR trap is executed by both the subshell (for the failed `false') and the parent shell (for the failed `var=$(false)'). For example: $ cat foo.sh 'END' set -o errtrace TRIGGERED_ERR() { echo $BASHPID, $? 2; } trap 'TRIGGERED_ERR' ERR set -x echo parent: $BASHPID 2 var=$(echo child: $BASHPID 2; false) END $ bash foo.sh + echo parent: 20348 parent: 20348 ++ echo child: 20349 child: 20349 ++ false +++ TRIGGERED_ERR +++ echo 20349, 1 # this is the subshell 20349, 1 + var= ++ TRIGGERED_ERR ++ echo 20348, 1 # this is the parent shell 20348, 1 HTH, Stefano
Re: bash 3.2.51, ERR traps and subshells
At Tuesday 22 June 2010, Andres P wrote: On Tue, Jun 22, 2010 at 4:45 AM, Stefano Lattarini stefano.lattar...@gmail.com wrote: ++ false # Subshell false +++ TRIGGERED_ERR # Ignores outer || true No, it doesen't even see it; the script seen by the subshell consists just of the string false, so there is no `||' the subshell can see. And this seems IMHO quite natural if you remember that the parent shell and the subshell are run in two different proceses. Thanks, makes sense. So this is a regression with bash 4? Because as I mentioned, the ERR trap does not trigger at any point in this example. Andres P Sorry, I missed that we were using bash3 in your example! *blush* So obviously I missed the sense of your question, too. And in fact you're right, the ERR trap is not triggered with bash 4 (I'm using version 4.0.28(1)-release). I don't see anything in the NEWS file about it. So I'm joining you in asking if this is a regression. Thanks and sorry for the noise, Stefano
Re: printf does not always display warning messages on write errors
At Thursday 03 September 2009, Chet Ramey chet.ra...@case.edu wrote: Thanks for the report. This will be fixed in the next version. Good! And thanks to you for your quick answers and your useful software. Chet Regards, Stefano
printf does not always display warning messages on write errors
Hi everybody. I found the following bug while running some of my bash scripts on GNU/Linux with stdout redirected to /dev/full, to see if write errors where correctly detected and reported. It turned out that, on write errors, the printf builtin correctly returns a non-zero status (thus my scripts at least had a correct exit status), but unfortunately it does not always display a suitable error message on stderr; in particular, it fails to do so if the printed string does *not* end with a newline. On the contrary, the echo builtin both returns a non-zero status and write a clear error message on standard error, even if called with the `-n' option (so that the printed string does not end with a newline). Examples (tested with both bash 3.2 and bash 4.0, more details about versions and system information will follow): $ ls -l /dev/full crw-rw-rw- 1 root root 1, 7 Sep 2 18:36 /dev/full $ cat printf-bug.sh echo * `type printf` echo * `type echo` # - - - printf x /dev/full echo a:$? printf %s\n x /dev/full echo b:$? echo -n x /dev/full echo c:$? echo x /dev/full echo d:$? # - - - exit 0 $ bash printf-bug.sh # using either bash 4.0 or 3.2 * printf is a shell builtin * echo is a shell builtin a:1 printf-bug.sh: line 6: printf: write error: No space left on device b:1 printf-bug.sh: line 8: echo: write error: No space left on device c:1 printf-bug.sh: line 10: echo: write error: No space left on device d:1 By the way, bash 3.0 behaves far worser (I don't known if you can found this info useful, but anyway here it is): $ bash-3.0 printf-bug.sh * printf is a shell builtin * echo is a shell builtin a:0 b:0 c:1 d:1 Here are the details on my system and the bash shells used. --- Details on operating system: $ uname -s -r -m -o Linux 2.6.26-1-686 i686 GNU/Linux $ lsb_release -i -d -r -c Distributor ID: Debian Description: Debian GNU/Linux testing/unstable Release: testing/unstable Codename: n/a $ cat /etc/debian_version squeeze/sid --- Details on bash versions: Bash 4.0 --- Installed from debian package bash, version 4.0-4 Complete version string: 4.0.28(1)-release Information from bashbug [Automatically generated]: Machine: i486 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall Machine Type: i486-pc-linux-gnu Bash Version: 4.0 Patch Level: 28 Release Status: release Bash 3.2 --- Installed by hand from official tarball. Complete version string: 3.2.0(1)-release Information from bashbug [Automatically generated]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/opt/vintage/bash-3.2/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 Machine Type: i686-pc-linux-gnu Bash Version: 3.2 Patch Level: 0 Release Status: release Bash 3.0 --- Installed by hand from official tarball. Complete version string: 3.00.0(1)-release Information from bashbug [Automatically generated]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/opt/vintage/bash-3.0/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 Machine Type: i686-pc-linux-gnu Bash Version: 3.0 Patch Level: 0 Release Status: release --- Regards, Stefano
Re: 'set -e' and 'trap 0' togheter does not work as expected on syntax errors
At Saturday 22 August 2009, Chet Ramey chet.ra...@case.edu wrote: Stefano Lattarini wrote: I have the following scripts: [CUT] I thought that when bash detect a syntax errors in the script, it would pass a $? != 0 to the code in the exit trap, regardless of whether `set -e' is active or not. It's not exactly a bug -- this behavior isn't standardized anywhere, and historical shells behave differently. The behavior you want is useful enough that I'll change it for bash-4.1, though. Chet Thanks, much appreciated. Oh, and by the way, sorry for the duplicate message. Regards, Stefano
'set -e' and 'trap 0' togheter does not work as expected on syntax errors
I have the following scripts: $ cat nobug.sh trap 'e=$?; [ $e -gt 0 ] echo OK || echo BAD; exit $e' 0 # syntax error here true $ cat bug.sh set -e trap 'e=$?; [ $e -gt 0 ] echo OK || echo BAD; exit $e' 0 # syntax error here true I thought that when bash detect a syntax errors in the script, it would pass a $? != 0 to the code in the exit trap, regardless of whether `set -e' is active or not. But if I run bug.sh with either bash-3.2 or bash-4.0, I get: $ bash bug.sh; echo $? bug.sh: line 4: syntax error near unexpected token `' BAD 0 On the other hand: $ bash nobug.sh; echo $? nobug.sh: line 4: syntax error near unexpected token `' nobug.sh: line 4: ` true' OK 2 $ dash bug.sh; echo $? # Debian Alquist shell, version 0.5 bug.sh: 4: Syntax error: unexpected OK 2 $ zsh bug.sh; echo $? # Zsh, version 4.3 nobug.sh:4: parse error near `' OK 1 I think this can be classified as a bug in bash (in some situations, a very nasty one). Please let me know if I have misunderstood something, or if there is a simple workaround. More details about my environment and bash versions follow... --- Details on operating system: $ uname -s -r -m -o Linux 2.6.26-1-686 i686 GNU/Linux $ lsb_release -i -d -r -c Distributor ID: Debian Description: Debian GNU/Linux testing/unstable Release: testing/unstable Codename: n/a $ cat /etc/debian_version squeeze/sid --- Details on bash versions: Bash 4.0 --- Installed by hand from official tarball Complete version string: 4.0.0(1)-release Information from bashbug [Automatically generated]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/opt/bleedingedge/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I.. -I../include -I../lib -g -O2 Machine Type: i686-pc-linux-gnu Bash Version: 4.0 Patch Level: 0 Release Status: release Bash 3.2 --- Installed from debian package bash, version 3.2-6 Complete version string: 3.2.48(1)-release Information from bashbug [Automatically generated]: Machine: i486 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall Machine Type: i486-pc-linux-gnu Bash Version: 3.2 Patch Level: 48 Release Status: release ---
bug with 'set -e' + 'trap 0' + syntax error
I have the following scripts: $ cat nobug.sh trap 'e=$?; [ $e -gt 0 ] echo OK || echo BAD; exit $e' 0 # syntax error here true $ cat bug.sh set -e trap 'e=$?; [ $e -gt 0 ] echo OK || echo BAD; exit $e' 0 # syntax error here true I thought that when bash detect a syntax errors in a script, it would pass a $? != 0 to the code in the exit trap, regardless of whether `set -e' is active or not. But if I run bug.sh with either bash-3.2 or bash-4.0, I get: $ bash bug.sh; echo $? bug.sh: line 4: syntax error near unexpected token `' BAD 0 On the other hand: $ bash nobug.sh; echo $? nobug.sh: line 4: syntax error near unexpected token `' nobug.sh: line 4: ` true' OK 2 $ dash bug.sh; echo $? # Debian Alquist shell, version 0.5 bug.sh: 4: Syntax error: unexpected OK 2 $ zsh bug.sh; echo $? # Zsh, version 4.3 nobug.sh:4: parse error near `' OK 1 I think this can be classified as a bug in bash (in some situations, a very nasty one). Please let me know if I have misunderstood something, or if there is a simple workaround. More details about my environment and bash versions follow... --- Details on operating system: $ uname -s -r -m -o Linux 2.6.26-1-686 i686 GNU/Linux $ lsb_release -i -d -r -c Distributor ID: Debian Description: Debian GNU/Linux testing/unstable Release: testing/unstable Codename: n/a $ cat /etc/debian_version squeeze/sid --- Details on bash versions: Bash 4.0 --- Installed by hand from official tarball Complete version string: 4.0.0(1)-release Information from bashbug [Automatically generated]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/opt/bleedingedge/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I.. -I../include -I../lib -g -O2 Machine Type: i686-pc-linux-gnu Bash Version: 4.0 Patch Level: 0 Release Status: release Bash 3.2 --- Installed from debian package bash, version 3.2-6 Complete version string: 3.2.48(1)-release Information from bashbug [Automatically generated]: Machine: i486 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall Machine Type: i486-pc-linux-gnu Bash Version: 3.2 Patch Level: 48 Release Status: release ---
Re: bug with 'set -e' + 'trap 0' + syntax error
Stefano Lattarini a écrit : I thought that when bash detect a syntax errors in a script, it would pass a $? != 0 to the code in the exit trap, regardless of whether `set -e' is active or not. [CUT] I think this can be classified as a bug in bash (in some situations, a very nasty one). Please let me know if I have misunderstood something, or if there is a simple workaround. I am not familiar with the standard(s), but... isn't having expectations in the case of syntax errors a bit far-fetched? Well, I'd not expect that the exit trap is executed flawlessly, and not even that it is executed at all, but at least the shell should abort the script and exit with a non-zero status. This is a much more rational approach than having the flawed script exiting sucessfully, IMHO. In fact, I've been bitten by this bug (or limitation) when a stupid syntax error leaked in some scripts part of a testsuite (that was my fault). The scripts erroneously apperead as PASS'd, while they should have been marked as FAIL'd -- a vary bad thing in my opinion. And I discovered the bug only when I tried to run the testsuite with dash, to check its portability. Aside that, the exit trap executes correctly even on bash when `set -e' is not active, which makes the described behaviour seeming more a bug rather than a limitation. By the way, sorry for the duplicate message. Regards, Stefano