NetBSD-Users archive

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

Re: HISTFILE support for /bin/sh



On Sat, 6 Jul 2024, Robert Elz wrote:

 | Or provide a cmd to write out the history (non-append mode) in the
 | EXIT handler?

I think that will be possible; if HISTAPPEND gets set, the current
history buffer will be flushed to the file immediately - it needs to
be or history order wrt future commands would be broken.   If you
were to set HISTAPPEND=yes in the exit trap, then (assuming HISTFILE is
set of course) the history buffer would be flushed, and of course, by
the time the exit trap is run, no more commands are going to be read,
so (apart from causing the buffer to be flushed) turning HISTAPPEND
on wouldn't do anything else.   You'd want to leave it set to prevent
the shell from writing the history buffer again (destroying your work)
when the shell exits.


OK, so this is working out quite well so far. I have:

# ~/.profile

```
if [ -n "$NETBSD_SHELL" ]
then    export HISTFILE=$HOME/.sh.hist
        export HISTAPPEND=true
        export HISTSIZE=100000
fi
trap 'suniq.sh "$HISTFILE"' EXIT
```

# ~/bin/suniq.sh

```
#!/bin/sh
#
# Massage NetBSD /bin/sh's history file before running nuniq.awk.

set -eu -o pipefail

F=${1:-$HOME/.sh.hist}
[ -f "$F" ] || exit 0                   # no file

H=$(head -n1 "$F")
[ "$H" = _HiStOrY_V2_ ] || exit 0       # nolle pros.

n=$(who | awk -v U="$(id -nu)" '$1==U { n++ } END { print n+0 }')
[ $n -eq 1 ] || exit 0                  # not final sess.

T=$(mktemp "$F.XXXXXX")
trap '[ -f "$T" ] && rm -f "$T"' EXIT   # clean-up

"$T" (
echo "$H"                               # signature
sed -Ee '
    # delete 1st line, lines w/ leading blanks.
    # remove trailing blanks.
    1d
    /^(\\040|\\011)/d
    s/(\\040|\\011)+\\012$/\\012/
' "$F" | nuniq.awk && mv -f "$T" "$F"
)
```

# ~/bin/nuniq.awk

```
#!/usr/bin/awk -f

{
        if ($0 in A)
                delete L[A[$0]]
        L[NR] = $0
        A[$0] = NR
}
END {
        for (i = 1; i <= NR; i++)
                if (i in L)
                        print L[i]
}
```

Gets rid of duplicate lines and lines beginning with blanks (just like in
bash). Suggestions for improvement welcome.

-RVP


Home | Main Index | Thread Index | Old Index