a problem that i run into every few months is i've solved a problem on one machine, but haven't yet exited from the shell so the solution is not stored in the history file yet. and i'm at a remote location, so i can't run "history -a"
solution
add the following to .bashrc
# safely append the bash history
function .save_hist {
exec 200<${HISTFILE}
if flock -w 5 200; then
history -a
flock -u 200
echo "SIGHUP received, history file saved"
else
echo "SIGHUP received, but lock failed, history not saved"
fi
exec 200<&-
}
trap '.save_hist' HUP
# signal all bashes
function save_hist {
# not no tty and user and bash
(ps h -o pid -Nt - | sed "s/ //g"; pgrep -u "$USER" bash) | sort | uniq -d | xargs kill -HUP
}
to use it, ssh into the machine and run "save_hist"
Note: this is semi untested and has the potential to kill background process (the ps arguments aren't documented perfectly). but it appears to work
Note: *all* shells to have been started since the bashrc change to work
how it works
i wanted to use SIGUSR1, but bash doesn't appear to trap that signal until the user presses enter. which defeats the purpose. SIGHUP isn't really intuitive, but it is used by some daemons to reload their config file, which is somewhat along the same lines. and afaict, interactive bash doesn't use SIGHUP for anything. i'm open to other suggestionstrap is used to catch the HUP signal and then run "history -a". i use flock since it's not clear that bash handles simultaneous saves safely, and i routinely have dozens of bash tabs open.
you can use kill directly to send the signal, but i wanted to be able to save all the active interactive shells. i couldn't find an easy way to list them, so i came up with listing everything with a tty, combining that list with the users bash instances, filtering for only duplicates, and passing those PIDs to kill. it seems to work
good luck, and let me know if you have any problems
No comments:
Post a Comment