Re: No filename expansion in shell-expand-line

2024-01-12 Thread Martin Schulte
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

2024-01-12 Thread Martin Schulte
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

2024-01-03 Thread Martin Schulte
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"

2023-10-08 Thread Martin Schulte
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%%[...]*}

2023-04-02 Thread Martin Schulte
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

2023-03-31 Thread Martin Schulte
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

2023-03-31 Thread Martin Schulte
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

2023-03-16 Thread Martin Schulte
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

2023-02-10 Thread Martin Schulte
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

2023-01-20 Thread Martin Schulte
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

2023-01-07 Thread Martin Schulte
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

2022-12-15 Thread Martin Schulte
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

2022-09-06 Thread Martin Schulte
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

2022-09-06 Thread Martin Schulte
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

2022-07-18 Thread Martin Schulte
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

2022-07-17 Thread Martin Schulte
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

2022-07-16 Thread Martin Schulte
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

2022-07-06 Thread Martin Schulte
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

2022-06-01 Thread Martin Schulte
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

2022-04-15 Thread Martin Schulte
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

2022-03-30 Thread Martin Schulte
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

2022-03-29 Thread Martin Schulte
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

2022-03-28 Thread Martin Schulte
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

2022-02-12 Thread Martin Schulte
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

2022-02-12 Thread Martin Schulte
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

2021-10-24 Thread Martin Schulte
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

2021-10-24 Thread Martin Schulte
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

2021-10-24 Thread Martin Schulte
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

2021-01-17 Thread Martin Schulte
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

2021-01-17 Thread Martin Schulte
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)

2020-10-20 Thread Martin Schulte
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)

2020-10-20 Thread Martin Schulte
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

2020-10-13 Thread Martin Schulte
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

2020-10-13 Thread Martin Schulte
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

2020-10-11 Thread Martin Schulte
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

2020-08-16 Thread Martin Schulte
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

2020-06-03 Thread Martin Schulte
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

2020-04-14 Thread Martin Schulte
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

2020-04-08 Thread Martin Schulte
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.

2019-12-19 Thread Martin Schulte
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

2019-12-12 Thread Martin Schulte
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

2019-12-08 Thread Martin Schulte
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

2019-12-05 Thread Martin Schulte
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

2019-12-05 Thread Martin Schulte
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

2019-09-21 Thread Martin Schulte
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?

2019-07-28 Thread Martin Schulte
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

2019-03-03 Thread Martin Schulte
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"

2018-10-21 Thread Martin Schulte
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

2018-03-28 Thread Martin Schulte
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