Come ottenere la cronologia condivisa bashed tra diverse schede


19

Ho usato la risposta in /unix//a/1292/41729 per abilitare la cronologia condivisa in tempo reale tra terminali bash separati. Come spiegato nella risposta sopra, ciò si ottiene aggiungendo:

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

# After each command, save and reload history
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Funziona bene se le shell bash sono separate (ad esempio aprendo diversi terminali bash usando CTRL+ALT+T. Tuttavia non funziona se uso tabs(da un terminale aperto `CTRL + MAIUSC + T) anziché nuove finestre. Perché questa differenza di comportamento? Come posso condividere la cronologia di bash anche tra varie schede?

AGGIORNAMENTO: ho notato un comportamento insolito: se digito, CTRL+Cl'ultimo comando digitato in uno qualsiasi degli altri terminali (sia una scheda che non) viene visualizzato correttamente. È come se CTRL + C forzasse un flush della cronologia in modo che fosse correttamente condiviso.

Ad esempio le uscite (T1 indica i terminali 1 e T2 2):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<up> (i.e. I press the up arrow)
ls -lah #i.e the last command in terminal 1 is shown rather than the last of terminal 2
^C (i.e. I press CTRL+C)
<up>
cd Documents #the last command issued in terminal 2 is correctly displayed

Spero che questo possa offrire qualsiasi suggerimento!


L'hai aggiunto al tuo ~.bashrcfile? In una nota a margine, esportare quelle variabili è inutile; spreca solo spazio nell'ambiente.
geirha,

@geirha sì, ho aggiunto al mio file .bashrc. Grazie per il commento sull'esportazione.
lucacerone,

Risposte:


2

Sembra che tu stia provando ad accedere alla cronologia dell'altro terminale prima che abbia luogo la sincronizzazione. PROMPT_COMMANDviene eseguito subito prima della stampa di un nuovo prompt, ovvero dopo aver eseguito un comando e prima di digitare il comando successivo. Quindi non accadrà subito in T1; devi far apparire un nuovo prompt.

Per provare questo, prova questa variante sui tuoi passaggi (ho aggiunto un extra <enter>in T1):

T1:
ls -lah <enter>
# the list of files and directory is shown

T2:
cd Documents <enter>

T1:
<enter>
<up> (i.e. I press the up arrow)

Con questa ulteriore pressione di invio, si ottiene un nuovo prompt, che esegue PROMPT_COMMANDe sincronizza la cronologia, e quindi mi aspetterei che questa freccia su recuperi il cdanziché il ls, come desiderato. Sfortunatamente, non penso che ci sia un modo per far sì che la sincronizzazione avvenga istantaneamente in tutti i terminali senza eseguire alcun comando come sembra che tu voglia; effettivamente ciò richiederebbe che tutte le sessioni di accesso sincronizzino continuamente i propri elenchi cronologici, il che comporterebbe un enorme spreco di CPU e throughput del disco.


hai ragione, premendo invio viene sincronizzato dopo. Anche se c'è uno spreco di memoria o CPU, come potrei forzare la sincronizzazione? (Se è troppo posso sempre disabilitarlo, ma vorrei provarlo)
lucacerone,

1

Ho fatto la stessa domanda ed ecco la risposta che mi è venuta in mente ....

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

history() {
  _bash_history_sync
  builtin history "$@"
}

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

PROMPT_COMMAND=_bash_history_sync


due chiarimenti prima di provare: dovrei rimuovere le altre storie - opzioni allora? questo va in .bashrc giusto?
lucacerone,

purtroppo non funziona ...
Lucacerone,

Ogni volta che HISTFILESIZEviene modificato, tenta automaticamente di troncare il file della cronologia esistente. Il cambiamento HISTSIZEha un effetto simile sulla storia attuale. Per riferimento, vedere il commento in variables.cbash src poco prima sv_histsize.
Brian Vandenberg,

1

aggiungi quelle righe al tuo .bashrcfile

# avoid duplicates..
export HISTCONTROL=ignoredups:erasedups  
# append history entries..
shopt -s histappend

trap 'history -r' USR1 
export PROMPT_COMMAND="history -a ; history -c; ps a | awk '/ bash$/ {system (\"kill -USR1 \" \$1)}'; $PROMPT_COMMAND"

Nota:

Inizialmente ho fatto il mio banco di prova inviando il segnale USR1 per colpire con killall, poi ho pensato di usare un nome shell univoco, una copia bash chiamata testshell, per evitare di uccidere le mie shell che potevano funzionare (processi cron per esempio) ma stranamente che non lo era Lavorando.

Il killall non era abbastanza selettivo, l'ho sostituito con uno script che uccide solo i processi bash fino a un tty ( ps ariporta solo processi legati a un tty)

Non dimenticare di riavviare la sessione per avere un nuovo PROMPT_COMMAND, mentre stavo testando ho visto molti dei miei test precedenti impilati all'interno di PROMPT_COMMAND.


Non hai bisogno del nuovo utente e dell'altra shell, puoi solo dire killalldi inviare il segnale solo ai processi dello stesso utente con un -uargomento aggiuntivo , e.g. -u $ (whoami) `.
Philipp Wendler,

Penso che la sintassi di csh sia sbagliata ... @PhilippWendler potresti per favore elaborare un po '?
lucacerone,

La domanda riguarda bash, quindi ho usato la sintassi bash. Non so csh. Per bash, killall -q -USR1 -u $(whoami) bashinvia il segnale USR1 a tutti i processi bash dell'utente corrente.
Philipp Wendler,

@Philipp ty btw Non ho testato la soluzione shell dedicata, era per risolvere un caso in cui sarebbe stato eseguito cron bash script.
Emmanuel,

@LucaCerone che ho riscritto sembra funzionare
Emmanuel,

0

Ho avuto lo stesso strano comportamento in Yakuake quando ho provato a creare elaborati prompt bash che mostrassero il numero di altri accessi. Il numero non è aumentato per le schede. La mia soluzione era di dire a Yakuake di correre di bashnuovo in ogni nuova scheda, essenzialmente iniziando bash in bash. Ha iniziato a funzionare perfettamente. Potrebbe essere anche per te. La mia ipotesi cieca è che la GUI per la console carica da sola le configurazioni bash e le invia alle istanze bash. Può essere essere in grado di giocherellare con loro.


Ho provato a caricare bash in bash, ma senza successo :(
lucacerone,
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.