Re: [bash 4] 'test -v 1' is never true

2022-11-28 Thread Alex Colomar

Hi Martin,

On 11/27/22 17:53, Martin D Kealey wrote:
The expansion `$[var+replacement}` was part of the Bourne shell when I 
used it in 1985 (before POSIX was first published),


I didn't know that; interesting.  Still looks ugly/convoluted to me to 
use that feature here.  Might be useful if I didn't had another tool...


whereas `test A -gt 
B` is rather newer,


Being POSIX, it's old enough for my taste :)

and `test -v` is only a Bash extension (and 
similarly wasn't added until later).


Yeah, I started using that for consistency with other -v tests.  In 
fact, the first time I used it instead of $#, I wasn't sure if it would 
work.


I think $# wins for me.

Thanks!

Alex



The man and info pages have retained the rather terse descriptions of 
those oldest expansions, and they are buried in the sheer volume of the 
current documentation.



On Sun, 27 Nov 2022 at 23:00, Alejandro Colomar > wrote:


Hi Alexey,

On 11/27/22 12:41, Alexey wrote:
 > On 2022-11-26 21:45, Alejandro Colomar wrote:
 >> That was my gut; thanks!  I'll workaround with $#.
 >
 > I could suggest you to use for clarity another construction:
 > [[ ${1+isset} ]] || echo "not set"
 >
 > Here "isset" is just for readability. You could place any other
string literal
 > there.

I actually find that very confusing.  What feature is it using?  I
couldn't find
it with `info bash | less` then `/\+`.

      test $# -ge 1

has the benefit that it's just a sed(1) away from my old

      test -v 1

And it only needs the following to be understood:

      man test | grep -A1 ' -ge '
      man sh | grep '   # '

The old version (test -v 1) required:

      help test | grep ' -v '
      man sh | sed -n '/^   Positional/,/^$/p'

Both are easy to find.

 >
 > Regards,
 > Alexey.

Cheers,

Alex

-- 
>




--




OpenPGP_signature
Description: OpenPGP digital signature


Re: [bash 4] 'test -v 1' is never true

2022-11-27 Thread Robert Elz
Date:Mon, 28 Nov 2022 02:53:40 +1000
From:Martin D Kealey 
Message-ID:  


  | The expansion `$[var+replacement}` was part of the Bourne shell when I used
  | it in 1985 (before POSIX was first published),

>From the original Bourne sh (released outside Bell Labs in 1979)

  | whereas `test A -gt B` is rather newer,

No, same vintage.   All appeared in 7th edition - though test wasn't
built into the shell back then (still worked just the same, just a bit
slower).

  | and `test -v` is only a Bash extension (and similarly wasn't
  | added until later).

Yes.

There's also no need to use [[ ]] for this, good old test (or [ ])
works for everything described here, except -v, (and is portable).

kre




Re: [bash 4] 'test -v 1' is never true

2022-11-27 Thread Martin D Kealey
The expansion `$[var+replacement}` was part of the Bourne shell when I used
it in 1985 (before POSIX was first published), whereas `test A -gt B` is
rather newer, and `test -v` is only a Bash extension (and similarly wasn't
added until later).

The man and info pages have retained the rather terse descriptions of those
oldest expansions, and they are buried in the sheer volume of the current
documentation.


On Sun, 27 Nov 2022 at 23:00, Alejandro Colomar 
wrote:

> Hi Alexey,
>
> On 11/27/22 12:41, Alexey wrote:
> > On 2022-11-26 21:45, Alejandro Colomar wrote:
> >> That was my gut; thanks!  I'll workaround with $#.
> >
> > I could suggest you to use for clarity another construction:
> > [[ ${1+isset} ]] || echo "not set"
> >
> > Here "isset" is just for readability. You could place any other string
> literal
> > there.
>
> I actually find that very confusing.  What feature is it using?  I
> couldn't find
> it with `info bash | less` then `/\+`.
>
>  test $# -ge 1
>
> has the benefit that it's just a sed(1) away from my old
>
>  test -v 1
>
> And it only needs the following to be understood:
>
>  man test | grep -A1 ' -ge '
>  man sh | grep '   # '
>
> The old version (test -v 1) required:
>
>  help test | grep ' -v '
>  man sh | sed -n '/^   Positional/,/^$/p'
>
> Both are easy to find.
>
> >
> > Regards,
> > Alexey.
>
> Cheers,
>
> Alex
>
> --
> 
>


Re: [bash 4] 'test -v 1' is never true

2022-11-27 Thread Alejandro Colomar



On 11/27/22 14:10, David wrote:

On Mon, 28 Nov 2022 at 00:01, Alejandro Colomar  wrote:

On 11/27/22 12:41, Alexey wrote:

On 2022-11-26 21:45, Alejandro Colomar wrote:



I could suggest you to use for clarity another construction:
[[ ${1+isset} ]] || echo "not set"



Here "isset" is just for readability. You could place any other string literal
there.



I actually find that very confusing.  What feature is it using?  I couldn't find
it with `info bash | less` then `/\+`.


See:
https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
- Under heading: ${parameter:+word}
- The parameter is 1
- The word is isset
- The colon ':' is optional, explained by the sentences beginning with
"Omitting the colon" ..


Ahh, it was the optional-ness of ':' that bugged me.  I'm also quite 
unaccustomed to [[ expr ]].  :)


Thanks!

Cheers,

Alex


--



OpenPGP_signature
Description: OpenPGP digital signature


Re: [bash 4] 'test -v 1' is never true

2022-11-27 Thread David
On Mon, 28 Nov 2022 at 00:01, Alejandro Colomar  wrote:
> On 11/27/22 12:41, Alexey wrote:
> > On 2022-11-26 21:45, Alejandro Colomar wrote:

> > I could suggest you to use for clarity another construction:
> > [[ ${1+isset} ]] || echo "not set"

> > Here "isset" is just for readability. You could place any other string 
> > literal
> > there.

> I actually find that very confusing.  What feature is it using?  I couldn't 
> find
> it with `info bash | less` then `/\+`.

See:
https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
- Under heading: ${parameter:+word}
- The parameter is 1
- The word is isset
- The colon ':' is optional, explained by the sentences beginning with
"Omitting the colon" ..



Re: [bash 4] 'test -v 1' is never true

2022-11-27 Thread Alejandro Colomar

Hi Alexey,

On 11/27/22 12:41, Alexey wrote:

On 2022-11-26 21:45, Alejandro Colomar wrote:

That was my gut; thanks!  I'll workaround with $#.


I could suggest you to use for clarity another construction:
[[ ${1+isset} ]] || echo "not set"

Here "isset" is just for readability. You could place any other string literal 
there.


I actually find that very confusing.  What feature is it using?  I couldn't find 
it with `info bash | less` then `/\+`.


test $# -ge 1

has the benefit that it's just a sed(1) away from my old

test -v 1

And it only needs the following to be understood:

man test | grep -A1 ' -ge '
man sh | grep '   # '

The old version (test -v 1) required:

help test | grep ' -v '
man sh | sed -n '/^   Positional/,/^$/p'

Both are easy to find.



Regards,
Alexey.


Cheers,

Alex

--



OpenPGP_signature
Description: OpenPGP digital signature


Re: [bash 4] 'test -v 1' is never true

2022-11-27 Thread Alexey via Bug reports for the GNU Bourne Again SHell

On 2022-11-26 21:45, Alejandro Colomar wrote:

That was my gut; thanks!  I'll workaround with $#.


I could suggest you to use for clarity another construction:
[[ ${1+isset} ]] || echo "not set"

Here "isset" is just for readability. You could place any other string 
literal there.


Regards,
Alexey.



Re: [bash 4] 'test -v 1' is never true

2022-11-26 Thread Alejandro Colomar

Hi Chet!

On 11/26/22 18:44, Chet Ramey wrote:

On 11/25/22 4:02 PM, Alejandro Colomar wrote:

Hi!

I wrote a script, and am trying it on many systems.  On RHEL8, which has bash 
4, it didn't work.  I could reduce the problem to the following command, which 
never returns true:


 test -v 1;


This is a bash feature. I cribbed it from ksh93, and it first appeared in
bash-4.2.

The initial implementation was restricted to shell variables -- positional
parameters like $1 are not shell variables.

After a bunch of requests, like

https://lists.gnu.org/archive/html/bug-bash/2018-12/msg00098.html
https://lists.gnu.org/archive/html/bug-bash/2018-12/msg00104.html
https://lists.gnu.org/archive/html/bug-bash/2020-01/msg00027.html

I added support for testing positional parameters in bash-5.1.


That was my gut; thanks!  I'll workaround with $#.

Cheers,

Alex


--



OpenPGP_signature
Description: OpenPGP digital signature


Re: [bash 4] 'test -v 1' is never true

2022-11-26 Thread Chet Ramey

On 11/25/22 4:02 PM, Alejandro Colomar wrote:

Hi!

I wrote a script, and am trying it on many systems.  On RHEL8, which has 
bash 4, it didn't work.  I could reduce the problem to the following 
command, which never returns true:


     test -v 1;


This is a bash feature. I cribbed it from ksh93, and it first appeared in
bash-4.2.

The initial implementation was restricted to shell variables -- positional
parameters like $1 are not shell variables.

After a bunch of requests, like

https://lists.gnu.org/archive/html/bug-bash/2018-12/msg00098.html
https://lists.gnu.org/archive/html/bug-bash/2018-12/msg00104.html
https://lists.gnu.org/archive/html/bug-bash/2020-01/msg00027.html

I added support for testing positional parameters in bash-5.1.

--
``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: [bash 4] 'test -v 1' is never true

2022-11-25 Thread Robert Elz
Date:Sat, 26 Nov 2022 10:09:22 +0700
From:Robert Elz 
Message-ID:  <28751.1669432...@jacaranda.noi.kre.to>

  | This can be easier to read if written as 'test "$@" -ge 1'
  | which means the same.

And of course, I meant $# there, not $@   (just a typo...)

kre




Re: [bash 4] 'test -v 1' is never true

2022-11-25 Thread Greg Wooledge
On Sat, Nov 26, 2022 at 10:09:22AM +0700, Robert Elz wrote:
> My preferred method for this, which works for all kinds
> of variables and parameters is
> 
>   test "${X+s}" = s
> 
> where X is whatever is to be tested (1 in this case)
> and "s" is any string you like, except "" .. must be
> the same both occurrences of course.

This is also recommended on 
for the general case.

I don't personally suggest using it to check how many positional
parameters were given, because there are alternatives that are much
easier to read for that case.



Re: [bash 4] 'test -v 1' is never true

2022-11-25 Thread Robert Elz
Date:Fri, 25 Nov 2022 16:53:11 -0500
From:Greg Wooledge 
Message-ID:  

  | So the question is whether "1" qualifies as a "shell variable".  I would
  | argue that it doesn't -- it's a special parameter, not a variable (because
  | you can't assign to it).

A positional param, rather than a special param, but the same argument
applies.

  | So, there's no reason to expect that "test -v 1" would work.

And even with variables, is non portable, and as alternatives
exist here which are portable and just as easy to use, why not
just use one of thise, such as:

  | you should use something like:
  | test "$#" -gt 0

but only for positional params (the 0 is 1 less than the
positional param to be checked ... for positional params,
if one exists (is set), all those before it are also set.
This can be easier to read if written as 'test "$@" -ge 1'
which means the same.

My preferred method for this, which works for all kinds
of variables and parameters is

test "${X+s}" = s

where X is whatever is to be tested (1 in this case)
and "s" is any string you like, except "" .. must be
the same both occurrences of course.

kre



Re: [bash 4] 'test -v 1' is never true

2022-11-25 Thread Alejandro Colomar

Hi Branden!

On 11/25/22 22:40, G. Branden Robinson wrote:

Hi Alex,

At 2022-11-25T22:02:46+0100, Alejandro Colomar wrote:

I wrote a script, and am trying it on many systems.  On RHEL8, which
has bash 4, it didn't work.  I could reduce the problem to the
following command, which never returns true:

 test -v 1;

In Debian Sid, where I develop, and where I have bash 5, that works
fine, and is true if the function or script in which it is has any
arguments.  On zsh(1) it also works fine.

Is this a known bug in bash?
The exact version where I can reproduce it is 4.4.20(1)-release
(x86_64-redhat-linux-gnu).


I don't think it is a bug.  It is unspecified behavior according to
POSIX.

"-v" is not an operator according to POSIX,


Yeah, I know.  I tried dash(1), which at least gives some warning:

$ cat bug.sh
#!/bin/bash

echo $1;

test -v 1 \
&& echo 'arguments';

$ dash bug.sh

bug.sh: 5: test: -v: unexpected operator



and I don't recall seeing it
in any shell.  It is therefore interpreted as a string argument.


But `-v` is a specified option of bash(1) (and also, at least, zsh(1)):

$ help test | grep '\-v'
  -v VAR True if the shell variable VAR is set.


I find it very useful, since I use `set -Eeufo pipefail` in my scripts, to 
simplify error handling.  When I want to use a variable that might be undefined, 
I first check if it exists.




   The algorithm for determining the precedence of the operators and the
   return value that shall be generated is based on the number of
   arguments presented to test. (However, when using the "[...]" form,
   the right-bracket final argument shall not be counted in this
   algorithm.)

   In the following list, $1, $2, $3, and $4 represent the arguments
   presented to test:

   0 arguments:
   Exit false (1).
   1 argument:
   Exit true (0) if $1 is not null; otherwise, exit false.
   2 arguments:

   If $1 is '!', exit true if $2 is null, false if $2 is not
   null.

   If $1 is a unary primary, exit true if the unary test is true,
   false if the unary test is false.

   Otherwise, produce unspecified results.

https://pubs.opengroup.org/onlinepubs/009695299/utilities/test.html

Regards,
Branden


Cheers,

Alex

--



OpenPGP_signature
Description: OpenPGP digital signature


Re: [bash 4] 'test -v 1' is never true

2022-11-25 Thread Greg Wooledge
On Fri, Nov 25, 2022 at 03:40:42PM -0600, G. Branden Robinson wrote:
> I don't think it is a bug.  It is unspecified behavior according to
> POSIX.
> 
> "-v" is not an operator according to POSIX, and I don't recall seeing it
> in any shell.  It is therefore interpreted as a string argument.

[...]

It's a bash extension, not part of POSIX.  From 'help test':

  -v VAR True if the shell variable VAR is set.

Or from the man page:

   -v varname
  True if the shell variable varname is set (has been  assigned  a
  value).

So the question is whether "1" qualifies as a "shell variable".  I would
argue that it doesn't -- it's a special parameter, not a variable (because
you can't assign to it).

So, there's no reason to expect that "test -v 1" would work.  If you want
to test whether there's at least one argument, you should use something
like:

(($# > 0)) # bash extension

or

test "$#" -gt 0



Re: [bash 4] 'test -v 1' is never true

2022-11-25 Thread G. Branden Robinson
Hi Alex,

At 2022-11-25T22:02:46+0100, Alejandro Colomar wrote:
> I wrote a script, and am trying it on many systems.  On RHEL8, which
> has bash 4, it didn't work.  I could reduce the problem to the
> following command, which never returns true:
> 
> test -v 1;
> 
> In Debian Sid, where I develop, and where I have bash 5, that works
> fine, and is true if the function or script in which it is has any
> arguments.  On zsh(1) it also works fine.
> 
> Is this a known bug in bash?
> The exact version where I can reproduce it is 4.4.20(1)-release
> (x86_64-redhat-linux-gnu).

I don't think it is a bug.  It is unspecified behavior according to
POSIX.

"-v" is not an operator according to POSIX, and I don't recall seeing it
in any shell.  It is therefore interpreted as a string argument.

  The algorithm for determining the precedence of the operators and the
  return value that shall be generated is based on the number of
  arguments presented to test. (However, when using the "[...]" form,
  the right-bracket final argument shall not be counted in this
  algorithm.)

  In the following list, $1, $2, $3, and $4 represent the arguments
  presented to test:

  0 arguments:
  Exit false (1).
  1 argument:
  Exit true (0) if $1 is not null; otherwise, exit false.
  2 arguments:

  If $1 is '!', exit true if $2 is null, false if $2 is not
  null.

  If $1 is a unary primary, exit true if the unary test is true,
  false if the unary test is false.

  Otherwise, produce unspecified results.

https://pubs.opengroup.org/onlinepubs/009695299/utilities/test.html

Regards,
Branden


signature.asc
Description: PGP signature