LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Syncing Command History Across Many C Shell Terminals (https://www.linuxquestions.org/questions/linux-newbie-8/syncing-command-history-across-many-c-shell-terminals-4175707477/)

TacitusKilgor 02-04-2022 11:45 AM

Syncing Command History Across Many C Shell Terminals
 
I haven't been able to find an answer to this question after looking into it for almost a week. Please help me, Linux Questions, you're my only hope. Working on Red Hat Enterprise Linux Workstation, Release 6.6.

For work, I remote into a Linux server (using Remote Desktop) that uses C Shell rather than BASH (I'm not allowed to switch to BASH either). While in a session (lets call it session 1) I'll open up many tabs in a given terminal and type commands throughout all of them. I'll also sometimes open up additional sessions with Remote Desktop (lets call them session 2 and session 3) with many tabs in their respective terminals and type many commands throughout all of them.

I have noticed that the "history" command when invoked in any tab of any terminal across any session does not include all of the commands I have used across all of the tabs and sessions. Only some of the commands are saved. Or alternatively, if I press the up arrow in one terminal, I get a command that is different from when I press the up arrow in another terminal.

I would like a history that:
  • Remembers all commands typed, regardless of what tab, terminal or session I am in
  • Instantly accessible from any of tabs/terminals/sessions

I've found solutions for BASH Shells, but not C Shell. I've found some information about C Shell on my own and have tried to implement solutions on my own without success. I've tried adding the following to the ".cshrc" file:

Code:

set history=10000
set savehist=(10000 merge)
alias precmd 'history -L, history -S'

and:

Code:

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

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

but both of these don't work, and in some cases mess up the history count (every time I type "history", the count increases by thousands)!

It's been super frustrating, especially because I've been at this problem for a week. Even if I could get the history to sync up across terminal tabs in a single session, I would be happy. Having this capability would seriously speed up my learning process.

computersavvy 02-04-2022 02:37 PM

Each terminal session tab has its own buffer that is accessed by the up & down arrows.
Each session has its own access to the history for saving and then it only writes to the history when that session is properly closed, i.e. when each tab has been closed by 'exit' and the last tab is closed by exit. Thus the order of entries in the history shows, not in the order the commands were used, but in the order the commands were used combined with the order the tabs were closed.

If you want the history to show everything done and in the order it was done you will need to limit your sessions and tabs to one of each and exit that one before you open the next.

ondoho 02-04-2022 02:50 PM

The bash soluitions, iirc, require the shell to write out the internal history each time you press enter (and also read it back into memory?).
My guess is that it will be pretty much the same on csh.

computersavvy 02-04-2022 05:51 PM

If that is true then the history file when using multiple terminal windows/tabs would have commands mixed from those different terminal sessions. I am not sure what the OP expected but it seemed he did not want them mixed like that. I don't think he really has an option though.

scasey 02-04-2022 06:01 PM

I’m too busy/lazy to look it up right now, but I believe there are switches to cause the history to write to/read from disk. See your man page.
Personally, I’m OK with the per-session histories…

shruggy 02-05-2022 08:50 AM

^ Yep. What scasey said.
Quote:

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.

With -L, the shell appends filename, which is presumably a history list saved by the -S option or the savehist mechanism, to the history list. -M is like -L, but the contents of filename are merged into the history list and sorted by timestamp. In either case, histfile is used if filename is not given and ~/.history is used if histfile is unset. `history -L' is exactly like 'source -h' except that it does not require a filename.

Note that login shells do the equivalent of `history -L' on startup and, if savehist is set, `history -S' before exiting. Because only ~/.tcshrc is normally sourced before ~/.history, histfile should be set in ~/.tcshrc rather than ~/.login.

TacitusKilgor 02-07-2022 03:19 PM

computersavvy, I found this solution which apparently would give me everything I want if I was working in a BASH shell:

Code:

# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend

# After each command, append to the history file and reread it
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

source for above solution

It looks like this solution appends a command to the history file the moment it is written, so commands would essentially be organized chronologically. So while the commands would be "mixed" from different terminals, there would be some order to them. This kind of order is exactly what I am looking for.

scasey & shruggy, I took a look at the man page by typing "man history" at the terminal and now I am really confused.

Firstly, the manual seemed to be for BASH: The top of the manual read "BASH_BULITINS(1)" and the bottom of the document read "GNU Bash-4.0...2004 Apr 20...BASH_BULITINS(1)". Typing "ps" at the terminal confirms that I'm running a C Shell, so why is there a bash manual?

Secondly, I found no mention of "savehist" in this manual. There are options for the history command namely:

Code:

-c: Clear the history list by deleting all the entries.
-d offset: Delete the history entry at the new position.
-a: Append the "new" history lines (history lines entered since the beginning of the current bash session) to the history file.
-n: Read the history lines not already read from the history file into the current history list.
    These are lines appended to the history file since the beginning of the current bash session.
-r: Read the contents of the history file and use them as the current history.
-w: Write the current history to the history file, overwriting the history file's contents
-p: Perform history substitution on the following args and display the result on the standard output.
    Does not store the result in the history list.
    Each arg must be quoted to disable normal history expansion.
-s: Store the args in the history list as a single entry the last command in the history list as a single entry.
    The last command in the history list is removed before the args are added.

I wonder if these all work though: I tried typing "history -c" in the terminal, followed by "history" to see it the "histroy -c" command worked, but the full history list still populated.

All, what if I added something like this to the ".cshrc" file:
Code:

alias postcmd 'history -a; history -c; history -r'
After every command I enter, which is stored in the history list, I append the entirety of the current history list to the history file (-a). Then, I clear the entirety of the history list (-c). Finally, I read the contents of the current history file into the current history list (-r). If this line of code works as I have described (which I would appreciate all of your comments on), and if I were to implement this on a fresh session with an unpopulated history list and history file, then the history list would be populated with one command at the time of entry, transferred to the history file, deleted from the history list, and then the history list would be populated with an "updated" history file.

shruggy 02-07-2022 03:27 PM

The manual page for tcsh is obviously tcsh(1). The quoted part is from Builtin commands because... well, history is a builtin command.

Until not so long ago, man history would result in
Code:

No manual entry for history
But then Bash maintainers took pity on Linux newbies and provided builtins(1) man page, with redirects to it from the names of all the builtins.


All times are GMT -5. The time now is 06:15 AM.