bash crashes with named pipes
Maybe I'm doing something wrong, but the following will make bash crash. terminal 2: $ mkfifo test $ while true; do echo foo && sleep 1; done > test terminal 1: $
Helpful app for your dream wedding planning
The wedding planning can be done easily using like wedding planner, wedding app etc. It depends upon the wedding planning people to choose the path, according to their convenient, Budget allocations and their requirement. The best option to plan the wedding is doing by wedding couple itself. They can plan their wedding with the help of "iWedPlanner" wedding app. This wedding app will helpful in all stages of wedding planning. It has the carious features like RSVP, Budget calculation, Creating wedding personnel wedding website, Easy finding of wedding resources, Reminder, Organizer and many more. To get this wedding app(iPhone, iPad, iPod Touch and Android) will available in appstore or get from the given link. http://itunes.apple.com/us/app/iwedplanner-the-wedding-planner/id408373537?mt=8 https://play.google.com/store/apps/details?id=com.sentientit.newiwedplanner(Android) Also Get the useful updates of wedding directly on your facebook http://www.facebook.com/iWedPlanner
Re: [DOC] Incomplete explanation about the regex =~ operator
Le 12/01/2019 à 23:27, Chet Ramey a écrit : On 1/12/19 1:14 AM, kevin wrote: Moreover, the explanation in the Bash FAQ is unclear; it lacks examples to know when "an interference" occurred. What is "an interference"? Look at the following answer to get an overview of the issue: https://stackoverflow.com/a/12696899 That answer is correct: bash uses the C library's regexp library and only guarantees that POSIX EREs work. I do not speak English very well. Your English is fine. The Bash FAQ indicates that the shell works differently in a conditional expression formed using a regular expression. Nonetheless, the Bash FAQ does not give examples to get a concrete idea. I think Greg Wooledge's site has some examples along these lines. |"In versions of bash prior to bash-3.2, the effect of quoting the regular expression argument to the [[ command's =~ operator was not specified. *The practical effect* was that double-quoting the pattern argument required backslashes to quote special pattern characters, *which interfered with* the backslash processing performed by double-quoted word expansion and was inconsistent with how the == shell pattern matching operator treated quoted characters."| I do not see the practical effect because I do not find concrete cases (or examples). In other words, I do not understand the justification. The ambiguity is that the backslash is special to both the shell and the regular expression matching engine. Since double-quoting the pattern enables backslash processing as part of word expansion, what should a string like "abc\$" match? That gets passed to the regular expression engine as "abc$" after being processed by the shell's word expansions. Since the unquoted $ in the pattern means to anchor the pattern at the end of the string, it's ambiguous what the user meant. If you use a literal pattern, you can use single quotes to make your intent clear ('abc\$'), but if you want some expansion to be performed, you have to experiment with the correct number of backslashes to use to get the right pattern passed through to the regexp engine. Beginning with bash-3.2, the behavior of =~ is documented to be the same as ==: quoting any part of the pattern forces it to be matched as a string, which means characters special to regular expressions have to be quoted before they are passed to the regexp matching engine. The shell does this by processing the quoted portions of the pattern and inserting backslashes to quote special pattern characters. Finally, the fact that the shell works differently in the mentioned case should be indicated in the man page and Texinfo source. It is. That is the difference. The effect of quoting characters in the pattern is now specified where it was not in bash-3.1 and earlier versions. I looked at Greg Wooledge's site <https://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29>: Since *[[* isn't a normal command (like [ is), but a /shell keyword/, *it has special magical powers*. *It parses its arguments before they are expanded by Bash and does the expansion itself*, taking the result as a single argument, even if that result contains whitespace. (In other words, [[ does not allow word-splitting of its arguments.) /However/, be aware that simple strings still have to be quoted properly. [[ treats a space outside of quotes as an argument separator, just like Bash normally would. Unfortunately, there is no example that shows how *[[* differs from the usual shell operation. I know that the documentation does not indicate the particular property of "[[" (features), and there has been an adjustment based on the operator "==" concerning "=~" but I still do not understand why we could not have used the normal shell rules. In your example, a user may use single quotes to escape the special meaning of the $ sign "abc'$'".
Re: [DOC] Incomplete explanation about the regex =~ operator
Le 17/01/2019 à 07:53, kevin a écrit : Le 12/01/2019 à 23:27, Chet Ramey a écrit : On 1/12/19 1:14 AM, kevin wrote: Moreover, the explanation in the Bash FAQ is unclear; it lacks examples to know when "an interference" occurred. What is "an interference"? Look at the following answer to get an overview of the issue: https://stackoverflow.com/a/12696899 That answer is correct: bash uses the C library's regexp library and only guarantees that POSIX EREs work. I do not speak English very well. Your English is fine. The Bash FAQ indicates that the shell works differently in a conditional expression formed using a regular expression. Nonetheless, the Bash FAQ does not give examples to get a concrete idea. I think Greg Wooledge's site has some examples along these lines. |"In versions of bash prior to bash-3.2, the effect of quoting the regular expression argument to the [[ command's =~ operator was not specified. *The practical effect* was that double-quoting the pattern argument required backslashes to quote special pattern characters, *which interfered with* the backslash processing performed by double-quoted word expansion and was inconsistent with how the == shell pattern matching operator treated quoted characters."| I do not see the practical effect because I do not find concrete cases (or examples). In other words, I do not understand the justification. The ambiguity is that the backslash is special to both the shell and the regular expression matching engine. Since double-quoting the pattern enables backslash processing as part of word expansion, what should a string like "abc\$" match? That gets passed to the regular expression engine as "abc$" after being processed by the shell's word expansions. Since the unquoted $ in the pattern means to anchor the pattern at the end of the string, it's ambiguous what the user meant. If you use a literal pattern, you can use single quotes to make your intent clear ('abc\$'), but if you want some expansion to be performed, you have to experiment with the correct number of backslashes to use to get the right pattern passed through to the regexp engine. Beginning with bash-3.2, the behavior of =~ is documented to be the same as ==: quoting any part of the pattern forces it to be matched as a string, which means characters special to regular expressions have to be quoted before they are passed to the regexp matching engine. The shell does this by processing the quoted portions of the pattern and inserting backslashes to quote special pattern characters. Finally, the fact that the shell works differently in the mentioned case should be indicated in the man page and Texinfo source. It is. That is the difference. The effect of quoting characters in the pattern is now specified where it was not in bash-3.1 and earlier versions. I looked at Greg Wooledge's site <https://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29>: Since *[[* isn't a normal command (like [ is), but a /shell keyword/, *it has special magical powers*. *It parses its arguments before they are expanded by Bash and does the expansion itself*, taking the result as a single argument, even if that result contains whitespace. (In other words, [[ does not allow word-splitting of its arguments.) /However/, be aware that simple strings still have to be quoted properly. [[ treats a space outside of quotes as an argument separator, just like Bash normally would. Unfortunately, there is no example that shows how *[[* differs from the usual shell operation. I know that the documentation does not indicate the particular property of "[[" (features), and there has been an adjustment based on the operator "==" concerning "=~" but I still do not understand why we could not have used the normal shell rules. In your example, a user may use single quotes to escape the special meaning of the $ sign "abc'$'". I made a mistake (typo): abc'\$'
Suggestion for .bashrc
I see the bash web page on Xubuntu gives this email address for requests and such. Nice. It also gives a usenet group as an alternative. I did not know usenet was still around. Anyway, my problem is thatI have so many things added to my .bashrc (well to .bash_aliases really), and they've become corrupted and tangled over time, that I am reluctant to even look at it. That's not your fault, of course, but there's a simple path that might reduce the likelihood of this happening, and not just for me. It's inspired by the change over time from files named "conf" in favor of directories named conf.d. Things can just be dropped into the directory and they don't have to mess with each other. They can have descriptive names. They can be short. So I propose extending the stanza near the end of .bashrc: if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi by following it with for __bash_alias in ~/.bash_aliases.d/* ; do if [ -f $__bash_alias ]; then source $__bash_alias fi done This would make it possible to keep all of the additions in separate files. It even works for me if the directory is empty or does not exist, so it does not clutter up the dotfile space of folks who don't use it. *Kevin O'Gorman (he/him/his)*
add vi mode refresh command of inputrc to documentation
I believe to be complete, you should add the vi mode refresh command of inputrc to compliment the emacs refresh command you provided on the following page: http://www.gnu.org/software/bash/manual/bashref.html#Readline-Init-File-Syntax 8.3 Readline Init File "In addition, the C-x C-r command re-reads this init file, thus incorporating any changes that you might have made to it." This refresh command you provided, won't work in VI mode. It puts the representation of CTRL-x (^x) on the command line, which I assume means it wasn't interpreted as a command character. CTRL-l, (el), the redraw screen command in VI does not cause bash to re-read its inputrc file either. Of course I would be interested to find out what the command is, but more importantly, I think this information should be provided along with the emacs information. Thanks, Kevin
patch submission: "read -i" feature
rlbuf = edit_line (prompt ? prompt : ""); + rlbuf = edit_line (prompt ? prompt : "", initial); rlind = 0; } if (rlbuf == 0) @@ -689,10 +695,31 @@ #if defined (READLINE) static rl_completion_func_t *old_attempted_completion_function; +static rl_hook_func_t *old_startup_hook; +static char *initial_text; + +int +set_initial_text (void) +{ + int rc1, rc2; + + rc1 = rc2 = 0; + if (old_startup_hook) +rc1 = (*old_startup_hook)(); + if (initial_text) +{ + rc2 = rl_insert_text(initial_text); + initial_text = (char *)NULL; + rl_startup_hook = old_startup_hook; + old_startup_hook = (rl_hook_func_t *)NULL; +} + return rc1 || rc2; +} static char * -edit_line (p) +edit_line (p, i) char *p; + char *i; { char *ret; int len; @@ -701,6 +728,12 @@ initialize_readline (); old_attempted_completion_function = rl_attempted_completion_function; rl_attempted_completion_function = (rl_completion_func_t *)NULL; + if (i) +{ + old_startup_hook = rl_startup_hook; + rl_startup_hook = set_initial_text; + initial_text = i; +} ret = readline (p); rl_attempted_completion_function = old_attempted_completion_function; if (ret == 0) -- .--. | Kevin PuloQuidquid latine dictum sit, altum viditur. | | [EMAIL PROTECTED] _ll l_ng__g_e_ _r_ hi__ly p__d_ct__le. | | http://www.kev.pulo.com.au/ God casts the die, not the dice. | `--- Linux: The choice of a GNU generation. ---' ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Execution continuing after SIGINT received
Hi, I have run into a rather weird behaviour related to SIGINT, which doesn't seem to be intended, as it's not consistent with other shells (and is so unexpected that it took me a while to figure out what was going wrong in my script!). When Bash receives SIGINT while executing a command, it normally waits for the command to complete, and then aborts execution. However, it looks like somehow, this is not the case if the command handles SIGINT, and execution continues after the command completes. For instance: $ bash -c '(trap "echo INT; exit 1" INT; sleep 60s); echo after' ^CINT after $ Whereas: $ bash -c '(sleep 60s); echo after' ^C $ The command doesn't need to be a subshell; for instance, since Python handles SIGINT by default, execution continues as well: $ bash -c 'python -c "import time; time.sleep(60)"; echo after' ^CTraceback (most recent call last): File "", line 1, in KeyboardInterrupt after $ dash, mksh, zsh don't exhibit this behaviour: in all cases, execution is aborted. Bash seems to have always behaved like that, at least since 4.0. Kevin
Re: Execution continuing after SIGINT received
On 05/08/2017 15:53, Chet Ramey wrote: > On 8/4/17 7:52 PM, Kevin Brodsky wrote: > >> When Bash receives SIGINT while executing a command, it normally waits >> for the command to complete, and then aborts execution. However, it >> looks like somehow, this is not the case if the command handles SIGINT, >> and execution continues after the command completes. For instance: > The question of what happens when bash receives SIGINT while waiting for a > foreground job to complete has come up many times in the past. > > See this for a good discussion of the issue: > > https://www.cons.org/cracauer/sigint.html > > The basic idea is that the user intends a keyboard-generated SIGINT to go > to the foreground process; that process gets to decide how to handle it; > and bash reacts accordingly. If the process dies to due SIGINT, bash acts > as if it received the SIGINT; if it does not, bash assumes the process > handled it and effectively ignores it. > > Consider a process (emacs is the usual example) that uses SIGINT for its > own purposes as a normal part of operation. If you run that program in a > script, you don't want the shell aborting the script unexpectedly as a > result. > > Chet Thank you for your answer Chet. The article you linked is extremely informative, I wasn't aware of the various possible strategies shells can use to handle SIGINT! So in summary, there is no bug on the Bash side, it simply implements the WCE strategy, which does what the user wants... as long as the invoked commands are well-behaved! And I just got very unlucky, as I did stumble upon a misbehaved program, and all the other shells I tried don't implement WCE... Some more experimentations showed that all three (dash, mksh and zsh) implement WUE (I would have expected zsh to follow Bash?). Knowing this, it's now clear that the bug is on the Python side, as it uses exit(1) when receiving SIGINT instead of doing the signal()/kill() dance mentioned in the article. Other interpreters like Perl or Ruby behave correctly, which confirms that there's a problem with Python. To be fair, killing oneself when receiving SIGINT is quite counter-intuitive, POSIX is not helping here. Thanks, Kevin
Re: Execution continuing after SIGINT received
On 05/08/2017 03:22, Bob Proulx wrote: > Kevin Brodsky wrote: >> $ bash -c '(trap "echo INT; exit 1" INT; sleep 60s); echo after' >> ^CINT >> after >> $ > This is a good example of a bad example case. You shouldn't "exit 1" > or you will replace the information that the process is exiting due to > a signal with an error code. The trap handler should kill itself > instead. Use this test case instead. > >> $ bash -c '(trap "echo INT; trap - INT; kill -s INT $$" INT; sleep 60); echo >> after' > Of course that doesn't change the end result here. But at least the > program exit WIFSIGNALED information is now correct. > > Signal handlers should always raise the signal on themselves after > handling whatever they need to handle first. > > In any case I can't recreate your problem when using real processes in > separate shells not all on one line. > > Bob You're right Bob, I didn't think about the difference between exit()ing and being kill()ed, notably in terms of WIFSIGNALED. Chet's reply explains well the rationale, and it's now clear that the problem is on Python's side (reproduced in my dummy example!). Thanks, Kevin
Re: Execution continuing after SIGINT received
On 05/08/2017 20:35, Bob Proulx wrote: > > Really? It seems intuitive to me that at any trap handling level one > should handle what needs to be handled and then raise the signal > higher to the next level of the program. Software is all about layers > and abstraction. Sending the signal to one self to raise the signal > again feels good to me. The thing is, "the next level of the program" really is another program, i.e. the one that invoked it, and you are communicating via the exit status, so it's certainly not as explicit as re-throwing an exception in C++, for instance. But sure, once you are aware of this mechanism, it's not difficult to understand the rationale. Actually, IMHO, what makes it look very counter-intuitive is the fact that you need to first reset the signal handler for SIGINT. Of course this is necessary to avoid invoking the handler recursively, but it feels very much like a workaround. WIFSIGNALED is true if "the child process [...] terminated due to the receipt of a signal that was not caught". That's not really what we want to know here; we want to know if the child process received a signal that caused it to terminate. Whether it handled SIGINT to clean up resources is irrelevant; what's relevant is that it eventually terminated as a consequence of SIGINT. Ideally, exit()ing from a signal handler should set a bit in the exit status expressing exactly this. I'll stop digressing, POSIX is what it is and we won't change it anyway ;-) For now, there's no other way to communicate with the shell, so that's fair enough. > POSIX even added a raise(3) call to make this easier. (Although I > still do things the old way.) > > man 3 raise That's a good point, it's arguably more self-explanatory than kill(getpid(), ...). Kevin
simple function causes BASH to exit when -e in effect
The bug happens to me on GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu) and GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.4.0) The script is attached, but the function in question is this: function debug1 { [ "$debug" ] && echo "$(date "+%Y-%m-%d %H:%M:%S"): $@" } If it is defined like this then no problem exists: function debug1 { if [ "$debug" ]; then echo "$(date "+%Y-%m-%d %H:%M:%S"): $@" fi } nor if it is defined like this: function debug1 { [ "$debug" ] && echo "$(date "+%Y-%m-%d %H:%M:%S"): $@" : } When I run the script I see this output: BEFORE test 2 AFTER test 2 BEFORE test 1 but I expected to see BEFORE test 2 AFTER test 2 BEFORE test 1 AFTER test 1 It took me hours of work to distill this down from a very large and long running script. foo.sh is attached. foo.sh Description: Bourne shell script
Re: simple function causes BASH to exit when -e in effect
The man page says: The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !. The fact that [ exits with 1 seems to be covered by the above passage for -e. On Fri, Dec 22, 2017 at 10:50 AM, DJ Mills wrote: > > > On Fri, Dec 22, 2017 at 1:39 PM, Kevin Layer wrote: > >> The bug happens to me on >> GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu) >> and >> GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.4.0) >> >> The script is attached, but the function in question is this: >> >> function debug1 { >> [ "$debug" ] && echo "$(date "+%Y-%m-%d %H:%M:%S"): $@" >> } >> >> > This is expected behavior. When "$debug" is empty, the [ command exits 1. > That means the && isn't > run, and the whole function returns with the status of the last run > command, which is still 1 at this point. > > http://mywiki.wooledge.org/BashFAQ/105 >
Re: simple function causes BASH to exit when -e in effect
Bob, 'set -e' is a double-edged sword, for sure, but I'm not sure it creates more problems than it solves. Hidden non-zero exits have wasted far more time, for me, than this little exercise has. On Sun, Dec 24, 2017 at 11:45 AM, Bob Proulx wrote: > Kevin Layer wrote: > > It took me hours of work to distill this down from a very large and long > > running script. > > > set -eu > > Hours and hours of debug time could be saved if people stopped using > 'set -e' in their programs. It creates more problems than people > think it solves. Do not meddle in the affairs of 'set -e' for it is > subtle and quick to anger. > > Bob >
Error building bash-3.2.52 downloaded/patched from ftp.gnu.org.
Configuration Information [Automatically generated, do not change]: 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='/usr/local/share/locale' -DPACKAGE='b\ ash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 uname output: Linux c2n2 2.4.21-40.ELsmp #1 SMP Thu Feb 2 22:22:39 EST 2006 i686 i686 i386 GNU/Linux Machine Type: i686-pc-linux-gnu Bash Version: 3.2 Patch Level: 52 Release Status: release I downloaded these files from anonym...@ftp.gnu.org:/pub/gnu/bash:- bash-3.2.48.tar.gz bash-3.2-patches/bash32-049 bash-3.2-patches/bash32-050 bash-3.2-patches/bash32-051 bash-3.2-patches/bash32-052 I then ran ³tar zxf bash-3.2.48.tar.gz² to unpack the archive and ³patch p0 < patchfile² for each of the patch files in turn. I then ran ³./configure² and ³make² on a RHEL 3.7 system. I got this error:- gcc -DPROGRAM='"bash"' -DCONF_HOSTTYPE='"i686"' -DCONF_OSTYPE='"linux-gnu"' -DCONF_MACHTYPE='"i686-pc-linux-gnu"' -DCONF_VENDOR='"pc"' -DLOCALEDIR='"/usr/local/share/locale"' -DPACKAGE='"bash"' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 -c y.tab.c /Users/chet/src/bash/src/parse.y: In function `decode_prompt_string': /Users/chet/src/bash/src/parse.y:4333: too few arguments to function `expand_prompt_string' make: *** [y.tab.o] Error 1 [root@c2n2 bash-3.2.52]# gcc --version gcc (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-54) Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. The patch is as follows:- $ git diff master~1 diff --git a/y.tab.c b/y.tab.c index f8db50d..a47a4dd 100644 --- a/y.tab.c +++ b/y.tab.c @@ -5660,7 +5660,7 @@ not_escape: if (promptvars || posixly_correct) { last_exit_value = last_command_exit_value; - list = expand_prompt_string (result, Q_DOUBLE_QUOTES); + list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0); free (result); result = string_list (list); dispose_words (list); I¹ve checked parse.y and the call to expand_prompt_string is correct, so it looks like you¹ve distributed this version without running bison first. My machine has bison installed so I¹m not sure why ³make² didn¹t invoke it. Best regards Kevin Broadey
Follow-up to Non-expanding here-documents inside command substitution
On February 11th 2017, there was a discussion on the topic of "Non-expanding here-documents inside command substitution are subject to newline joining" where it was confirmed that Bash contains a bug. Two questions: 1. Is there a plan to fix this or should a patch be submitted? 2. Regarding the response: > [POSIX] is not necessarily ambiguous, but it does require close > reading. Can you please explain how it was concluded that it's a bug based on the specification? Thank you -- Kevin G
Unexpected word splitting on $* when IFS is unset
Hi, When IFS is unset, unquoted $* undergoes word splitting as if IFS=' ', and not the expected IFS=$' \t\n'. All the other unquoted mass expansions ($@, array[*], array[@]) are word-split as if IFS=$' \t\n'.For instance: nb_args() { echo $#; } set -- $'a\nb' unset IFS # Expected: 2, actual: 2 nb_args $@ # Expected: 2, actual: 1 nb_args $* ar=("$@") # Expected: 2, actual: 2 nb_args ${ar[*]} # Expected: 2, actual: 2 nb_args ${ar[@]} Note that this only occurs if IFS is *globally* unset. If made local and then unset (as in f() { local IFS; unset IFS; ... }), $* is word-split as expected. This is a regression that appeared in 4.3 and is still present on devel (bash-snap-20170616). A git bisect on devel shows that commit 1a81420a36fa (bash-20130125 snapshot) introduced this change. It seems indeed that this commit is related to the handling of $* when IFS is unset, but my knowledge of Bash's sources is too limited to tell what's wrong with it :-) Kevin
Re: Unexpected word splitting on $* when IFS is unset
On 20/06/2017 06:33, Eduardo A. Bustamante López wrote: > On Tue, Jun 20, 2017 at 01:13:07AM +0100, Kevin Brodsky wrote: > [...] >> When IFS is unset, unquoted $* undergoes word splitting as if IFS=' ', >> and not the expected IFS=$' \t\n'. All the other unquoted mass >> This is a regression that appeared in 4.3 and is still present on devel > [...] > > AFAICT, the following patch fixes this. > > diff --git a/subst.c b/subst.c > index 3093309f..bf73a35f 100644 > --- a/subst.c > +++ b/subst.c > @@ -10158,7 +10158,7 @@ finished_with_string: >or we expanded "$@" with IFS null and we need to split the positional >parameters into separate words. */ >if (split_on_spaces) > - list = list_string (istring, " ", 1); /* XXX quoted == 1? */ > + list = list_string (istring, " \t\n", 1); /* XXX quoted == 1? */ >/* If we have $@ (has_dollar_at != 0) and we are in a context where we >don't want to split the result (W_NOSPLIT2), and we are not quoted, >we have already separated the arguments with the first character of > > The above code (`list_string' function call when split_on_spaces != 0) > seems to be executed when IFS is either unset or the empty string. The > comment above that block of code mentions that in either case, the > result should be "split on spaces", although it has a narrow definition > of space. > The comments about "IFS either unset or null" confuse me, because word splitting should behave very differently when IFS is null (there is no word splitting at all, whereas unset IFS is equivalent to IFS=$' \t\n'). My tests show that the behaviour is as expected when IFS is null, so I'm wondering if the comments match the actual behaviour. Kevin
Re: Unexpected word splitting on $* when IFS is unset
On 21/06/2017 14:54, Chet Ramey wrote: > On 6/20/17 1:33 AM, Eduardo A. Bustamante López wrote: >> On Tue, Jun 20, 2017 at 01:13:07AM +0100, Kevin Brodsky wrote: >> [...] >>> When IFS is unset, unquoted $* undergoes word splitting as if IFS=' ', >>> and not the expected IFS=$' \t\n'. All the other unquoted mass >>> This is a regression that appeared in 4.3 and is still present on devel >> [...] >> >> AFAICT, the following patch fixes this. > It's on the right track, but you still need to differentiate between the > cases where IFS is unset (in which case the positional parameters need to > be separated into individual words, and those individual words need to be > split on $' \t\n') and where IFS is null (in which case split_on_spaces is > used as an internal flag to satisfy the Posix requirement that $* expand > into separate words no matter what IFS is set to). That is also my reading of POSIX (and that's more or less what Bash's manpage says as well), but it doesn't seem to be the case (even in <=4.2): $ set -- 'a b' $ IFS='' $ nb_args $* 1 $ nb_args $@ 1 Am I missing something? Other shells like dash or zsh seem to behave exactly in the same way, so I must be... Kevin
Re: Unexpected word splitting on $* when IFS is unset
On 21/06/2017 20:29, Chet Ramey wrote: > On 6/21/17 2:43 PM, Kevin Brodsky wrote: > >> That is also my reading of POSIX (and that's more or less what Bash's >> manpage says as well), but it doesn't seem to be the case (even in <=4.2): > That's a relatively new requirement. The portion of the relevant sentence > that reads "initially producing one field for each positional parameter > that is set" is new as of issue 7 TC2. Without that, the splitting rules > for $* were effectively identical whether it was quoted or not quoted -- > they were separated using the first character of $IFS. In a context where > they were not quoted and word splitting took place, this had the side > effect of splitting them in an unquoted context. When IFS is null, that > resulted in no splitting. I have to admit I am now a bit confused as to what word splitting is supposed to happen when expanding $* (with the old and new spec). I thought it was very simple: * If quoted, there is no splitting whatsoever, and arguments are concatenated into a single string. * If not quoted, then each argument expands into a field, and all fields are split according to IFS (i.e. no splitting if IFS is null). IIUC, before this sentence was added, then 'IFS=""; set -- a b; nb_args $*' should give 1, as no splitting occurs when IFS is null. However, this not the case on Bash 4.2. Do you have an example that results in a different number of arguments (after splitting) between Bash 4.2 and 4.3? > There were long discussions on the Posix list about this starting in late > 2014, resulting in Posix interp 888. > > http://austingroupbugs.net/view.php?id=888 > > There are still some cases where I haven't completely made bash conform to > the new spec. > >> $ set -- 'a b' >> $ IFS='' >> $ nb_args $* >> 1 >> $ nb_args $@ >> 1 > This is a different situation: when IFS is null, there is no splitting. So > N fields are produced, one for each of N positional parameters, but they > are not split any further. Yes I realise now that this has to be true, as IFS being null means at least that fields are not further split. Kevin
Quoting near =~ is inconsistent
Configuration Information [Automatically generated, do not change]: Machine: i686 OS: linux-gnu Compiler: i686-pc-linux-gnu-gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -ggdb2 -O2 -march=pentium3 -pipe -Wall -Wstack-protector -Wtrampolines uname output: Linux c1358217 2.6.18-hardened #4 PREEMPT Wed Dec 20 23:25:36 CET 2006 i686 Mobile Intel(R) Pentium(R) III CPU - M 1200MHz GenuineIntel GNU/Linux Machine Type: i686-pc-linux-gnu Bash Version: 3.2 Patch Level: 9 Release Status: release Description: Matching on =~ is inconsistent with == et. al. I see there's a FAQ entry mentioning that the rhs of =~ is automatically interpreted as a string, but I don't think it means the behaviour below is expected. It means the only way of expressing strings containing characters meaningful to the shell, is to escape them. The behaviour in bash-3.1 is consistent with other comparison operators. It seems that with '=~', quotes on a literal string in the rhs are considered part of the text to match - traditionally I'd have written that by escaping the quotes if I wanted to match them. Repeat-By: $ v="Alphabet" $ [[ ${v} == "Alphabet" ]] && echo matches matches $ [[ ${v} == 'Alphabet' ]] && echo matches matches $ [[ ${v} == Alphabet ]] && echo matches matches $ [[ ${v} =~ "Alphabet" ]] && echo matches $ [[ ${v} =~ 'Alphabet' ]] && echo matches $ [[ ${v} =~ Alphabet ]] && echo matches matches $ v="one two buckle my shoe" $ [[ ${v} =~ "one two" ]] && echo matches $ [[ ${v} =~ one two ]] && echo matches $ [[ ${v} =~ one\ two ]] && echo matches matches -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Conditional Regexp matching problem in 3.2
On Fri, 19 Jan 2007 00:56:03 -0600 (CST) [EMAIL PROTECTED] wrote: > # run this, eh? > DOG="Dog name - 01 - Wiggles" > if [[ $DOG =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - > (.*)$" ]] then > echo Dog ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]} > fi You can actually get it to work in bash 3.2, by writing: if [[ $DOG =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]] then echo Unquoted Dog ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]} fi however this fails in 3.1 - it'll work in 3.1 if you also escape the brackets, but that then fails in 3.2. Which means the only way to guarantee it is to write both, and check the bash version :/ Chet, any comment on this issue? (see also my earlier mail from Sunday 14th, http://lists.gnu.org/archive/html/bug-bash/2007-01/msg00035.html, and Tim's bug at https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=220087) At least to confirm/deny that it may be a real problem? Thanks, -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Conditional Regexp matching problem in 3.2
On Tue, 23 Jan 2007 11:04:58 -0500 Chet Ramey <[EMAIL PROTECTED]> wrote: > One of the changes between bash-3.1 and bash-3.2 was to unify the > handling of the pattern in the `==' and `=~' conditional command > operators. Pattern characters on the rhs are quoted to represent > themselves (remove their special pattern meaning). This is how == > has always worked. I don't get this; I must be missing something. If I do, in bash-3.1: $ V="alphabet" $ [[ $V == alphabet ]] && echo yes yes $ [[ $V == "alphabet" ]] && echo yes yes $ [[ $V == 'alphabet' ]] && echo yes yes $ [[ $V =~ alphabet ]] && echo yes yes $ [[ $V =~ "alphabet" ]] && echo yes yes $ [[ $V =~ 'alphabet' ]] && echo yes yes $ yet if I try the same in 3.2: $ V="alphabet" $ [[ $V == alphabet ]] && echo yes yes $ [[ $V == "alphabet" ]] && echo yes yes $ [[ $V == 'alphabet' ]] && echo yes yes $ [[ $V =~ alphabet ]] && echo yes yes $ [[ $V =~ "alphabet" ]] && echo yes $ [[ $V =~ 'alphabet' ]] && echo yes $ which to me looks like the two operators are not treating quotes the same way. -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Conditional Regexp matching problem in 3.2
On Tue, 23 Jan 2007 16:55:02 -0500 Chet Ramey <[EMAIL PROTECTED]> wrote: > > I don't get this; I must be missing something. If I do, in > > bash-3.1: > > I get identical results with fully-patched versions of bash-3.1 and > bash-3.2: $ /data/g2/tmp/portage/app-shells/bash-3.2_p9-r2/image/bin/bash -version GNU bash, version 3.2.9(1)-release (i686-pc-linux-gnu) Copyright (C) 2005 Free Software Foundation, Inc. $ /data/g2/tmp/portage/app-shells/bash-3.2_p9-r2/image/bin/bash ~/x17 yes 1 yes 2 yes 3 yes 4 That's with bash-3.2 built with only the 001 through 009 patches applied (we have a few other local patches for various reasons, but I've built without them to be sure they're not affecting this). What's the (7) in the release number - does that refer to difference I might be missing? -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: while read subcommand problem
On Fri, 2 Mar 2007 03:04:14 -0800 (PST) rleeden <[EMAIL PROTECTED]> wrote: > > Hi, > > I struggled recently with a 'while read' type of loop in bash, where > after the loop had finished the variables used inside the loop are > not visible any more. I soon found the problem as explained in > section E4 of the FAQ. But I didn't find any of the alternate > examples given very useful for what I want to do. > > Let me give you a simplified example of something I'm attempting to > do: > > - > #!/bin/bash > > grep -v "^#" /etc/hosts | head -5 | while read IP HOSTNAME > do > (( i++ )) > echo "$i : $IP $HOSTNAME" > done > > echo > echo "Total : $i" > > - > > but the $i in the last line is empty - not set to 5 as it should be. > > As you probably know, this kind of loop works fine in ksh. > > NOTE: This is just an example, so I don't need alternatives for how I > could achieve the specifics shown above. I need to find a good > solution where I can do things with a file (whether it be with sed, > awk, tail, head etc.) then pipe it into a 'while read' loop, and then > after the loop access any variables set within the while loop. > > One alternative is to use a temporary file, but I would prefer not to > - e.g. > > - > #!/bin/bash > > grep -v "^#" /etc/hosts | head -5 > tmpfile > > while read IP HOSTNAME > do > (( i++ )) > echo "$i : $IP $HOSTNAME" > done < tmpfile > > rm tmpfile > > echo > echo "Total : $i" > > - > > > Any ideas? You could use a here doc: - #!/bin/bash while read IP HOSTNAME do (( i++ )) echo "$i : $IP $HOSTNAME" done < signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash-3.2 Official Patch 10
On Mon, 5 Mar 2007 17:49:47 -0500 Chet Ramey <[EMAIL PROTECTED]> wrote: > Bash-Release: 3.2 > Patch-ID: bash32-010 I'm still seeing a difference in behaviour: $ cat ~/bash-test v="Alphabet" [[ ${v} =~ "Alphabet" ]] && echo match 1 || echo no match 1 [[ ${v} =~ 'Alphabet' ]] && echo match 2 || echo no match 2 [[ ${v} =~ Alphabet ]] && echo match 3 || echo no match 3 [[ ${v} =~ "^Alpha" ]] && echo match 4 || echo no match 4 [[ ${v} =~ '^Alpha' ]] && echo match 5 || echo no match 5 [[ ${v} =~ ^Alpha ]] && echo match 6 || echo no match 6 bash 3.1.17(1): $ source ~/bash-test match 1 match 2 match 3 match 4 match 5 match 6 bash 3.2.10(1): $ source ~/bash-test match 1 match 2 match 3 no match 4 no match 5 match 6 To get the 3.2 results, I expected to have to write: [[ ${v} =~ "\^Alpha" ]] && echo match 4 || echo no match 4 [[ ${v} =~ '\^Alpha' ]] && echo match 5 || echo no match 5 (which is what I think bash-3.2_p10 is effectively doing) I tried reading the posix standard (well, the single-unix specification at opengroup.org, base definitions chapter 9 and shells & utilitis chapter 2) but things are not so clear to me. It still seems counter-intuitive to me to have the regex characters auto-quoted in single and double-quoted strings, just because they're the rhs of =~. Doesn't happen if I pass one to grep, compare for example: 3.1: $ v="Alphabet" $ [[ ${v} =~ "^Alpha" ]] && echo matches matches $ echo ${v} | grep "^Alpha" Alphabet 3.2.10 $ v="Alphabet" $ [[ ${v} =~ "^Alpha" ]] && echo matches $ echo ${v} | grep "^Alpha" Alphabet I guess the question is, is the difference between 3.2.10 and 3.1 semantics for the =~ rhs as described above intended? -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: Bash-3.2 Official Patch 10
On Fri, 09 Mar 2007 11:39:18 -0500 Chet Ramey <[EMAIL PROTECTED]> wrote: > Kevin F. Quinn wrote: > > On Mon, 5 Mar 2007 17:49:47 -0500 > > Chet Ramey <[EMAIL PROTECTED]> wrote: > > > >> Bash-Release: 3.2 > >> Patch-ID: bash32-010 > > > > I'm still seeing a difference in behaviour: > > Yes. That's the difference between the undefined quoting semantics > in bash-3.1 and the defined semantics in bash-3.2. In bash-3.2, the > quoting removes all meaning from any characters special to the regular > expression engine. > > > > > To get the 3.2 results, I expected to have to write: > > > > [[ ${v} =~ "\^Alpha" ]] && echo match 4 || echo no match 4 > > [[ ${v} =~ '\^Alpha' ]] && echo match 5 || echo no match 5 > > Why? I guess I've gotten into the habit of putting any text string in double-quotes to avoid having to quote things like spaces, or single-quotes to avoid having to quote $ as well. Actually, I didn't expect to _have_ to write it like that, just that it would be possible; e.g. that the following would be equivalent: \^Alpha\ Beta "\^Alpha Beta" '^Alpha Beta' (thinking now that perhaps ^ would lose its special meaning in '') in order to match the literal string `^Alpha Beta' - i.e. without special meaning to ^. > The 3.2 behavior means that the match is performed on the > literal string `\^Alpha', with the backslash and circumflex quoted to > protect them from interpretation by the regexp matching engine. > That's the difference. So effectively, the new rule is that all the regex special characters lose their special meaning when placed in double or single quotes (much like '$' does inside single quotes). Thanks for the clarification. -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: variable assignments and parameter expansion in a single command
On Sat, 24 Mar 2007 14:23:39 -0400 Chet Ramey <[EMAIL PROTECTED]> wrote: > Mike Frysinger wrote: > > i'm trying to determine whether POSIX allows for utilizing of > > variables in simple commands that were defined earlier in the same > > command ... in other words, whether this snippet: > > unset A B > > A="moo" B="$A more" > > echo $A , $B > > should display moo twice or just once: > > As I read Posix, twice, as long as there are only assignment > statements in the command. Assignment statements preceding simple > commands are treated differently. I don't see that posix defines simple commands like that - an assignment _is_ a simple command: `A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.' which implies to me that: A=one B="$A two" is a simple command. The same section (that Mike referred to - http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_09_01) also explicitly says that variable assignments are "saved for processing in steps 3 and 4". Step 2 expands all words except variable assignments and redirections - my interpretation of "variable assignment" is the `A=' part of the statement; i.e. that the rhs of the assignment is expanded. Step 3 does the redirections and step 4 does the variable assignments. So if expansions are done before the assignments, any assignment referring to other variables that are assigned, should be expanded with the value before the assignment. Either way, I've yet to find a shell that claims posix-compliance that does it the bash way; all of Solaris sh, BSD sh/ash/dash (not sure if Solaris is BSD or SYSV - or indeed if there's any difference) and busybox all yield "moo , more" in Mike's example. Hmm: $ A=one B="$A two" env A=one B= two ... $ A=one B="$A two" env | grep ^[AB]= A=one B=one two $ cat show_ab #!/bin/bash echo A: $A echo B: $B $ A=one B="$A two" ./show_ab A: one B: two $ A=one B="$A two" ./show_ab | more A: one B: one two is a little bizarre. Again; the other shells never yield "one two". -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: variable assignments and parameter expansion in a single command
On Sat, 24 Mar 2007 19:32:35 -0400 Chet Ramey <[EMAIL PROTECTED]> wrote: > Kevin F. Quinn wrote: > > my interpretation of > > "variable assignment" is the `A=' part of the statement; i.e. that > > the rhs of the assignment is expanded. > > It's not; the entire word, including the portion after the `=', is a > variable assignment. ah; that explains the bash behaviour w.r.t. Posix. I concur, as: $ A= one is two words due to the whitespace, so the rhs must be part of the word. > None of these shells are or claim posix compliance. The Solaris posix > shell is /usr/xpg4/bin/sh (or something). Of the others, dash is > closest to Posix compliance. FWIW I tried also /usr/xpg4/bin/sh (with the Belenix livecd, SunOS 5.11) and that shows the same as sh/ash/dash/bb. > I don't get these results with bash-3.2. I get "one two" for B both > times with bash (and ksh93, incidentally). Sorry; should have said - that was with bash-3.1.17; I should have tried 3.2. I see the same as you with bash-3.2 (and ksh-93s). Thanks again for your patience :) -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: variable assignments and parameter expansion in a single command
On Sun, 25 Mar 2007 12:26:32 +0200 "Kevin F. Quinn" <[EMAIL PROTECTED]> wrote: > FWIW I tried also /usr/xpg4/bin/sh (with the Belenix livecd, SunOS > 5.11) and that shows the same as sh/ash/dash/bb. FI just tried on SunOS 5.8 (sparc) - a proper Sun installation - and /usr/xpg4/bin/sh there shows "one two" (i.e behaves the same as bash-3.2, ksh-93) - maybe Belenix has the wrong thing for /usr/xpg4/bin/sh. -- Kevin F. Quinn signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash
Re: variable assignments and parameter expansion in a single command
Following a discussion we had earlier this year regarding the order of evaluation of variables and variable assignments: $ A="moo" B="$A more" env |grep ^B B=moo more (rather than showing just 'B= more') the dash maintainer has highlighted the following: $ bash -c 'K=dvb0.net0 A=${K#dvb} eval echo \$A' $ bash -c 'a=/bin PATH=$a ls /dev/null' bash: line 1: ls: No such file or directory $ bash -c 'x=${K:=dvb0.net0} A=${K#dvb} echo $A' $ which he says is inconsistent. I could see the third one is correct (variable assignments are evaluated after expansion, according to the spec), but can't see whether the first two are correct or not. Is the bash behaviour correct in these cases? Cheers, Kev. signature.asc Description: PGP signature ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash