Re: wrong variable name in error message about unbound variable?

2023-10-17 Thread Christoph Anton Mitterer
On Tue, 2023-10-17 at 00:26 -0400, Grisha Levit wrote:
> The array subscript can an arbitrary arithmetic expression with side
> effects, so it makes sense to perform the expansion even if the array
> whose subscript is being expanded is unset:

Okay... that's all pretty convoluted. I assume it boils down to the
idea that a variable that's not an associative array may become
automatically an indexed array, right?


As Lawrence pointed out:
$ set -u 
$ declare -A a
$ echo ${a[k]}
bash: a[k]: unbound variable

Here it actually looks first at a (which turns out to be an associative
array) and thus doesn't even bother to evaluate k, which makes sense of
course, in order to avoid any side effects.


Here, when a is still undeclared it still makes "sense" to evaluate the
subscript, as a may even become a declared indexed array while doing
so:
$ set -u
$ declare -p a
bash: declare: a: not found
$ echo ${a[a[4]=0]}
bash: a[a[4]=0]: unbound variable
$ declare -p a
declare -a a=([4]="0")

okay, makes sense to me. But:
$ set -u
$ declare -p a
bash: declare: a: not found
$ echo ${a[a[4]=4]}
bash: a[a[4]=4]: unbound variable
$ declare -p a
declare -a a=([4]="4")

Why does it say unbound here?
a[4]=4 should evaluate to 4 and also set the index 4, right?



Cheers,
Chris.



Re: wrong variable name in error message about unbound variable?

2023-10-16 Thread Christoph Anton Mitterer
Hey.

On Mon, 2023-10-16 at 22:05 -0400, Lawrence Velázquez wrote:
> Under no circumstances should your examples complain about "array"
> because they do not attempt to expand it.  As I demonstrated, your
> examples do not even complain about unset scalar variables.

Okay I realise now, why it worked once it was declared an associative
array.

But why does it even try to evaluate the subscript "key" as arithmetic
expression?

Yes it's defined for indexed arrays, but shouldn't it already know that
there is no indexed array of the name "array" and any evaluation of the
subscript is thus pointless?



And a follow up question on this (guess its pointless to post this now
on help-bash):

When one just wants to check whether some var[key] is set with var
being an associative array and assuming that set -u might be in effect.

It's obviously not enough to do:
  [[ -v var[key] ]]

- in an indexed array it would do arithmetic evaluation of the key
  and might give a false positive as in:
  $ declare -a a
  $ a[3]=foo
  $ key='1+2'
  $ [[ -v a[key] ]]; echo $?
  0

- or as above, it might yield nothing but give the unbound error


One cannot use e.g ${var@a} or ${var@A} either as these would already
give unbound errors if the variable is not set (declaring it wouldn't
suffice either).

So AFAICS, the only way is to match the output of "declare -p var" for
"declare -A *" and only then to the [[ -v ... ]]?
Or would it make sense to exempt @a and @A form set -u?


Thanks,
Chris.



wrong variable name in error message about unbound variable?

2023-10-16 Thread Christoph Anton Mitterer
Hey.

On 5.2.15 I've noticed the following:

$ set -u
$ [ -n "${array[key]+is_set}" ] && echo is set || echo not set
bash: key: unbound variable
$ [[ -v array[key] ]] && echo is set || echo not set
bash: key: unbound variable

$ declare -A array
$ [ -n "${array[key]+is_set}" ] && echo is set || echo not set
not set
$ [[ -v array[key] ]] && echo is set || echo not set
not set

Once array is declared (not even anything of it set yet) it gives
already no unbound error.

So shouldn't the error message refer to "array" as the unbound
variable? Or perhaps both "array[key]"?
Because the problem isn't that no key named "key" exists.


And beyond that:
POSIX says:
> -u
>When the shell tries to expand an unset parameter other than the
>'@' and '*' special parameters, it shall write a message to
>standard error and the expansion shall fail with the consequences
>specified in Consequences of Shell Errors.

But just declaring the var, doesn't make it set... so shouldn't it
still give an error message (which it does when using a non-array
variable that is declared but not set)?


Cheers,
Chris.



Re: definite way to determine the running shell

2015-03-27 Thread Christoph Anton Mitterer
On Fri, 2015-03-27 at 01:44 -0600, Eduardo A. Bustamante López wrote: 
 Why would the user set BASH_VERSION in the environment? That sounds like 
 asking
 for trouble!
Murphy's law! :D


 - try to unset BASHOPTS (did it work? then it's not bash)
 - Now, store the value of BASHOPTS in a temp var
 - Set a shopt option that's not set already in BASHOPTS (or unset one from
 BASHOPTS)
 - Check if the value of BASHOPTS changed.
that sounds like a nice idea.

I just thought about another solution myself
PATH= shopt

then only a shell having shopt (hopefully that is just bash) should give
$?=0 .



Thanks,
Chris.


smime.p7s
Description: S/MIME cryptographic signature


Re: definite way to determine the running shell

2015-03-27 Thread Christoph Anton Mitterer
On Fri, 2015-03-27 at 15:11 -0400, Greg Wooledge wrote: 
 OK, this is for some personal configuration management.
Well it's rather for some 1000 institute workstations,...

   Not as part of
 a product you're deploying, etc.  As such, presumably you are not trying
 to trick yourself into breaking your own logins or shell startups.
... and you never really know what strange thins users accidentally
do ;)


   So,
 just check for $BASH_VERSION and you should be all right.
Sure,... I just wanted to as, whether there's maybe a much more obvious
fool-proof solution :)



 Though, if it were me, I'd just simplify everything.  Don't use so many
 different shells, don't use such complicated aliases that you have to
 have multiple versions of them
I personally just use bash (except for sh where it's dash)... but see
above :)


Cheers,
Chris.


smime.p7s
Description: S/MIME cryptographic signature


Re: definite way to determine the running shell

2015-03-27 Thread Christoph Anton Mitterer
On Fri, 2015-03-27 at 08:56 +0100, Andreas Schwab wrote: 
 Why do you need to know that?
Well there are so many use cases... my particular one is, that many
shells share config files (e.g. .profile) and for other cases (e.g.
aliases definitions) it would be handy if one could set up a sourcable
script, which does the necessary stuff, automatically in the way for the
current shell.


Cheers,
Chris.


smime.p7s
Description: S/MIME cryptographic signature


Re: definite way to determine the running shell

2015-03-27 Thread Christoph Anton Mitterer
On Fri, 2015-03-27 at 14:56 -0400, Greg Wooledge wrote: 
 ... why are you running test suites in your .bashrc??

As said, I'd find it nice to have one aliases file for all shells, and
that would in turn then be sourced from either .profile or
rather .bashrc... so while tests wouldn't run in .bashrc itself, they'd
always be executed along.


smime.p7s
Description: S/MIME cryptographic signature


definite way to determine the running shell

2015-03-26 Thread Christoph Anton Mitterer
Hey.

There are a lot of articles on the web about detecting the actually
running shell.
Unfortunately, just relying on $SHELL doesn't really work since when I
invoke e.g. csh from bash, it would be still $SHELL=bash and I guess I
won't be able to convince all shell upstreams to overwrite $SHELL (which
IMHO would be much better, and more like $TERM).

Now I see basically two other ways to detect a shell:
a) using ps or something similar... which is not really portable either
and can be rather easily/accidentally fooled

b) Using some env vars typically to the shell, e.g. BASH_VERSION for
bash.
AFAIU per default these are not declared'ed -x , so when I rund fooShell
from bash it wouldn't be inherited.
But the user could still manually mark it exportable.

c) I've also thought about somehow using e.g. shopt, when it runs I
could be sure, it was bash. But for that in turn I'd need to make sure
whether it's a built-in command, which works in bash with the builtin
built in command ;) ... but not portably as in POSIX shell command
language (at least not that I'd know).


Is there some better way to do this (at least to detect bash)? E.g. some
VAR that bash sets and that it would neither take from its own
environment when being started nor that it would pass on to processes?

Thanks,
Chris.


smime.p7s
Description: S/MIME cryptographic signature


Re: feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-26 Thread Christoph Anton Mitterer
On Thu, 2015-03-26 at 16:26 -0400, Chet Ramey wrote: 
  And b) it seems kinda ugly that one needs to explicitly set a default
  value that would be set later anyway.
 Maybe.
Okay, keep me tuned if you should plan to actually do that, cause then I
can revise manually setting it :)

   It is what it is, and it's an effective workaround that you can
 use today.
Sure, thanks for that,...


  Wasn't it possible to simply set the default for histchars earlier in
  the startup?
 histchars defaulting is part of the interactive shell setup; environment
 variables are scanned before any other setup so they are available when
 the startup files are read.  The interactive shell startup comes after
 the startup files are read so the startup files can set any appropriate
 variables.
One other possibility would be, if HISTTIMEFORMAT is set and histchars
is not, while you read in the .bash_history, assume only there the
default of # and ignore these lines.
That way would probably not change the behaviour a lot.


Cheers,
Chris.




Re: feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-26 Thread Christoph Anton Mitterer
On Thu, 2015-03-26 at 15:21 -0400, Chet Ramey wrote: 
 What do you mean ignore its effect?  You have newlines embedded in
 history entries; what do you plan to do about them?
Well that was just the uneducated idea based on blind assumptions by
*not* having read the code O:-)

AFAIU, both already works:
- if cmdhist=on lithist=off
  = we get the if true; then echo foo ; fi layout for both history
 and history file + in both cases each command stays one command.
- if cmdhist=on lithist=on
  = we get the layout with embedded newlines in the history (with each
 command staying one command), but in the history file it breaks
 and the multiline command is split up in several commands

Right?

So why not make a thrid mode like:
- if cmdhist=on lithist=not-in-file
  which keeps:
if true; then\n
echo foo\n
fi
  in the history
  but writes the serialised if true; then echo foo ; fi to the history
  file.

Of course on re-loading the history it would again be the form without
\n, but better having the serialised form than mutliple commands.
And it would then at least work for the current command history

Cheers,
Chris.




Re: feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-26 Thread Christoph Anton Mitterer
On Thu, 2015-03-26 at 16:54 -0400, Chet Ramey wrote: 
 The solution cannot be bash-specific; the history library is used by many
 other applications.
One, design-wise ugly, idea:
Couldn't you abuse the history comment char another time for that?
Like consider anything between a ^#[[:digit:]] to be part of one
command:

With HISTTIMEFORMAT set that could look like:
#1427416260
echo foo
#1427416363
if true; then
echo bar
fi
#1427416625
./and_so_on


If HISTTIMEFORMAT is not set, you could simply write 0
#0
echo foo
#0
if true; then
echo bar
fi
#0
./and_so_on


AFAICS, this wouldn't break compatibility
- anything that matches ^#[[:digit:]] is already now not stored in the
  history files, AFAICS
- of course one would probably need to clear the history when one
  enables the shopt for using the above schema (or otherwise one could
  see extremely big multiline commands)
  Or one may just start with that way of parsing the file, the first
  time a ^#[[:digit:]] is encountered, and anything before is considered
  to be single commands per line.


Cheers,
Chris.




feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-25 Thread Christoph Anton Mitterer
Hey.

When HISTTIMEFORMAT is used the history time comment lines are written
to HISTFILE.
Therefore, HISTFILESIZE is effectively only half as large.

Would it be possible to simply not count the history time comment lines
when enforcing HISTFILESIZE?

Cheers,
Chris.




Re: feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-25 Thread Christoph Anton Mitterer
On Wed, 2015-03-25 at 14:48 -0400, Chet Ramey wrote: 
 The history file truncation code already skips lines that look like history
 timestamps.  Look at history.c:history_truncate_file().
Ah? Hmm was that only recently introduced?
I'm having bash4.3 with patches up to including 33. And this time I
looked whether Debian added any of it's goodness ;-)


When I set e.g. in .bashrc:
HISTSIZE=50
HISTFILESIZE=50
HISTTIMEFORMAT=$'%c\t'

Then:
$ rm .bash_history
$ history -c

Then start a new shell and then enter commands 
$ echo 1
$ echo 2
...
$ echo 50


When I do now a:
$ history
I see all the 50 (+/- 1)

But when I leave the shell and go into a new one:
$ histroy
gives me only about the last 25 (i.e. echo 27 to echo 50 + history),
and these are also the only entries in .bash_history, i.e.:
#1427309882
echo 27
#1427309882
echo 28
[snip snap]
#1427309882
echo 50
#1427309884
history



Cheers,
Chris.





Re: feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-25 Thread Christoph Anton Mitterer
On Wed, 2015-03-25 at 16:21 -0400, Chet Ramey wrote: 
 https://lists.gnu.org/archive/html/bug-bash/2011-02/msg00042.html
Maybe I've missed something but that thread basically just discussed the
same issue without giving a solution, right?

I understand you concerns about any format changes, that's why my idea
was to allow lithist set but ignore it's effect when the history file
is written... wouldn't that work out?


Cheers,
Chris.




Re: feature-request: don't count history time comment lines when in HISTFILESIZE

2015-03-25 Thread Christoph Anton Mitterer
On Wed, 2015-03-25 at 16:19 -0400, Chet Ramey wrote:
 When you start bash, and source your .bashrc, the history comment character
 is not set.  You haven't set it in .bashrc, I assume
Yes, I haven't.

 Since that's not set, the lines beginning with
 `#[digit]' are not recognized as timestamps and treated as ordinary history
 entries.
 You can fix this by assigning to histchars before setting HISTFILESIZE:
 histchars='!^#'
Okay that works in principle.

But a) this means truncation of the history file happens immediately
each the HISTFILESIZE is set and not just when the shell quits, right?

And b) it seems kinda ugly that one needs to explicitly set a default
value that would be set later anyway.
Wasn't it possible to simply set the default for histchars earlier in
the startup?
If someone wants to set histchars he'd have to do it anyway, and for
those who want to stick with the defaults, this would solve the above
issue.

Apart from that, it's not really directly obvious that histchars also
affects the history itself and not just history expansion.
E.g. it's normally not even set in my shell environment (not even the
default value).


Thanks,
Chris.




bug in documentation?

2015-03-22 Thread Christoph Anton Mitterer
Hey.

The bash manpage says:
When a login shell exits, bash reads and executes commands from the
file ~/.bash_logout, if it exists.

However, it seems that this happens only for interactive login
shells,... at least I couldn't get it executed for non-interactive login
shells with the --login option.

Could you please clarify that?


Thanks,
Chris.


smime.p7s
Description: S/MIME cryptographic signature


Re: bug in documentation?

2015-03-22 Thread Christoph Anton Mitterer
Hey.

On Sun, 2015-03-22 at 22:08 -0400, Chet Ramey wrote: 
 It does when you call the exit builtin.  EOF to an interactive shell
 executes the exit builtin, but you have to explicitly call it when in
 a non-interactive shell.
Ah... tricky :D
Okay could you then please add this? Guess many others would also never
found out without asking.

Cheers,
Chris.





smime.p7s
Description: S/MIME cryptographic signature