9

Use case: distribute zsh's history between machines in source control.

Is that something that I can achieve with zsh's history -- put history in version control the sync between machines? This is to avoid re-typing commands and quick trace.

Garo
  • 2,023
  • 9
  • 15
Tuyen Pham
  • 1,765
  • 1
  • 16
  • 46
  • **WARNING** : Although the BashHub-answer is the best way to do it, you should know that your history is on a server under control of person that you (probably) don't know and shouldn't just trust ! You can work around this by running your own server: https://github.com/nicksherron/bashhub-server – Garo May 08 '23 at 14:37

2 Answers2

2

Looks like you want BashHub:

Bashhub saves every terminal command entered across all sessions and systems and provides powerful querying across all commands.

Support for Bash and Zsh with a sweet cli for everything.

Edit: If you don't trust the person running the BashHub server for 100% and have commands that should stay private, you should run your own BashHub server.

Garo
  • 2,023
  • 9
  • 15
Marlon Richert
  • 3,715
  • 5
  • 30
-1

This is an attempt to answer how to do it using, bash or zsh

In zsh the precmd function is similar to PROMPT_COMMAND in bash, in that it gets executed before each new prompt.

An example using bash:

$ function precmd() {
    echo ssh copy the files to another machine
}
$ export OLD_PROMPT=$PROMPT_COMMAND
$ unset PROMPT_COMMAND && export PROMPT_COMMAND="precmd; $PROMPT_COMMAND"
ssh copy the files to another machine
$ pwd
/home/jmunsch
ssh copy the files to another machine
$ export PROMPT_COMMAND=$OLD_PROMPT

An example using zsh:

% function precmd() {
    echo ssh copy the files to another machine
}
% pwd
/home/jmunsch
ssh copy the files to another machine
% unset -f precmd

Add this to the .zshrc:

function precmd() {
    # across terminals, sessions 
    setopt APPEND_HISTORY
    export machines="192.168.43.70 192.168.43.71 192.168.43.72"
    for m in $machines; do
        scp ~/.zsh_history $m:~/.zsh_history
    done
}

For the .bashrc:

function precmd() {
    # since bash generally saves history on session exit
    history -a # append session to history
    history -c # clear session
    history -r # read from history
    export machines="192.168.43.70 192.168.43.71 192.168.43.72"
    for m in $machines; do
        scp ~/.zsh_history $m:~/.zsh_history
    done
}
export PROMPT_COMMAND="precmd; $PROMPT_COMMAND"

To make it easier to do this

  • Setup key based ssh login, or passwordless login.
  • Add hostnames/usernames to the .ssh/ssh_config.

related:

Some assumptions about the usage here, is that only 1 person is using 1 session at a time, all machines are online, and all histories get updated successfully.

You might be able to add some additional steps to merge histories, or keep the order of histories.

Using git:

  • type a command
  • commit changes
  • push changes to repo
  • on every other machine pull changes

It's not a trivial problem, from what I understand. Say for example you log into two machines with the same history, but then type two different commands in at the same time; do both commands get saved, do the histories diverge, do they overwrite each other?

For further research look into distributed consistency/consensus:

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
jmunsch
  • 4,166
  • 3
  • 19
  • 29
  • Can you give an explanation on `export PROMPT_COMMAND="history -a; history -c; <...>`, still look ambiguous to me. Even though I don't work at both machines at the same time, your setup look interesting for another use-case that I would cross in the future. – Tuyen Pham Nov 03 '18 at 16:37
  • @TuyenPham updated – jmunsch Nov 03 '18 at 16:46
  • 1
    `PROMPT_COMMAND` is bash-only. This question is about `zsh`. (the equivalent in `zsh` would be defining a `precmd` function). Also, the `history` command is different in `zsh`. –  Nov 03 '18 at 17:40
  • 2
    Why on earth are you defining a variable just to `eval` it? Put the code directly in `precmd`! In addition, you haven't actually solved the problem. You're uploading the file history to another machine, and never downloading it. So `$machine1` will only contain the history from the last machine where you used this. – Gilles 'SO- stop being evil' Nov 04 '18 at 10:32
  • @Gilles lol, i guess cause i'm on earth. hope the updates are more clear. – jmunsch Nov 04 '18 at 14:05
  • I think this time it works, but only under completely unrealistic assumptions. In real life people open multiple terminals, people log in remotely, people remain logged in while they aren't in front of a machine, and networks fail. – Gilles 'SO- stop being evil' Nov 05 '18 at 06:21
  • @Gilles'SO-stopbeingevil' I figured you may have some ideas on what to do here. As it happens I'm running into this exact question and quickly thought: _"this is something Gilles may be able to provide guidance on"_ (seriously your answers are _that_ good). Seriously, how do you recommend keeping history synced across machines _and_ source controlling it? – Amelio Vazquez-Reina Jan 08 '20 at 23:34