Created attachment 149 [details] Adds a configuration option to skip reloading the command line history. It's annoying to work with two separate ash shells when they both store and reload the command line history after every command. The attached patch adds a configuration option to skip the reload.
Created attachment 179 [details] Patch: make history saving/loading concurrent-safe Please try this patch. It makes the following changes: * all history writes always append (not overwrite) history files * they reload history if they detect that file length has changed since last write * they trim history file only when it grows 4 times longer thna MAXLINES * they do this atomically by creating new file and renaming it to old.
(In reply to comment #1) > * they reload history if they detect that file length has changed since last > write This is the thing I want to get rid of. I don't want other shells to append commands to history of the shell I'm currently using. I.e. when I press the arrow key up, I want to get *always* the command I wrote in that very same shell last time. Not something that was entered in a some other shell.
Created attachment 183 [details] Patch: make history saving concurrent-safe Try try 8a.patch then. It still makes saving concurrent-safe, but does not "snoop" into history lines saved by others.
*** Bug 149 has been marked as a duplicate of this bug. ***
Another patch by Lucas Maneos is available at https://bugs.maemo.org/attachment.cgi?id=1147&action=view as part of the downstream ticket https://bugs.maemo.org/show_bug.cgi?id=4174 .
Those patches are not safe wrt concurrent writes. Try running two ash shells and give commands in each. Check history file, only commands from last shell are there.
Created attachment 193 [details] patch against 1.13.3 ash to load/save history only at start/exit time You are absolutely correct. There's no official specification regarding this[1], but it would be reasonable to expect more bash-like behaviour. The other half of the story is that currently history is saved after every interactive command or subshell, which is a bit undesirable when the filesystem is on flash memory (eg maemo or openmoko). The attached patch loads the history when the shell starts, keeps track of history lines that are new to this ash session, and when the shell exits merges these with the on-disk history. Comments welcome. [1] http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html : "If more than one instance of the shell is using the same history file, it is unspecified how updates to the history file from those shells interact"
So, nobody is actually interested in keeping the old behaviour as an option? I didn't want to change that but to add a new optional feature. But since I don't like the old behaviour, I don't mind if that's changed permanently. (In reply to comment #7) > The attached patch loads the history when the shell starts, keeps track of > history lines that are new to this ash session, and when the shell exits merges > these with the on-disk history. This approach sounds good to me.
Alexander said that "This particular problem actually does not exist in the trunk, at least, from what I see here." The patch that was used for Maemo Fremantle (Busybox 1.10.x) is at https://bugs.maemo.org/attachment.cgi?id=1162
Guys, please let me know whether fixed history saving in 1.14.0 works to your satisfaction.
(In reply to comment #10) > Guys, please let me know whether fixed history saving in 1.14.0 works to your > satisfaction. With 1.14.0 individual ash instances' histories remain separate in-memory, which is great, however the history file is still re-written after each (non-repeated) command.
> With 1.14.0 individual ash instances' histories remain separate in-memory, > which is great, however the history file is still re-written after each > (non-repeated) command. What do you want it to do instead?
Based on Comment #11, the issue I had, have been fixed. I recommend filing a new bug report about the write-on-every-command -issue.
bash either writes out the entire command history or it appends the *new* history entries based on the "histappend" shell option. either way, it only does it at shell exit. that seems perfectly reasonable, especially on embedded systems where you dont want to constantly be updating a file or truncating it and rewriting it completely. that kind of thrashing will easily piss of flash based file systems.
> that seems perfectly reasonable but it is not fair. last user wins.
With bash 3.2.48: - open a shell session and enter some commands: $ PS1="1> " 1> cat .bash_history echo 1 echo 2 echo 3 exit 1> echo A A 1> echo B B 1> echo C C - leaving that running, open a second shell session and enter some more: $ PS1="2> " 2> echo a a 2> echo b b 2> echo c c - Then, after exiting both sessions: 1> exit 2> exit the contents of .bash_history are: echo 1 echo 2 echo 3 exit PS1="1> " cat .bash_history echo A echo B echo C exit PS1="2> " echo a echo b echo c exit So no one "wins", each shell only appends the new (ie entered by the user in that session as opposed to loaded from previous history) commands to the existing history as it is at the time the shell exits. The only difference if the other shell exits first is that lines 11-15 & 5-10 will be swapped. Attachment 193 [details] implements the same behaviour in ash. Would you in principle accept a similar patch against 1.14.0? (BTW, I didn't mean to hijack Tuomas's report for this, if you prefer a separate bug report for save_history that's fine with me).
> So no one "wins", each shell only appends the new (ie entered by the user in that session as opposed to loaded from previous history) commands to the existing history as it is at the time the shell exits. This is not fair. If sessions were long, user which exited last has his commands easy to retrieve, whereas previous user has to press up arrow key zillions of times. Why? Because he exited two seconds before first one? > Would you in principle accept a similar patch against 1.14.0? Yes.
Created attachment 335 [details] patch against 1.14.0 ash to load/save history only at start/exit time (In reply to comment #17) > This is not fair. If sessions were long, user which exited last has his > commands easy to retrieve, whereas previous user has to press up arrow key > zillions of times. Why? Because he exited two seconds before first one? Right, I see what you mean. There's no correct answer since there's no official specification on how concurrent shells' history writes are supposed to behave :-| In bash at least, readline's reverse-search-history and friends make life much easier when you want to retrieve an older session's commands quickly. There is value in preserving each session's command history order though. After a bit more testing I confess I found the 1.14.0 interleaving behaviour confusing (commands not being where expected in the history relative to other commands), and as it is it wouldn't be possible to usefully implement features like fc or operate-and-get-next later. Anyway, here's a patch against 1.14.0. It hasn't been tested exhaustively but seems to work ok so far, comments welcome.
In your patch: +++ busybox-1.14.0/shell/ash.c @@ -1751,6 +1751,9 @@ #if ENABLE_ASH_RANDOM_SUPPORT static void change_random(const char *); #endif +#if ENABLE_FEATURE_EDITING_SAVEHISTORY +void save_history(line_input_t *); +#endif This should go into libbb.h, not ash.c. Interfaces are defined in .h files, not .c files. Ideally, ash should not know/care how history saving works. It just sets history file name and SAVE_HISTORY bit in ->flags.
Created attachment 337 [details] patch against 1.14.0 ash to load/save history only at start/exit time (In reply to comment #19) > This should go into libbb.h, not ash.c. Good point, updated patch uploaded. > Ideally, ash should not know/care how history saving works. It just sets > history file name and SAVE_HISTORY bit in ->flags. I agree it looks a bit unclean. However if ash is to save its history when it exits and FEATURE_EDITING_SAVEHISTORY functions live in libbb, ash needs to call some libbb function and pass it its own line_input_t (read_line_input() clears its reference to it in every incovation) so it might as well be save_history(). At least I can't think of any alternative that doesn't amount to the same thing.
There is another complication: shell can be killed. Don't know about ash, but hush for sure has a clever-ish minimalistic signal handling which AVOIDS installing signal handling if shell's reaction to the signal is to simply exit. In order to implement "delaying saving of history" this will need to be changed. Bug 723 complains about exactly this problem: that when shell gets killed, history is lost. I lean towards sticking with current (circa 1.15.x) behavior, which is (1) fair and (2) does not have "lost history" problem.