Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tcsh - save history right after command

Tags:

terminal

tcsh

I try to save history in tcsh after every entered command instead of saving it just after the "exit" command. This is because usually I open around 10 tabs at the same time and after it I just close the terminal window instead of typing "exit" in each tab. the result is that the history is saved only for the last tab. This solution doesn't work when I close the terminal window: https://stackoverflow.com/a/3577709/2773143.

Because I found no solution just using history commands, I tried to solve it by a different way: echoing every command to ~/.tcsh_history directly and setting set histfile= ~/.tcsh_history in the .tcshrc file. However I didn't find a way to do this as well. I thought about doing one alias in .alias to all commands, something like alias * '*; ~/someScript.tcsh (with many other versions) but it didn't work. I found how to make it work by doing a different alias to each command, but it's somewhat ugly.
for example:
alias cd 'cd \!*; ~/saveHist.tcsh \!:0 \!*'
alias grep 'grep \!*; ~/saveHist.tcsh \!:0 \!*'
(etc)
and in the ~/saveHist.tcsh file:

#!/bin/tcsh -f

echo "$argv" >> ~/.tcsh_history

but of course this is somewhat ugly and this way some commands will be written twice in the ~/.tcsh_history after closing the window.

Any ideas?

like image 874
user2773143 Avatar asked Apr 06 '14 13:04

user2773143


4 Answers

To automatically run a command after every shell command you enter, set the command to the postcmd alias. For example:

alias postcmd 'date'

…will cause the "date" command to run right after you enter a command (though it actually executes before the command you entered, as far as I can tell).

And, as Mark Armstrong alludes to in his answer, history -S saves the current history. So, theoretically, you could put

alias postcmd 'history -S'

…in your .tcshrc, and your history file will be saved every time you enter a command - so no need to create aliases for every command you might possibly use, or to use some custom script to write to your history file manually.

(EDIT: Despite what is written below, the line above now works on macOS, at least with tcsh as installed with MacPorts.)

I say this works theoretically because when I try it (as I also suffer from my history being blown away when I forget to exit before closing a Terminal window…), the .history file is written only with the history of the current shell, even if merge is specified in the savehist variable - very frustrating. But perhaps your system behaves differently (I'm on OS X), so perhaps give it a try.

like image 114
Garrett Albright Avatar answered Nov 20 '22 01:11

Garrett Albright


This might work:

  set history = 200
  set histdup = erase
  set savehist = (${history} merge lock)

  alias precmd 'history -S'
  alias postcmd 'history -M'

History is written before each command, merged after. Effects:

  • history is immediately stored, no need for closing rituals
  • parallel shells share history

Anyway, history is a fabrication.

like image 22
marafaka Avatar answered Nov 20 '22 03:11

marafaka


If you set savehist shell variable as shown below, it will merge the history into the existing history every time you save it. Below from the man page on usage of history -S:

With -S, the second form saves the history list to filename. If the first word of the savehist shell variable is set to a number, at most that many lines are saved. If the second word of savehist is set to 'merge', the history list is merged with the existing history file instead of replacing it (if there is one) and sorted by time stamp. (+) Merging is intended for an environment like the X Window System with several shells in simultaneous use. If the second word of savehist is 'merge' and the third word is set to 'lock', the history file update will be serialized with other shell sessions that would possibly like to merge history at exactly the same time.

like image 1
Mark Armstrong Avatar answered Nov 20 '22 03:11

Mark Armstrong


I tried a lot, including the perl script history cleaner from Getopt. But still my history is lost most of the time. So I added an additional history archiving method to my .cshrc. It just saves commands to a file:

alias postcmd 'history 1 >>' ~/save.hitory

in my linux (Opensuse leap 15) the postcmd alias is executed before the command is executed and after as I assumed from the meaning of the word post. What is more surprising is that the command exit appears 28 times in the file ~/save.history each time I exit the shell. Maybe this is the reason why the 'history -M' corrupts the ~/.history file.

like image 1
MatthiasB Avatar answered Nov 20 '22 01:11

MatthiasB