3

I just realised that a workflow I've been using for years, doesn't do what it is supposed to do. Since I haven't realised that for such a long time, you might think it's not worth putting much effort into it, but it turns out that right now, it has become somewhat important.

What am I talking about? Okay, I have tmux running with several sessions and each session has different windows and so on. Working like that is wonderful. There's one downside to it, though. When the server gets restarted, for whatever resason, it closes all my sessions. Fair enough, cannot be avoided and doesn't happen often. However, the annoying part is, that all my zsh or bash history is gone as well. This is a problem. I rely on my history, maybe far too much.

I was circumventing this problem by hitting fc -W (in zsh) every now and then. I thought this would append history that is in the memory and I would then only lose the part between my last invocation of fc -W and the restart of the server. But that's not what it does. If I use fc -W in one window, then fc -W in another one, the history from the first window would be overwritten by the history from the second window. I would need to use fc -R first, but this would duplicate the whole history... basically I was misusing the fc command the whole time.

Here's the question: How can I make sure to not lose any of my history when I'm in tmux and there is a sudden power cut? Note:

  • I use infinite history, in case that matters.
  • Losing some of the history is ok, i.e. if I have to invoke a command by hand (or in a cronjob) and I lose the part of the history since the command has last been run, that's fine.
  • Exiting the terminal and open up new one is not the solution.
  • I don't want to store my commands directly to the history, since this mixes up different histories.
  • Solutions for both bash and zsh are welcome. zsh is preferred.

Edit: Highlight the part that everyone seems to misunderstand.

pfnuesel
  • 5,837

2 Answers2

2

You can save your bash history with this command (I am not familiar with zsh):

history -a

This seems to work with zsh:

fc -ln 1 -1 > ~/.zsh_history
Hauke Laging
  • 90,279
  • That seems to do the trick. Probably I will just call bash within zsh and then invoke history -a. – pfnuesel Jan 07 '18 at 19:24
  • @pfnuesel I don't think that will work but maybe I misunderstand what you have in mind. Why call bash from zsh? Would you execute the command manually or do you want it automated? – Hauke Laging Jan 07 '18 at 19:27
  • You are right, that won't work, obviously bash and zsh have different histories. Automatising the process would be nice to have, but is not absolutely necessary. – pfnuesel Jan 07 '18 at 19:30
  • @pfnuesel Maybe it helps to set an EXIT trap with this command. In addition you could set a trap for SIGUSR1 and create a cron job which sends this signal to the shell. – Hauke Laging Jan 07 '18 at 19:37
  • That's an excellent idea for catching the history when the server is turned off. However, I first need a solution to grab the zsh history, since this is the shell I'm usually working with. I guess a combination of fc commands will do the trick, but it is not yet clear to me how. – pfnuesel Jan 07 '18 at 19:42
  • @pfnuesel See my edit. The funny part is that this was the first version of my answer for bash before I happened to notice the bash history command... So for once bash is better that zsh... You can use the same command for both shells. – Hauke Laging Jan 07 '18 at 20:23
  • 1
    The zsh command you propose doesn't do what it should do: it replaces the history file with the history from that shell instance, which wipes out what other instances have written. The bash command kind of works, but it's substandard because it appends the complete history from that shell instance, which duplicates lines that were already present the last time you ran it. – Gilles 'SO- stop being evil' Jan 07 '18 at 20:25
  • @HaukeLaging Thanks for your help. I went with Gilles answer in the end, since fc -AI does exactly what I need. Your answer could be modified as well, I guess, to retain the history. – pfnuesel Jan 07 '18 at 21:43
2

In zsh, use fc -AI to save your history, not fc -W. Use -A, not -W, otherwise the history from other shell instances is overwritten. And -I saves only the new history entries since the last save.

Given your workflow, rather than saving manually, you should probably save the history automatically. Turn on the inc_append_history option to save each command to the history file immediately before it gets executed.

While it's possible to achieve the same effect in bash, properly sharing history between bash instances is harder. See Preserve bash history in multiple terminal windows

  • Thank you! I haven't tested yet, but this looks like a lifesaver! I don't want to use inc_append_history, since it mixes different histories together. – pfnuesel Jan 07 '18 at 20:29
  • Sorry, but who is downvoting this answer? It is the perfect answer, the only one actually answering my question... – pfnuesel Jan 07 '18 at 21:41