Bash test builtin fails on: test -n '>' -a 1 -eq 1

2024-10-22 Thread cirrus . mazurka-0t
The following produces a `bash: test: too many arguments` exception in `test`, 
with exit status 2:

``` bash
v='>'
test -n "$v" -a yes '!=' no # bash: test: too many arguments
echo $? # 2

test -n '>' -a 1 -eq 1 # bash: test: too many arguments
echo $? # 2

[ -n '>' -a 1 -eq 1 ] # bash: [: too many arguments
echo $? # 2

[[ -n '>' -a 1 -eq 1 ]]
# bash: syntax error in conditional expression
# bash: syntax error near `-a'
echo $? # 2
```

It works without the -a, and as such, it works using && instead of the -a:

```
v='>'
test -n "$v"
echo $? # 0

[ -n "$v" ]
echo $? # 0

test -n "$v" && test yes '!=' no
echo $? # 0

[ -n "$v" ] && [ yes '!=' no ]
echo $? # 0
```

There is no mention of this peculiar behaviour inside the documentation:
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-test

Known versions affected:
GNU bash, version 5.2.37(1)-release (x86_64-apple-darwin22.6.0)
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin22)

If this is intended behaviour, then what is the suitable workaround?
1. Should I always use `&&` instead of `-a`?
2. Should I use a parameter replacement? e.g. `test -n "${v//>/.}" -a 1 -eq 1`
3. Is there another suggestion?

I've cross-posted this on Stack Exchange:
https://unix.stackexchange.com/q/785456/50703

Regards, Benjamin Lupton


errexit is not respected on nested functions when parent function preceeds ||

2023-08-08 Thread cirrus . mazurka-0t--- via Bug reports for the GNU Bourne Again SHell
I think I've found a bug with Bash's handling of errexit.



The following code:

``` bash
#!/usr/bin/env bash

set -Eeuo pipefail
shopt -s huponexit
shopt -s inherit_errexit

function child_function {
return 1
}
function parent_function {
child_function
echo "parent noticed child exit code as $?"
}
function grandparent_function {
local ec
ec=0 && parent_function || ec="$?"
echo "grandparent noticed parent exit code as $ec"
}

grandparent_function
```

Will surprisingly output:

```
parent noticed child exit code as 1
grandparent noticed parent exit code as 0
```




Changing the code to:

``` bash
#!/usr/bin/env bash

set -Eeuo pipefail
shopt -s huponexit
shopt -s inherit_errexit

function child_function {
return 1
}
function parent_function {
child_function || return "$?"
echo "parent noticed child exit code as $?"
}
function grandparent_function {
local ec
ec=0 && parent_function || ec="$?"
echo "grandparent noticed parent exit code as $ec"
}

grandparent_function
```

Returns the expected result of:

```
grandparent noticed parent exit code as 1
```




Is there an additional setting that I need to set to fix this? Or is this a bug 
in bash?



The reason I believe it is a bug, is that changing the code to not use the `|| 
ec="$?"` will cause each called function to exit on initial failure:

``` bash
#!/usr/bin/env bash

set -Eeuo pipefail
shopt -s huponexit
shopt -s inherit_errexit

function child_function {
return 1
}
function parent_function {
child_function
echo "parent noticed child exit code as $?"
}
function grandparent_function {
parent_function
echo "grandparent noticed parent exit code as $?"
}

grandparent_function
```

Outputs nothing and returns exit code 1



Cross-posted to https://stackoverflow.com/q/76861137/130638



Bash verison:

```
GNU bash, version 5.2.15(1)-release (aarch64-apple-darwin22.1.0)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
```