NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: HISTFILE support for /bin/sh



    Date:        Thu, 04 Jul 2024 10:47:12 -0700
    From:        "Greg A. Woods" <woods%planix.ca@localhost>
    Message-ID:  <m1sPQY4-003UYYC@more.local>

  | Shouldn't the on-disk history initially be prepended to in-core history
  | (which might only be what has been sourced so far from the profiles etc.)?

That might be nice, perhaps, though it would be a little weird if one did:

	HISTFILE=x
	HISTFILE=y
	HISTFILE=z

and the data appeared in history in the order z y x ...

I'm also just using the libedit (editline) history facilities - which is
what sh has always used for its history.   They have supported reading/writing
files for ages, just sh didn't make use of that functionality (that only
those minor changes were needed was how I made this stuff mostly work in a
day and a half...)

libedit has a "load" function, but it is "load and append", there's no
"load and prepend" to make use of, so either libedit would need new
functionality, or sh would need to duplicate a whole bunch of libedit code,
or do some exotic manipulation: save history to temp file, clear hist
buffer, load HISTFILE, load temp file, remove temp file.

Only data typed by the user on stdin ever counts (or more correctly I
think, only data read by the shell from stdin, in an interactive shell).
If HISTFILE is set in the environment, or a startup script, then that
setting happens before there's any possibility of any history eligible
commands being entered, so whether we append or prepend the contents of
the file makes no difference, the file contents will be everything at that
point.   It only makes a difference if HISTFILE is set (perhaps again) later.

  | Then, if HISTAPPEND is set any new history written to the file since it
  | was last read could be appended to in-core history.

That one I don't think libedit supports.   It might be possible to make
work in sh, but I'm not sure that's what most people want.   Eg: I have
a sh function:

	!!() { fc -s -1; }

which does what a simple "!!" does in csh (repeat the last command, the
most recent in history ... the function just because that's my ancient
finger muscle memory, and because it is shorter than typing the fc command)
but whether one uses !! (or something like it) or just "fc -s -1", I doubt
anyone would like it much if it repeated the most recent command that was
made in any sh sharing a HISTFILE, so I think attempting to make that
suggestion work would be something of a disaster.

If someone really wanted that, then (after HISTFILE appears in sh, assuming
that actually does happen) one could do
	PS1='$(HISTFILE=${HISTFILE})$ '
(along with set -o promptcmds) which would cause the shell to re-read the
history file every time PS1 is printed - which would (almost) do what you're
suggesting - the effect would be very similar, assuming HISTAPPEND is set as
well.


  | Do you have plans for adding HISTSIZE as well?

No need, that's been there for a long time (even documented).   However,
there's a bug, where if one attempts to set HISTSIZE to a non-numeric
value which doesn't start with '-' an error will be generated (that's OK,
and will remain, other than the "except -*" part which is just silly),
but in existing shells, including today's HEAD, if you have HISTSIZE in
the environment with a bad value like that, the shell won't start at all,
just issues an error and exits.   try:
	HISTSIZE=foo /bin/sh
That's not good, but fixing it properly is a non-trivial change (I might
make a temporary change to just ignore such bad settings, rather than error
them, just to avoid this issue - that kind of change could be pulled up
to -9 and -10).

I'm not sure what other shells do, but in libedit, its internal version of
HISTSIZE seems to be the number of history entries that the history mechanism
won't allow to exist (so HISTSIZE=100 -- the default in sh -- means up to 99
history entries can exist).   If it would be desirable, I could easily "fix"
that (if needed) by just adding 1 to the value before passing it to the libedit
history management routines.   Note: setting HISTSIZE to 1 or 2 means 1
history element exists, as we don't allow none to be there, but setting it
to 0 will cause sh to generate "internal error" for some attempted history
manipulation, such as "fc -l" ... the "add one" solution is looking better
and better...  though I think an internal sh code change will be a better
solution to that particular problem - that isn't a problem you'd normally
ever see now, but:
	/bin/sh -csi 'fc -l'
will make it happen in today's sh, regardless of what HISTSIZE is set to,
as when that fc command is run, the history buffer is certain to be empty
currently - the "si" are needed to allow history to be enabled at all, without
them you'd just get a more reasonable "history is not active" error).
Note this internal error isn't fatal to the shell, so after the above error
you're still in an interactive sh.

kre

ps: if these changes go in, one more I forgot to mention yesterday, is that
there will be a new "fc" option (-z) to clear the history buffer completely.




Home | Main Index | Thread Index | Old Index