Re: No filename expansion in shell-expand-line
Sorry, I falied to copy and paste R*, the last line is replaced by ls --color=auto echo {a..c} ~root xterm-256color 2024-01-12 42 /dev/fd/63 hello R* > Hello, > > from the documentation I understand that shell-expand-line (ESC CTRL-E) > should do alias expansion, history expansion, brace expansion, tilde > expansion, shell parameter expansion, command substitution, arithmetic > expansion, process substitution (if supported by the operation system), word > splitting, filename expansion and quote removal. > > $ echo $BASH_VERSION > 5.2.15(1)-release > $ echo R* > README > $ echo > > $ ls !! {a..c} ~root $TERM $(date +%F) $((6*7)) <(cat /etc/passwd) "hello" R* > > After pressing ESC CTRL-E the last line is replaced by: > > ls --color=auto echo {a..c} ~root xterm-256color 2024-01-12 42 /dev/fd/63 > hello > > So, everything works fine execept filename expansion, which seems to be > missing. > > Or do I understand something wrong? > > Best regards, > > Martin
No filename expansion in shell-expand-line
Hello, from the documentation I understand that shell-expand-line (ESC CTRL-E) should do alias expansion, history expansion, brace expansion, tilde expansion, shell parameter expansion, command substitution, arithmetic expansion, process substitution (if supported by the operation system), word splitting, filename expansion and quote removal. $ echo $BASH_VERSION 5.2.15(1)-release $ echo R* README $ echo $ ls !! {a..c} ~root $TERM $(date +%F) $((6*7)) <(cat /etc/passwd) "hello" R* After pressing ESC CTRL-E the last line is replaced by: ls --color=auto echo {a..c} ~root xterm-256color 2024-01-12 42 /dev/fd/63 hello So, everything works fine execept filename expansion, which seems to be missing. Or do I understand something wrong? Best regards, Martin
Re: inconsistent handling of closing brace inside no-fork command substitution
Hello Oğuz! > See: > > $ ${ case } in }) echo uname; esac } > Linux > $ ${ case }x in }x) echo uname; esac } > bash: command substitution: line 25: syntax error near unexpected token > `x' > bash: command substitution: line 25: `}x)' > $ ${ case }x in \}x) echo uname; esac } > Linux I couldn't reproduce this with neither 5.1.4 nor 5.2.15 - in both cases ${ case } in }) echo uname; esac } results in bash: syntax error near unexpected token `)' Any help appreciated! Thanks, Martin
Some minor notes on manual chapter 4 "Shell Builtin Commands"
Hello, I took a closer look on the online manual chapter 4 "Shell Builtin Commands" and found some inconsistencies: - true and false seem to be missing (in 4.1 Bourne Shell Builtins). The following has been tested with bash 5.2.15: - 3.7.5 Exit Status says: "All builtins return an exit status of 2 to indicate incorrect usage, generally invalid options or missing arguments." but cd with two or more non-optional arguments returns an exit status of 1. - The same is true if exit is called with two or more argument where the first is numeric. This exit doesn't terminate bash. - When exit is invoked with a non-numeric first argument it terminates bash. That seems to be inconsistent with the behaviour described before, while the exit status of the shell is 2 and consistent in some way. Best regards Martin
Possible problem with ${var%%[...]*}
Hello, in the following lines I consider dash's behaviour as correct an bash's as wrong: $ uname -a Linux martnix4 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64 GNU/Linux $ bash--version | head -n 1 GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu) $ bash-5.2.15 --version | head -n 1 GNU bash, version 5.2.15(1)-release (x86_64-pc-linux-gnu) $ bash-c 'option2="test{<().["; echo "${option2%%[<().[]*}"' test{<() $ bash-5.2.15 -c 'option2="test{<().["; echo "${option2%%[<().[]*}"' test{<() $ dash-c 'option2="test{<().["; echo "${option2%%[<().[]*}"' test{ Am I missing something? I tried to find a smaller example showing the difference but so far I didn't succeed. Best regards, Martin
Re: Bash Reference Manual Type
Hi Chet! > >> Thanks for the report. The synopsis should read > >> > >> cd [-L|[-P [-e]]] [-@] [dir] > > ^ ^ > > But aren't these two brackets just superfluous? > > -L and -P are mutually exclusive, and -e is valid only when -P is > supplied. Yes, my feeling was just that | has such a low precedence that the marked pair of brackets could be omitted, like in id|cut -c1-3 or in the ERE ^(-L|-P( -e)?)?$ But situation seems to be different here. Best regards, Martin
Re: Bash Reference Manual Type
Hi Chet! > Thanks for the report. The synopsis should read > > cd [-L|[-P [-e]]] [-@] [dir] ^ ^ But aren't these two brackets just superfluous? Best regards, Martin
Re: bash login shell detection broken using default compile options
Hello Tycho! > the login shell detection (leading dash: -bash) is apparently broken - at > least, ~/.bashrc is not sourced. As far as I understand the manual ~/.bashrc is not sourced from a login-shell, see https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files At least in Debian 11 the default ~/.profile cares for sourcing ~/.bashrc, that might explain the effect you describe. Best regards, Martin
Re: Logical expressions and job control
Hi Godmar! > For instance: > > gback@lat2022:~$ sleep 10 && echo yes > ^Z > [1]+ Stopped sleep 10 > gback@lat2022:~$ fg > sleep 10 > gback@lat2022:~$ > > ... > > What's the rationale for bash's behavior in this case and is this something > that should be changed? I assume this is because sleep "exits" with an exit status of 148 (=128+SIGTSTP) when it is stopped. If you replace the && with an ;, you get "yes" immediately after pressing ^Z. Best regards Martin
Re: Segmentation Fault in bash --posix
Hello Nicolas! > bash-5.1$ echo () { echo test } > > echo test > > } > bash-5.1$ echo You have defined a function echo that - calls itself with the first argument 'test' and the second argument '}' (!!!) - calls itself with the first and only argument test Try type -a echo and Echo() { echo test } Echo test } Echo to get an insight was is happening. So, it's no surprise that bash finally crashes. Most probably you want to insert a ; before the first closing }: echo() { echo test ; } But even now bash will crash. Best regards Martin
Re: UBSAN error in lib/sh/random.c:79
Hello! Am Sat, 07 Jan 2023 19:08:06 +0100 schrieb Andreas Schwab : > On Jan 07 2023, Greg Wooledge wrote: > ... > I think the original overflow can only happen if the argument of > intrand32 is bigger than INT_MAX. Question might be if an overflow does any harm - or maybe even is intended... Best regards, Martin
Re: reporting a bug
Hello! > function sa { > for y in $(seq $1 $e2); do > echo "echo search $y " > done > } I assume you should write $2 instead of $e2 in line 2. Best regards, Martin
Re: Parameter expansion with extended pattern make system hang
Hi! > > Here's another: > > > > printf -- '%s ' $(gcc --help) | sed 's/ $/\n/' > > > > Let just do the shell most of the work ;-) > > That's not safe. The unquoted substitution will undergo word splitting, > which we want, and also globbing, which we do *not* want. > > You should at least disable globbing first, with set -f. Sure, thanks! > I also don't understand why you used a '%s ' format and then changed > spaces to newlines with a second process. You might as well just use > a '%s\n' format in the first place, and skip the sed/tr. I just changed the last one! Best regards, Martin
Re: Parameter expansion with extended pattern make system hang
Hi! > Running with this assumption, now that we know bash's extglob matching > will not perform suitably for this task, we can look at other approaches. Here's another: printf -- '%s ' $(gcc --help) | sed 's/ $/\n/' Let just do the shell most of the work ;-) Best regards, Martin
Re: Gettings LINES and COLUMNS from stderr instead of /dev/tty
Hello Chet, on 2022-07-18 10:26:05 -0400 you wrote: > On 7/16/22 11:18 AM, Martin Schulte wrote: > > Hello, > > > > I'm just wondering that bash (reproduced with 5.2-rc1 under Debian 11) > > seems to determine LINES and COLUMNS from stderr. > > ... > When it's not interactive, all bets are off, and stderr is usually > a safe default. There's no consistent approach across shells. At least I lost my bet ;-) Since I still have the opinion that either stdout or /dev/tty should be asked to set the variables (because it's the "natural assumption" that you want to format what you write there) please consider the following script: #!/bin/bash shopt -s checkwinsize ( : ) # set LINES/COLUMNS for first time while true; do if ((EPOCHSECONDS%86400==11655)); then printf -v msg '%S' "It's pi o'clock UTC" else printf -v msg '%(%T)T' $EPOCHSECONDS fi tput clear ; tput cup 0 $(((COLUMNS-${#msg})/2)) ; echo "$msg" sleep 1 done It fails with a "bash: printf: `S': invalid format character" once a day but I've no chance to catch this error - either it is cleared on the screen or logging stderr breaks the output. BTW: tput first tries stderr, then stdout, then stdin, then /dev/tty. Best regards Martin
Re: Gettings LINES and COLUMNS from stderr instead of /dev/tty
Hello Dale! > Martin Schulte writes: > > I'm just wondering that bash (reproduced with 5.2-rc1 under Debian 11) > > seems to determine LINES and COLUMNS from stderr. > > It's not clear to me that the manual page says where the LINES and > COLUMNS values are obtained from. Sorry, maybe my mail was somewhat too short... I didn't find anything in the man pages that states where these variables are obtained from. To show the behaviour do the following: - Open a (resizable) terminal window (with a bash in it), say it is /dev/pts/5 - In a second terminal window start the script #!/bin/bash shopt -s checkwinsize trap 'echo $LINES $COLUMNS' SIGWINCH while true; do sleep 0.1; done with ./winsize 2> /dev/pts/5 Whenn you now resize this window, the script will show you the size of the other one. The sources (get_new_windows_size in lib/sh/winsize.c) seem to explain well why this happens. Hope this helps to understand the problem! Best regards Martin
Gettings LINES and COLUMNS from stderr instead of /dev/tty
Hello, I'm just wondering that bash (reproduced with 5.2-rc1 under Debian 11) seems to determine LINES and COLUMNS from stderr. For example, this will lead to strange results when starting the script #!/bin/bash shopt -s checkwinsize trap 'echo $LINES $COLUMNS' SIGWINCH while true; do sleep 0.1; done with standard error redirected to a file (or - even more strange ;-) - another terminal). A quick POC shows that replacing tty = input_tty (); with tty = open( "/dev/tty", O_RDONLY ); in get_new_windows_size in lib/sh/winsize.c gives the "expected" result. In case there is some reason not to use /dev/tty, wouldn't it then be better to ask stdin instead of stderr? The script will most probably be interested in the size of device it is writing to, not the one it is logging to. Best regards Martin
Re: Feature request
Hello Brad! > It would be fantastic if there was a nicer way to source files from the > same folder instead of copy-pasting complicated logic in every script. I'm not sure if I understand your questions correctly, but did you try source "${0%/*}/file.ext" ? >- my sourceables also need logic to prevent them from being executed by >accident (they tell you to source them instead). Just don't give them execute permission (at least when running on a unix system). Best regards, Martin
Re: BASH recursion segfault, FUNCNEST doesn't help
Hi Gergely! > I stumbled upon a recursion overflow crash in BASH. There are many ways to exhaust memory (and other) recources, recursion is one them. In your case a variable like SRCNEST (and all the code with its performance impacts needed behind it) might help, but what exactly is the advantage of a "maximum source nesting level exceeded" error over a segmentation fault? Next we will need MAXARRUSAGE, MAXBRACEEXPAN, ... > There's a slim chance this might be exploitable. I would really be interested in an example. Best regards, Martin
bash seems confused about it's state after unclosed single quotes in nested command substitution
Hello bash-bughunters, please consider the following interactive lines: $ echo $BASH_VERSION 5.1.4(1)-release $ uname -a Linux t1 5.10.0-13-amd64 #1 SMP Debian 5.10.106-1 (2022-03-17) x86_64 GNU/Linux $ echo $BASH_VERSION 5.1.4(1)-release $ sleep $(expr 60 - $(date +%s')) ; date bash: command substitution: line 417: unexpected EOF while looking for matching `'' bash: command substitution: line 418: syntax error: unexpected end of file bash: unexpected EOF while looking for matching `)' $ At this point it looks as if bash has encountered the problem and thus not executed the command line - fine. Things get strange when you enter a command, e.g. echo: $ echo > To get out of this you can enter the missing single quote followed by two closing braces: > ')) expr: non-integer argument sleep: missing operand Try 'sleep --help' for more information $ Now you can go on as expected, the last command in history is $'echo\n\'))' and the 'sleep ...' is not in the history at all. I would either have expected to get PS2 and no error messages after entering the line starting with sleep or being able to just enter the next command. Best regards Martin
Re: Bash regexp parsing would benefit from safe recursion limit
Hello Willi! > Fix: > Count the stack frames during recursive parsing and emit error before stack > resources are entirely consumed. What exactly should happen and what is the benefit of this solution? BTW: I tried trap 'echo "Ohohoh..."; exit 1;' SIGSEGV but the signal wasn't caught (which didn't really surprise me). Best regards Martin
Re: forwarded weirdness report
Hello Greg, hello *! > And here's a workaround: > > unicorn:~$ bash --noprofile --norc -i -c $'alias x="echo hallo"; x' > bash: x: command not found > unicorn:~$ bash --noprofile --norc -i -c $'alias x="echo hallo"\nx' > hallo Really cool - thanks! > Put a literal newline in the -c argument, rather than a semicolon. > > Or -- and I know this answer will be rejected, because it's too simple > and sensible -- stop using aliases in scripts. Or even stop using them at all, alias egrep1='grep -E' doesn't save much compared to egrep2() { grep -E "$@" ; } Or is there a reason why one shouldn't use this in an interactive shell? Best regards Martin
Re: forwarded weirdness report
Hello, on Mon, 28 Mar 2022 20:34:40 +0200 Alex fxmbsw7 Ratchev wrote: > https://pastebin.com/raw/T7ZnFapt > > about inconsitency, about chets 'uh no bugs' > > ive experienced this and such x times already ( got better, this is not my > code ) Here's a somewhat stripped down version: $ bash --noprofile --norc -i -c "echo \$BASH_VERSION; shopt -s expand_aliases ; source <(echo \"alias x='echo hallo'\"); alias; x" 5.1.4(1)-release alias x='echo hallo' bash: x: command not found Best regards Martin
Re: Interesting bug
Hi David! > A syntax error would be nice instead. I see - also from you second answer - that you have some fundamental misunderstandings about shell programming: - Your code will, in case the testCode fails, try execute a program called {echo. This is certainly not a good name for a program, but it is not a syntax error either. - Since bash interprets the code the problem with the closing brace is only detected when the offending line is passed. My personal opinion (although I'll probably be bashed here for it ;-) ): Except for a very few exceptions like small wrappers avoid writing new shell scripts at all - for example use python instead. There are many historically founded flaws and odds with shell proramming. Anyhow, bug-bash@gnu.org is not the right place for these topics, better try help-b...@gnu.org. Best regards Martin
Re: Interesting bug
Hello David! > I guess 99% of programmers would either expect "Finished" to be printed or > some syntax error. Well, 99% of shell programmers will (hopefully ;-) ) put a blank between "{" and "echo" in the line foo="$(testCode)" || {echo "foo";} Best regards Martin
Re: Option for read to handle incomplete last line
Hi Greg! > > Nevertheless, am I right that this solution relies on an undocumented > > feature? > > Which "undocumented" feature did you have in mind? Most things are > documented, somewhere. > > Are you thinking of -d '' signifying NUL as the delimiter? Chet told > us that he supports this "happy accident" and won't take it away. > > Are you thinking of the equivalence of "$array" and "${array[0]}"? I > think that's documented somewhere, but I'm not going to dig for it right > now. Before reading the source I would never have thought that read sets variables although it returns FAILURE. Best regards Martin
Re: Option for read to handle incomplete last line
Hi Greg, hi *! > For bash scripts using this, I'd go a little bit fancier: > > read_line() { > if (($# == 0)) || [[ ${!#} = -* ]]; then > declare -n _rl_lastvar=REPLY > else > declare -n _rl_lastvar=${!#} > fi > read -r "$@" || test -n "$_rl_lastvar" > } Great, thanks - this solution seems to solve more real world problems than it introduces ;-) > This intentionally skips a trailing incomplete line that has too few > fields, as in: > > ... > > The incomplete line here only has one field, so the "lastvar" (b) is > empty, and therefore the incomplete line isn't counted. I consider > this a feature, but others may not. Yes, one might discuss this... Nevertheless, am I right that this solution relies on an undocumented feature? Best regards Martin
Option for read to handle incomplete last line
Hello, my apologies if there's a much easier solution for the following problem - in this case please let me know! >From time to time a run into troubles when reading a file with a while-read >loop where the last "line" is not terminated with a newline. I found an ugly looking solution (probably relying on undocumented features) when reading the whole line into one variable (see below). The attached patch for bash-5.1.8 will add an -E option to the builtin read that will avoid the problem. To test it run the patched bash on the following script: >>> input=$'Line 1\nLine 2\nIncomplete line 3' echo "while read line" printf '%s' "$input" | while read line; do printf ' %s\n' "$line"; done echo "while read line || [[ \$line != '' ]]" printf '%s' "$input" | while read line || [[ $line != '' ]]; do printf ' %s\n' "$line"; done echo "while read -E line" printf '%s' "$input" | while read -E line; do printf ' %s\n' "$line"; done echo "while read -E line with no characters between last \\n and EOF" printf '%s\n' "$input" | sed 's/Incomplete l/L/' | while read -E line; do printf ' %s\n' "$line"; done <<< The patch has not been tested intensely - first I would like to hear if I'm on a sensible way. Best regards Martin --- ../bash-5.1.8-ori/builtins/read.def 2020-06-05 19:18:28.0 +0200 +++ builtins/read.def 2021-10-23 21:23:37.067915781 +0200 @@ -22,7 +22,7 @@ $BUILTIN read $FUNCTION read_builtin -$SHORT_DOC read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] +$SHORT_DOC read [-eErs] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] Read a line from the standard input and split it into fields. Reads a single line from the standard input, or from file descriptor FD @@ -40,6 +40,7 @@ -d delim continue until the first character of DELIM is read, rather than newline -e use Readline to obtain the line + -E return text between last newline and EOF -i text use TEXT as the initial text for Readline -n nchars return after reading NCHARS characters rather than waiting for a newline, but honor a delimiter if fewer than @@ -179,7 +180,7 @@ int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag; volatile int i; int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; - int raw, edit, nchars, silent, have_timeout, ignore_delim, fd; + int raw, edit, eof_terminates_line, nchars, silent, have_timeout, ignore_delim, fd; int lastsig, t_errno; int mb_cur_max; unsigned int tmsec, tmusec; @@ -209,6 +210,7 @@ USE_VAR(input_is_pipe); /* USE_VAR(raw); */ USE_VAR(edit); + USE_VAR(eof_terminates_line); USE_VAR(tmsec); USE_VAR(tmusec); USE_VAR(nchars); @@ -229,6 +231,7 @@ i = 0; /* Index into the string that we are reading. */ raw = edit = 0; /* Not reading raw input by default. */ + eof_terminates_line = 0; silent = 0; arrayname = prompt = (char *)NULL; fd = 0; /* file descriptor to read from */ @@ -245,7 +248,7 @@ ignore_delim = nflag = 0; reset_internal_getopt (); - while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -1) + while ((opt = internal_getopt (list, "eErsa:d:i:n:p:t:u:N:")) != -1) { switch (opt) { @@ -263,6 +266,9 @@ edit = 1; #endif break; + case 'E': + eof_terminates_line = 1; + break; case 'i': #if defined (READLINE) itext = list_optarg; @@ -788,7 +794,14 @@ discard_unwind_frame ("read_builtin"); - retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; + if (!eof_terminates_line) +{ + retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; +} + else +{ + retval = eof && strlen (input_string) == 0 ? EXECUTION_FAILURE : EXECUTION_SUCCESS; +} assign_vars:
Re: echo $'\0' >a does not write the nul byte
Hello Ilkka, hello *! > Bash's echo is a builtin, so using it doesn't involve an execve(). Sure – but while passing a string (however it will be encoded) containing a null byte to builtins would be possible in principle (as zsh shows) this would lead to a large bunch of problems, e.g. another incompatibility between the builtin and the external echo. Best regards Martin
Re: echo $'\0' >a does not write the nul byte
Hello Hans, hello Eduardo! > On Sun, Jan 17, 2021 at 12:05 PM wrote: > > (...) > > The nul byte is not echoed by $'\0'. > > This is expected. Bash uses NUL-byte terminated character sequences to > store strings, so it can't actually store NUL bytes themselves. To be exact, this is already caused by a Unix Kernel - strings passed by the exex* system calls are null terminated, too. As it is the default in the C programming language. Thus you can't pass a null byte in an argument when invoking a program. Best regards Martin
Re: find len of array w/name in another var...(bash 4.4.12)
Hello! Am Tue, 20 Oct 2020 00:58:36 -0700 schrieb L A Walsh : > There's got to be an easier way to do this, but not remembering or finding > it: > > First tried the obvious: > declare -a ar1=([0]="1" [1]="2" [2]="3" [3]="44") > an=ar1 > echo ${#!an[@]} > -bash: ${#!an[@]}: bad substitution > > This works but feels kludgy > > an=ar1 > eval echo \${#$an[@]} > 4 I'm not quite sure what exactly you intend, but if you use declare -n an=ar1 instead of an=ar1, then echo ${#an} ${an[3]} will work as I expect. Best regards Martin
Re: find len of array w/name in another var...(bash 4.4.12)
Hello! Am Tue, 20 Oct 2020 00:58:36 -0700 schrieb L A Walsh : > There's got to be an easier way to do this, but not remembering or finding > it: > > First tried the obvious: > declare -a ar1=([0]="1" [1]="2" [2]="3" [3]="44") > an=ar1 > echo ${#!an[@]} > -bash: ${#!an[@]}: bad substitution > > This works but feels kludgy > > an=ar1 > eval echo \${#$an[@]} > 4 I'm not quite sure what exactly you intend, but if you use declare -n an=ar1 instead of an=ar1, then echo ${#an} ${an[3]} will work as I expect. Best regards Martin
Re: Bad substitution breaks conditional statement
Hello Lawrence, hello *! > >> However, invalid parameter transformation operators are not considered > >> fatal errors, even in posix mode. Maybe they should be. > > > > Yes, please :-) > > > > Or no error at all. > > Why should invalid parameter transformation operators be treated > differently from other invalid parameter expansions? For sure all syntactical errors on parameter expansions should be handled in the same way - I suggest they should be considered as fatal errors. Consider the following script: >>> #!/bin/bash echo "${x;:-}" ; echo "Not executed" echo "Executed" echo "${x:-}" ;; echo "Not executed" echo "Not executed" <<< It just a source of problems that the two syntactical errors (both caused by an extra semicolon) lead to different behaviour. Martin
Re: Bad substitution breaks conditional statement
Hi Chet, hi all! > In general, variable expansion errors cause posix-mode shells to exit and > bash default mode shells to abort execution of the current command and > return to the top level, whether that is the command line or the next > command in the script. This aborts lists and other compound commands. > Bash has always behaved this way. > > However, invalid parameter transformation operators are not considered > fatal errors, even in posix mode. Maybe they should be. Yes, please :-) Or no error at all. Best regards Martin
Bad substitution breaks conditional statement
Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -g -O2 -fdebug-prefix-map=/build/bash-2bxm7h/bash-5.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wno-parentheses -Wno-format-sec$ uname output: Linux t1 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 5.0 Patch Level: 3 Release Status: release Description: It looks as if a bad substitution detected inside a case of if continues the script flow immediately after the conditional statement skipping the remaining statements inside the conditional. Please take a look into section "Repeat-By:". I detected this when running a script containing "${OPTARG@Q}" with a bash 4.1.5 where @Q is not yet supported - the script continued to run in a bad manner so this bug might cause real troubles... Repeat-By: schulte@t1:~$ cat bad_substitutions_breaks_conditional #!/bin/bash x=y case $x in y) echo "x has value ${x@q} - stop now!" exit 1;; esac echo "running" if [[ $x == y ]]; then echo "x has value ${x@q} - stop now!" exit 1 fi echo "still running" echo "x has value ${x@q} - stop now!" exit 1 echo "and running" schulte@t1:~$ ./bad_substitutions_breaks_conditional ./bad_substitutions_breaks_conditional: line 6: x has value ${x@q} - stop now!: bad substitution running ./bad_substitutions_breaks_conditional: line 11: x has value ${x@q} - stop now!: bad substitution still running ./bad_substitutions_breaks_conditional: line 15: x has value ${x@q} - stop now!: bad substitution
Re: echo builtin doesn't handle end-of-options flag
Hello Todd, Eric Cook wrote: > This is an intentional relic of the past, you really should use printf. See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_18 BTW/1: Because of this /bin/echo behaves the same way in most Linux distribution. BTW/2: echo -n -n$'\n' will print a -n in the bash. Best regards Martin
Re: Command substitution
Hello Felix! > Quoting is useless when assigning variable from ouptut of command or > another variable: Yes, I assume you are right. > Unfortunely, I don't retrieve this behaviour in man page. Me neither, maybe the manual should read If the substitution appears within double quotes *or as the right-hand side of an variable assignment*, word splitting and filename expansion are not performed on the results. at end of 3.5.4. Best regards, Martin
Re: Difference between EPOCHREALTIME and EPOCHSECONDS
Hello Chet, hello Felix, hello all! > > Bash Version: 5.0 > > Patch Level: 16 > > Release Status: release > > > > Description: > > Integer part of $EPOCHREALTIME could increase more than 8000 > > microseconds before $EPOCHSECONDS > > It's the difference between time() and gettimeofday(). I didn't believe it ;-) but running time_gettimeofday.c: #include #include #include int main(int argc, char *argv[]) { struct timeval tv; time_t t; struct timespec sleep; sleep.tv_sec = 0; sleep.tv_nsec = 100; for (int i=0; i<1001; i++) { gettimeofday(, NULL); t = time(NULL); printf("%d.%.6d %d %d\n", tv.tv_sec, tv.tv_usec, t, tv.tv_sec-t); nanosleep( , NULL ); } return 0; } with gcc -o time_gettimeofday time_gettimeofday.c && ./time_gettimeofday | egrep '\.(00|99) shows it is right... Thanks and best regards, Martin
First lines of examples/startup-files/bashrc
Hello bash developers, my apologies in advance if I'm overlooking something trivial but I'm really wondering about the first lines in examples/startup-files/bashrc (which are copied to Debian's skeleton ~/.bashrc): case $- in *i*);; *) return ;; esac Well, bash terminates sourcing the file if it is invoked non-interactively. But, as far as I understand, a non-interactive bash doesn't read ~/.bashrc at all - so shouldn't we just omit them? Best regards, Martin
Re: Fwd: read -t 0 fails to detect input.
Hello! > Could you please comment about this assertions: > > 1.- bash will either do a select() or an ioctl(FIONREAD), or neither > of them, but not both, as it should for it to work. read -t0 is broken. > 2.- Conclusion: read -t0 is *broken* in bash. Don't use it. – No. It works as intended. It's not usable in a pipe in the way you try, but this is caused by the principles of a pipe, not by a bug in read. while ! read -t 0; do echo 'It works as intended - just press RETURN to see why' done Best regards, Martin
Re: Two states of empty arrays
Hello Léa! Léa Gris wrote: > I was trying to play the the -v test to detect when an array or > associative array has been declared, not necessarily assigned entries > key, values, to not error when Bash runs with -o nounset Just for the curious: What is your attention here? I think that most useful questions (Is there an element in the array? Is there a value for a given key?) can be answered in a simpler way: #!/bin/bash set -o nounset # From what I learned today it seems to be good practice to always # assign and empty array to when declaring an associative array: declare -A assoc=() echo ${#assoc[@]} # Are there elements in it? assoc[key1]=val1 assoc[key2]= for key in key1 key2 key3; do if [[ -n ${assoc[$key]+isset} ]]; then echo "Element for $key is set" else echo "No Element for $key" fi done Best regards, Martin
Re: Backslash missing in brace expansion
Hello, thanks a lot for all the answers! I would like to suppose (Ilkka already argued in this direction) that in future versions of bash {x..C} should expand to x y z A B C. Best regards, Martin
Re: Backslash missing in brace expansion
Hi Chet, hi all! On Thu, 5 Dec 2019 12:01:31 -0800 Chet Ramey wrote: > On 12/5/19 11:11 AM, Martin Schulte wrote: > > Hello, > > > > please have a look: > > > > $ uname -a > > Linux martnix4 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u2 > > (2019-11-11) x86_64 GNU/Linux $ echo ${BASH_VERSINFO[@]} > > 4 4 12 1 release x86_64-pc-linux-gnu > > $ set -x > > $ echo {Z..a} > > + echo Z '[' '' ']' '^' _ '`' a > > Z [ ] ^ _ ` a > > > > It looks as if the backslash (between [ and ] in ASCII code) is > > missing in brace expansion. The same behaviour seems to be found in > > bash 5.0. > > It's an unquoted backslash, which is removed by quote removal when the > words are expanded. Look at the extra space between `[' and `]'; that's > the null argument resulting from the unquoted backslash. Yes - sure. But then I'm wondering why the unquoted backtick doesn't start command substitution: $ echo {Z..a} Z [ ] ^ _ ` a $ echo Z [ \ ] ^ _ ` a > Best regards, Martin
Backslash missing in brace expansion
Hello, please have a look: $ uname -a Linux martnix4 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u2 (2019-11-11) x86_64 GNU/Linux $ echo ${BASH_VERSINFO[@]} 4 4 12 1 release x86_64-pc-linux-gnu $ set -x $ echo {Z..a} + echo Z '[' '' ']' '^' _ '`' a Z [ ] ^ _ ` a It looks as if the backslash (between [ and ] in ASCII code) is missing in brace expansion. The same behaviour seems to be found in bash 5.0. Best regards, Martin
Output of jobs wrong
Hello, I'm not feeling well writing this mail because so far I've not been able to reproduce the behaviour I describe in the following... I was trying to understand the "[Patch] (tiny problem) bad short_doc for % command" thread when I entered more or less the following sequence of commands: $ help -s % %: job_spec [&] $ sleep 10 ^C [Interrupted with CTRL-C - maybe "exactly" after 10 seconds] $ sleep 100 & $ sleep 200 & $ sleep 30 & $ % ^C [Interrupted with CTRL-C] $ sleep 300 & $ jobs [1] Running sleep 10 & [2]- Running sleep 10 & [3]+ Running sleep 300 & So job 1 and job 2 listed the wrong argument. I checked this from a second terminal with 'ps -lf' - and there were three sleep with arguments 100, 200 and 300... Systeminfo: $ uname -a Linux martnix4 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u5 (2019-08-11) x86_64 GNU/Linux $ echo $BASH_VERSION 4.4.12(1)-release Sorry, I would like to be more helpful - but maybe someone else has noticed a similiar problem or has an idea with the sources in mind. Best regards, Martin
Re: T/F var expansion?
Hello! > Is there a T/F var expansion that does: > > var=${tst:+$yes}${tst:-$no} > > but with yes/no in 1 expansion? At least if you are only working with numbers you can use ((var=(tst!=0?42:31))) But is this a question for bug-bash? Best regards, Martin
@Q breaks set -o nounset
Hello, with "GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)" I get the following behaviour: + bash -c 'set -o nounset; echo $x' bash: x: unbound variable + bash -c 'set -o nounset; echo ${x}' bash: x: unbound variable + bash -c 'set -o nounset; echo ${x@Q}' + bash -c 'set -o nounset; echo ${x/a/b}' bash: x: unbound variable "GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)" behaves identically. So, @Q breaks the 'set -o nounset'. Is this intended? I like using @Q for output of variables with unknown content - is there a better way to do this? Best regards, Martin
Strange (wrong?) behaviour of "test ! -a file"
Hello, "help test" states that "-a file" and "-e file" do them same ("True if file exists.") This is not true when negating the result as you can see from the output below. The bash builtin even behaves different than the test from coreutils. It looks as if "! -a file" results in "( ! ) -a ( file )" in bash while it results in "! ( -a file )" in coreutils' test. Given all the problems with "-a" as the AND and the fact that POSIX doesn't have a "-a" filetest I suggest to mark "-a file" as strongly deprecated in the help page or remove it at all from test rather than thinking about if this is a bug and how to fix it. There's a related discussion in the coreutils mailing list: http://lists.gnu.org/archive/html/bug-coreutils/2018-10/msg00117.html Regards, Martin address@hidden:~/langs/sh$ cat minus-a #!/bin/bash set -o nounset file=/etc/passwd echo $BASH_VERSION /usr/bin/[ --version | head -1 for cmd in test /usr/bin/test do for op in -a -e do printf "%-30s -> " "$cmd ! $op $file" ; $cmd ! $op $file ; echo $? done done | cat -n address@hidden:~/langs/sh$ ./minus-a 4.4.12(1)-release [ (GNU coreutils) 8.26 1 test ! -a /etc/passwd -> 0 2 test ! -e /etc/passwd -> 1 3 /usr/bin/test ! -a /etc/passwd -> 1 4 /usr/bin/test ! -e /etc/passwd -> 1
Strange behaviour when sending SIGTERM to bash
Hello, I'm running bash under Debian Stretch: $ echo $BASH_VERSION 4.4.12(1)-release $ trap $ echo $$ 1100 $ kill 1100 $ => Looks fine for me Then I do a kill 1100 from another session and the bash above terminates. => Looks wrong for me Greetings, Martin