File di registro della cronologia bash / zsh per directory


14

Trovo di lavorare molto su un progetto in una directory impostata. A volte, qualche mese dopo, devo rifare qualcosa su quel progetto, ma non ricordo cosa ho fatto. Uso mercurial o git per tenere traccia delle modifiche ai file ma voglio essere in grado di ricordare quali comandi ho emesso in quella directory.

La ricerca nella cronologia della mia shell non è molto istruttiva. Ho già registrato tutto nei miei file. * _ History, ma voglio un elenco di cose che ho fatto in ~ / foo / bar, e non tutte le altre (milioni) cose che ho fatto quella settimana. Probabilmente non ricordo nemmeno quale mese ho lavorato per l'ultima volta a quel particolare progetto.

Qualcuno ha qualche idea di come un file di registro della directory di progetto di tutti i comandi della shell che ho usato? Sto immaginando un comando qualcosa del tipo:

workon myproject

... che imposta il file di registro della shell su ~ / myproject / .history.log, carica la cronologia precedente da quel file di registro e forse aggiorna il mio prompt per dirmi su quale directory sto lavorando (come ad esempio vcprompt per fornire la versione informazioni di controllo).

C'è qualcosa là fuori come questo?

Risposte:


4

Nel caso in cui non l'avessi ancora capito: quello che stai cercando è l'eccellente pacchetto virtualenvwrapper . È un wrapper per virtualenv (vai alla figura) di Python e, sebbene sia comunemente indicato quando si utilizzano ambienti Python, in realtà è uno strumento molto generico che soddisfa il tuo caso d'uso.

Installazione

pip install virtualenvwrapper

o

easy_install virtualenvwrapper

e aggiungi elementi di inizializzazione nella shell config ( ~/.zshrc, ~/.bashrc)

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$WORKON_HOME/projects
export PIP_VIRTUALENV_BASE=$WORKON_HOME
export PIP_RESPECT_VIRTUALENV=true
source /usr/local/bin/virtualenvwrapper.sh

uso

# create your env
mkvirtualenv my_project

# edit per project hooks
vim ~/.virtualenvs/my_project/bin/{postactivate,preactivate,predeactivate,etc}

# work in this env
workon my_project

Hai anche hook generici ~/.virtualenvs/{postactivate,postdeactivate,etc}che vengono chiamati ogni volta workon any_project.

Quindi, ad esempio, avere la linea export HISTFILE="$VIRTUAL_ENV/bash_history"nel ~/virtualenvs/postactivategancio significa che la $HISTFILEvariabile verrà espansa ogni volta in un progetto diverso.


3

Ne ho bisogno anche io e ho realizzato una versione che utilizza la variabile PROMPT_COMMAND di Bash :

Il valore della variabile PROMPT_COMMAND viene esaminato appena prima che Bash stampi ogni prompt principale. Se PROMPT_COMMAND è impostato e ha un valore non nullo, il valore viene eseguito come se fosse stato digitato sulla riga di comando.

Quindi dico PROMPT_COMMAND = "check_for_local_history" in ~ / .bashrc.my, dove check_for_local_historyè una mia funzione che controlla se l'ultimo comando eseguito è stato un cambio di directory e, quando è vero, controlla la nuova directory corrente per il file .bash_history . Se è lì, usalo come file cronologico.

Ecco la sintesi completa: https://gist.github.com/gurdiga/dac8d2e7eb3056d6b839


2

Un trucco che uso per creare un sotto-pacchetto per un prodotto è usare una sotto-shell.

Per bash potresti creare uno script di shell come questo:

#!/bin/bash

export PROJECT_DIRECTORY=$(pwd)

exec bash --rcfile $HOME/.project-bashrc

Quindi $HOME/.project-bashrcinserisci qualcosa come questo:

source $HOME/.bashrc
export HISTFILE="${PROJECT_DIRECTORY}/.bash_history"
cd "${PROJECT_DIRECTORY}"

Ciò consente anche di personalizzare il prompt nel .project-bashrcfile, che può essere utile.

Non sono sicuro di come fare lo stesso in zsh. Dovresti scavalcare la ZDOTDIRvariabile, penso. Ma sarebbe simile.

Ciao!


1

Dai un'occhiata ai miei script di registrazione qui . Usandone uno, puoi tenere traccia della directory in cui ti trovi quando esegui ciascun comando. È possibile grepil file di registro per il comando o altre informazioni. Uso la versione lunga a casa e al lavoro.


Grazie - darò un'occhiata in questo. Potrebbe fare qualcosa di simile a quello di cui ho bisogno!
Simon,

1

Potresti essere interessato a un plugin che ho scritto chiamato directory-history per zsh.
Guarda qui: https://github.com/tymm/directory-history

Sebbene non si adatti davvero al tuo lavoro sul flusso di lavoro di myproject , dovrebbe adattarsi perfettamente alle tue esigenze.

Crea una storia che include directory.
Quando esegui una ricerca nella cronologia, otterrai prima i comandi dalla directory in cui ti trovi.
Se non ci sono più comandi per quella directory, tornerà a una cronologia globale e suggerirà i comandi utilizzati in altre directory.


