Re: Bash 5.1: Make shell_script_filename available to startup files
On Tue, 2 Feb 2021, Marc Aurèle La France wrote: On Tue, 2 Feb 2021, Chet Ramey wrote: On Mon, 1 Feb 2021, Marc Aurèle La France wrote: Currently, only the script's arguments are passed as positional parameters. For compatibility reasons, $0 cannot be used to also pass the script's filename, so I'm creating a new BASH_SCRIPT variable instead. I'm interested in use cases for this feature. Well, I'll start with the optics, a.k.a. completeness/consistency argument. It makes little sense to pass the script's arguments, but not its name. Using $0 for this would have been even more consistent, but that's crying over spilt milk. I'm currently using this to greatly reduce code duplication in a framework that will eventually allow me to... - Rebuild my system from source, complete with local changes, but without the distribution fluff I still have left; - Keep it up date; and - When the time comes, move it to different hardware. ... all with much less pain than is currently necessary. To reduce duplication and maintenance effort, I want everything centralised, instead of the current messy patchwork, including, but not restricted to, my interactive use of bash. Currently, I set BASH_ENV system-wide which means all scripts that start with "#! /bin/bash" (but not "#! /bin/sh") inherit those settings. However, not all scripts need all settings, so to keep things clean, I'm using $BASH_SCRIPT to classify/differentiate them. Yes, I could have all such scripts source a file when they start. But isn't that just another startup file? And duplication. Or pass something through $1; again duplication. BASH_SCRIPT is a more elegant solution and doesn't require any intervention from the named script. If I end up carrying this as a local change, that's fine too. It wouldn't be the first time. Anything more on this? Thanks. Marc.
Say to use test -e in preference to test -a
$ man bash #and $ help test #say -a FILETrue if file exists. -e FILETrue if file exists. OK, but add a note that it would be better to use -e, as it is more portable. Compare $ test -a . $ /usr/bin/test -a .
[PATCH] Fix blocking read timeouts at a small probability
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -g -O2 -Wno-parentheses -Wno-format-security uname output: Linux chatoyancy 5.6.13-100.fc30.x86_64 #1 SMP Fri May 15 00:36:06 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 5.1 Patch Level: 4 Release Status: release Description: From Bash 4.3 to the `devel' branch, `read -t timeout' fails to time out and blocks the execution forever at a small probability. The current implementation tries to stop the execution of read(2) by SIGALRM which is arranged by setitimer(2) or alarm(2). The problem is that SIGALRM can arrive when Bash is not calling read(2) or, when read(2) is called but still trying to set up the file descriptor for read. This problem of timeout failure depends on a race condition, and the probability of the timeout failure largely depends on the following conditions: - Operating system, CPU, etc. - Bash versions, Bash release status (release, maint, etc.) - Constructs (subshell, etc.) used near `read -t'. Commands executed before `read -t' - The type of file descriptors, such as files, pipes, and sockets. Usually, the probability is very low, but I found that sometimes the probability of the timeout failure can be about several percents, which is not negligible. Repeat-By: Originally, this issue was reported to a devel branch of my shell program by `eximus (3ximus)' in the following comment: https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-770390986 Here is the reduced test case I created: #!/bin/bash rm -f a.pipe mkfifo a.pipe exec 9<> a.pipe rm -f a.pipe for c in {0..2000}; do (eval "echo {0..$c}" & read -u 9 -t 0.001) >/dev/null printf $'\r\e[Kok %d' "$c" done echo The expected behavior is to count up to 2000 without stopping, but the actual Bash's behavior is to randomly stop at some number before reaching 2000. I've tested with various versions of Bash in various systems. Here are the observations: - The problem starts to occur in Bash 4.3. The devel branch of Bash also exhibits the same problem. - The release status (which is specified in `configure.ac') largely matters. As far as `maint' is used, the failure probability is quite small. However, once the release status is changed to `release', the probability rises very much. - I could consistently reproduce it in Linux, FreeBSD, and Cygwin. I couldn't reproduce it in Minix. Among them, the probability is largest in Cygwin. - It also occurs with different setups of stdin for the `read' builtin including `exec 9< <(sleep 100)', `exec 9< /dev/udp/0.0.0.0/80', etc. Each setup results in a different probability of the timeout failure. - The failure probability also depends on the amount of output from `echo' in the above test case. There is a certain range of the amount where the failure probability becomes large. The range depends on other conditions. - The above construct `(COMMAND & read -t TIMEOUT) < SLOWFD' caused a significantly large probability of the timeout failure, but the timeout failures were also observed in simpler constructs very rarely in past (particularly in Cygwin). I've summarized the detailed tests and investigations at the following comment. https://github.com/akinomyoga/ble.sh/issues/82#issuecomment-774770516 I just briefly summarize it in this mail. Fix: I first checked the commit where the problem starts to occur, which was the following one: > commit 10e784337238e6081ca5f9bdc8c21492f7b89388 > Author: Chet Ramey > Date: Mon Mar 4 08:10:00 2013 -0500 > > commit bash-20130208 snapshot > This is the relevant log in ChangeLog: >2/9 >--- > > builtins/read.def > - sigalrm_seen, alrmbuf: now global so the rest of the shell (trap.c) >can use them > - sigalrm: just sets flag, no longer longjmps to alrmbuf; problem was >longjmp without manipulating signal mask, leaving SIGALRM blocked > > quit.h > - move CHECK_ALRM macro here from builtins/read.def so trap.c: >check_signals() can call it > > trap.c > - check_signals: add call to CHECK_ALRM before QUIT > - check_signals_and_traps: call check_signals() instead of including >CHECK_ALRM and QUIT inline. Integrating check for read builtin's >SIGALRM (where zread call to check_signals_and_traps can see it) >fixes problem reported by Mike Frysinger In the older code, `longjmp' was called in the signal handler for SIGALRT, but it was changed to be called from `check_signals'. This was introduced after the discussion at: https://lists.gnu.org/archive/html/bug-bash/2013-02/msg00016.html Actually, another report in 2018 has already the same issue as follows: https:
Re: Bash 5.1: Make shell_script_filename available to startup files
On 2/8/21 10:04 AM, Marc Aurèle La France wrote: Yes, I could have all such scripts source a file when they start. But isn't that just another startup file? And duplication. Or pass something through $1; again duplication. BASH_SCRIPT is a more elegant solution and doesn't require any intervention from the named script. If I end up carrying this as a local change, that's fine too. It wouldn't be the first time. Anything more on this? I haven't heard anyone else weigh in besides the two of us. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: feature request: ${ regex s expander, and multiple expandrs inside one
On Fri, Feb 05, 2021 at 09:29:49PM +0100, Alex fxmbsw7 Ratchev wrote: > .. > > var=mynewfoo > printf ${var~~n[^f]+} > -> > myfoo > > and also multiple expanders inside one statement would greatly speed up > processment and also fulfill old greatly coding wanting possibilities This could be done by: var=mynewfoo echo ${var/n*f/f} myfoo -- Félix Hauri -- http://www.f-hauri.ch
export loses error
$ export vim=$HOME/.GVim-v8.2.2451.glibc2.15-x86_64.AppImage $ $ vimV=$($vim --version)||echo handle error here #without export, error is captured fuse: failed to exec fusermount: No such file or directory open dir error: No such file or directory handle error here $ $ export vimV=$($vim --version)||echo handle error here #with export, error is lost fuse: failed to exec fusermount: No such file or directory open dir error: No such file or directory $
Re: export loses error
> On Feb 8, 2021, at 5:29 PM, gregrwm wrote: > > $ export vim=$HOME/.GVim-v8.2.2451.glibc2.15-x86_64.AppImage > $ > $ vimV=$($vim --version)||echo handle error here #without > export, error is captured > fuse: failed to exec fusermount: No such file or directory > open dir error: No such file or directory > handle error here > $ > $ export vimV=$($vim --version)||echo handle error here #with > export, error is lost > fuse: failed to exec fusermount: No such file or directory > open dir error: No such file or directory > $ Not a bug. Kind of annoying, sure, but not a bug. https://mywiki.wooledge.org/BashPitfalls#local_var.3D.24.28cmd.29 vq
Re: export loses error
Le 09/02/2021 à 01:05, Lawrence Velázquez écrivait : On Feb 8, 2021, at 5:29 PM, gregrwm wrote: $ export vim=$HOME/.GVim-v8.2.2451.glibc2.15-x86_64.AppImage $ $ vimV=$($vim --version)||echo handle error here #without export, error is captured fuse: failed to exec fusermount: No such file or directory open dir error: No such file or directory handle error here $ $ export vimV=$($vim --version)||echo handle error here #with export, error is lost fuse: failed to exec fusermount: No such file or directory open dir error: No such file or directory $ Not a bug. Kind of annoying, sure, but not a bug. https://mywiki.wooledge.org/BashPitfalls#local_var.3D.24.28cmd.29 vq Or this https://github.com/koalaman/shellcheck/wiki/SC2155 Nice helping shell linter would have warned of this pitfall. -- Léa Gris
extdebug now implies errtrace which implies `trap ... ERR` execution w/out `set -e`
this set of changes between bash-4.3 & bash-4.4: https://git.savannah.gnu.org/cgit/bash.git/commit/?h=814e1ff513ceca5d535b92f6c8dd9af7554fe83e has this buried nugget: + - shopt_set_debug_mode: make sure error_trace_mode reflects the setting + of extdebug. This one is tentative. Fix from Grisha Levit + + - shopt_set_debug_mode: call set_shellopts after setting error_trace_mode + or function_trace_mode. Fix from Grisha Levit which i'm guessing means this behavior is intentional: $ bash-4.3 -c 'shopt -p -o | grep err; shopt -s extdebug; shopt -p -o | grep err' set +o errexit set +o errtrace set +o errexit set +o errtrace $ bash-4.4 -c 'shopt -p -o | grep err; shopt -s extdebug; shopt -p -o | grep err' set +o errexit set +o errtrace set +o errexit set -o errtrace we're in the process of upgrading from bash-4.3 to bash-4.4 and it broke our build scripts because we use `trap ... ERR` with `shopt -s extdebug`, but we also toggle `set +e` in a few places to avoid trapping. that is no longer sufficient, and now we have to do `set +eE` and `set -eE`. example shell script showing change in behavior: $ cat test.sh #!/bin/bash foo() { false return 0 } shopt -s extdebug trap 'echo invalid trap; exit 1' ERR foo echo "pass" $ bash-4.3 ./test.sh pass $ bash-4.4 ./test.sh invalid trap the manual text for extdebug didn't change between the versions, so it's not clear if this is overall intended as a bug fix. -mike
Re: extdebug now implies errtrace which implies `trap ... ERR` execution w/out `set -e`
9 Şubat 2021 Salı tarihinde Mike Frysinger yazdı: > $ cat test.sh > #!/bin/bash > foo() { > false > return 0 > } > shopt -s extdebug > trap 'echo invalid trap; exit 1' ERR > foo > echo "pass" > $ bash-4.3 ./test.sh > pass > $ bash-4.4 ./test.sh > invalid trap > The manual says that when extdebug is on, functions inherit the ERR trap. I think 4.4 behaves just as expected here -- Oğuz