1

Se vuoi qualcosa di semplice potresti avere il tuo .history.logfile come tale:

#!/bin/cat
some
relevant
commands

Quindi eseguendo il file sarebbero catquei comandi che hai elencato in esso.
Puoi anche raggruppare quei comandi in file separati per funzionalità come convenzione:

.howto.datadump
.howto.restart

Questo ha l'ulteriore vantaggio di lavorare fuori dagli schemi e di non inquinare l'ambiente.


In alternativa, puoi utilizzare README.mdo creare altri .mdfile per argomento e indicarli dal file Leggimi. Questo se hai un'interfaccia di controllo del codice sorgente amichevole.
Reno,

1

Per ottenere un file di cronologia locale per una directory ho aggiunto la seguente riga al mio comando prompt di bash.

if [ -f .local_history ] ; then tail -1 $HISTFILE >> .local_history ; fi

Il comando touch .local_historyin una directory mi dà quindi un file di cronologia locale per tutti i comandi eseguiti in quella directory, senza perdere il file di cronologia principale. Qualcosa di simile avrebbe funzionato in zsh, immagino.


0

Almeno in bash, HISTFILE viene consultato solo all'inizio dell'istanza della shell. L'idea per dir non funzionerà qui, a meno che l'esempio "workon" sopra non crei un'istanza di shell.

Forse puoi guardare qualcosa del genere

alias workon='script ./.history.log'

Ma lo script crea anche una subshell.

In breve, probabilmente avrai bisogno di livelli disordinati di subshells per farlo funzionare.


Accidenti, speravo fosse qualcosa di semplice. Grazie comunque!
Simon,

0

Ho lavorato in case di software di produzione in cui avremmo semplicemente creato nuovi utenti e gruppi per varie funzioni. Nuovi account utente specifici per la gestione della configurazione o build di software con diversi livelli di visibilità in altre aree funzionali correlate tramite l'appartenenza al gruppo e ACL, e la cronologia dei comandi eseguita da dire, cmmgrverrebbero salvati in ~cmmgr/.bash_history, le bldmgrparole correlate verrebbero salvate in ~bldmgr/.bash_history, ecc. Sfortunatamente, per accedere, un utente deve possedere la propria directory di accesso. Pertanto, un'area del progetto è stata completamente impostata su un disco separato. La proprietà del creatore del file ha mostrato quale area funzionale ha creato i file nell'area del progetto, per cui è .bash_historypossibile esaminare l'appropriato .

L'approccio di cui sopra, tuttavia, non ti dà la granularità che desideri, tuttavia, ti dà uno scheletro che quando combinato con l'appartenenza al gruppo, un utente potrebbe cambiare gruppo con il newgrpquale crea efficacemente una nuova shell e un nuovo ambiente, e quindi usa uno degli approcci forniti nelle altre risposte per modificare il ~/.bash_historyfile efficace quando si cambia cappelli per dire, in cmmgrmodo che a newgrppossa gestire quale ~/.bash_historyviene utilizzato e salvato per cartella quando si entra ed esce dal nuovo gruppo tramite il newgrpcomando. Partenza man newgrp. Ci sono alcuni punti di partenza lungo queste linee in altre risposte a questa domanda. Questi dovrebbero funzionare con il paradigma del gruppo UNIX: la maggior parte dei dadi e bulloni sono gestiti dall'avvio della shell e dalle routine di uscita come controllato dalnewgrpinvocazione. Dai un'occhiata newgrp -l:

NAME
     newgrp -- change to a new group

SYNOPSIS
     newgrp [-l] [group]

DESCRIPTION
     The newgrp utility creates a new shell execution environment with modified real and effective group
     IDs.

     The options are as follows:

     -l      Simulate a full login.  The environment and umask are set to what would be expected if the user
             actually logged in again.

0

Qui presento due varianti, ma applicabile solo alla Z Shell .

Variante 1

Questo è quello che ho pensato per la prima volta quando ho letto il titolo della domanda. Con questa variante puoi passare tra due modalità di cronologia con ALT+ h: Global o local , dove quest'ultima passa automaticamente a una cronologia per directory su chdir . La storia globale accumula tutti i comandi emessi.

  • Dimostrazione

    ~ source src / cd_history
    ~ echo storia globale                                                
    storia globale
    ~ mkdir foo bar                                                      
    ~ [ALT-h] 
    ~                          nota l'indicatore per la cronologia locale ->    +
    ~ cd foo +
    ~ / foo fa eco alla storia locale in foo +
    storia locale in foo
    ~ / foo fc -l +
        1 eco storia locale in foo
    ~ / foo cd ../bar +
    ~ / bar fa eco alla storia locale in bar +
    storia locale nel bar
    ~ / bar fc -l +
        1 eco storia locale nel bar
    ~ / bar cd ../foo +
    ~ / foo fc -l +
        1 eco storia locale in foo
        3 cd ../bar
    ~ / foo [ALT-h]                                           
    ~ / foo fc -l                                                          
       55 sorgente src / cd_history
       64 echo storia globale
       65 mkdir foo bar
       66 cd foo
       70 eco storia locale nel bar
       72 cd ../foo
       73 echo storia locale in foo
       74 cd ../bar
    ~ / Foo  
  • Lo script (da includere ~/.zshrco da reperire)

    # set options for shared history
    setopt prompt_subst
    setopt share_history
    setopt hist_ignorealldups
    
    # define right prompt as an indicator if local (i.e. per directory) history is enabled
    RPS1=' ${HISTLOC}'
    export HISTLOC=''
    
    # configure global history file and global/local history size
    export HISTGLOBAL=$HOME/.zsh_history
    touch $HISTGLOBAL
    export HISTSIZE=2000
    export SAVEHIST=2000
    
    # define wrapper function and key binding to switch between globel and per-dir history
    function my-local-history()
    {
      if [[ -z $HISTLOC ]]; then
        HISTLOC='+'
        chpwd
      else
        HISTLOC=''
        export HISTFILE=$HISTGLOBAL
        fc -A $HISTFILE
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
      fi
      zle reset-prompt
    }
    zle -N my-local-history
    bindkey "^[h"    my-local-history
    
    # install hook function which is called upon every directory change
    chpwd () {
      if [[ ! -z $HISTLOC ]]; then
        fc -A $HISTGLOBAL $HISTSIZE $SAVEHIST
        export HISTFILE=$PWD/.zsh_history
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
        touch $HISTFILE
      fi 
    }

Variante 2

Ripensandoci, sembra che la storia per dir sia troppo fine e tu descriva anche una storia per progetto nel tuo corpo di domanda. Quindi ho trovato un'altra variante con una funzione workon per passare da un progetto all'altro. Ogni progetto ha il suo file di cronologia ~/.zsh_projhistory_[name].

  • Dimostrazione

    ~ source src / proj_history 
    ~ echo storia globale                                                                    
    storia globale
    ~ [ALT-h]                                                               [usa workon]
    ~ workon foo [usa workon]
    ~ comando echo nel progetto foo [su proj foo]
    comando nel progetto foo
    ~ fc -l [su proj foo]
        1 comando echo nel progetto foo
    ~ workon bar [su proj foo]
    ~ echo un altro proj, chiamato bar [sulla barra del proj]
    un altro proj, chiamato bar
    ~ fc -l [sulla barra del proj]
        1 echo un altro proj, chiamato barra
    ~ workon foo [sulla barra del proj]
    ~ fc -l [su proj foo]
        1 comando echo nel progetto foo
        3 barre di lavoro
    ~ [ALT-h]                                                              [su proj foo]
    ~
    ~ fc -l                                                                                   
       31 eco storia globale
       36 echeggiano un altro proj, chiamato bar
       38 worko foo
       39 comando echo nel progetto foo
       40 workon bar
    ~ ls -1 .zsh_ *
    .zsh_history
    .zsh_projhistory_bar
    .zsh_projhistory_foo
  • Lo script (da includere ~/.zshrco da reperire)

    # set options for shared history
    setopt prompt_subst
    setopt share_history
    setopt hist_ignorealldups
    
    # define right prompt as an indicator if local (i.e. per directory) history is enabled
    RPS1=' ${HISTLOC}'
    export HISTLOC=''
    
    # configure global history file and global/local history size
    export HISTGLOBAL=$HOME/.zsh_history
    touch $HISTGLOBAL
    export HISTFILE=$HISTGLOBAL
    export HISTSIZE=2000
    export SAVEHIST=2000
    
    # define wrapper function and key binding to switch between globel and per-dir history
    function my-local-history()
    {
      if [[ -z $HISTLOC ]]; then
        if [[ -z $HISTLOC ]]; then
          HISTLOC='+'
          [[ -z "$HISTPROJ" ]] && HISTLOC='[use workon]' || workon "$HISTPROJ"
        fi
      else
        HISTLOC=''
        export HISTFILE=$HISTGLOBAL
        fc -A $HISTFILE
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
      fi
      zle reset-prompt
    }
    zle -N my-local-history
    bindkey "^[h"    my-local-history
    
    # function to change project
    workon () {
      if [[ -z "$1" ]]; then
        echo Usage: workon [project name]
        return 1
      fi
      export HISTPROJ="$1"
      if [[ ! -z $HISTLOC ]]; then
        fc -A $HISTGLOBAL $HISTSIZE $SAVEHIST
        export HISTFILE=$HOME/.zsh_projhistory_"$HISTPROJ"
        fc -p "$HISTFILE" $HISTSIZE $SAVEHIST
        touch "$HISTFILE"
        HISTLOC="[on proj $HISTPROJ]"
      fi 
    }

0

Dopo aver lavorato in un'area per un po '.

storia> hist1.txt, quindi storia successiva> hist2.txt

A volte uso la data per il nome file. storia> hist20180727.txt

In questo modo è presente una cronologia dei comandi recente per ciascuna directory.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.