Comando cronologico all'interno dello script bash


20

La storia è un comando incorporato nella shell che non sono riuscito a usare all'interno di uno script BASH. Quindi, c'è un modo per ottenere questo usando lo script BASH?
Ecco qui la mia sceneggiatura per te:

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Risposte:


32

Bash disabilita la cronologia nelle shell non interattive per impostazione predefinita, ma è possibile attivarla.

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

Ma se stai cercando di monitorare l'attività su quel server, la cronologia della shell è inutile (è banale eseguire comandi che non compaiono nella cronologia). Vedi Come posso registrare tutti i lanci di processo in Linux .

Se stai eseguendo il debug di uno script, la cronologia della shell non è il modo migliore per ottenere informazioni utili. Uno strumento molto migliore è la funzione di traccia del debug: posizionata set -xnella parte superiore dello script. La traccia viene scritta nell'errore standard.


Questo si rifiuta di lavorare in una sceneggiatura:histtest.sh: 5: set: Illegal option -o history
Ken Sharp

4
@KenSharp Questo perché hai provato a usarlo in uno script sh (e il tuo shè un trattino a giudicare dal testo esatto del messaggio di errore). Per accedere alla cronologia di bash, è necessario utilizzare bash (script che inizia con #!/bin/basho #!/usr/bin/env bash).
Gilles 'SO- smetti di essere malvagio' il

1
@KenSharp Sì, lo è. Ovviamente l'hai eseguito sotto il trattino, dato il messaggio di errore. Bash non ha il messaggio di errore Illegal option(direbbe set: history: invalid option name).
Gilles 'SO- smetti di essere malvagio' il

il problema è che aggiunge tutti i comandi che seguono set -o history alla cronologia che verranno riempiti con voci come if [... vars=$(...ecc.
nath

1
@nath Ecco la domanda. È praticamente inutile, come faccio notare. Il monitoraggio dell'attività è un problema difficile che la cronologia della shell non risolve. Se stai eseguendo il debug di uno script, set -xè molto più utile.
Gilles 'SO- smetti di essere malvagio' il

6

Non sono sicuro che utilizzi effettivamente la funzionalità di cronologia quando viene eseguito in modo non interattivo, altrimenti ogni script di shell che eseguiresti ingombra la cronologia dei comandi.

Perché non andare direttamente alla fonte ${HOME}/.bash_history, sostituirlo history | tail -100con tail -100 ${HOME}/.bash_history. (Se usi i timestamp probabilmente dovresti fare qualcosa sulla falsariga di grep -v ^# ${HOME}/.bash_history | tail -100).


In effetti, con i timestamp, dovresti effettivamente greq -v '^#[0-9]\+$'(a volte "
eseguo

E in realtà, nel mio caso, devo usare il numero di riga della cronologia corretto , ma c'è una differenza tra l'output di historye l'output del grepmetodo ...
PlasmaBinturong

Ok, la correzione è stato quello di sincronizzare l'elenco storia con il file di cronologia in questo modo: history -a; history -c; history -r. (aggiungi, cancella, leggi)
PlasmaBinturong

2

Se si desidera utilizzare l'output del historycomando da una sessione di shell attiva in uno script, è possibile utilizzare un alias per eseguire prima il comando. Quindi, nello stesso alias, puoi chiamare il resto dello script. Con tale configurazione, è possibile ottenere essenzialmente lo stesso risultato che avere il historycomando nello script reale.

Ad esempio, puoi creare un alias come questo, supponendo che il nome dello script sia script.sh:

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

E cambia lo script in questo:

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Ho trovato questa domanda durante la scrittura di un processo per combinare, ordinare e sincronizzare i ~/bash_historyfile su due computer, quindi sarà facile cercare i comandi che ho usato in passato.

È molto meno complicato aggiornare il mio file di cronologia cumulativo senza dover accedere a una nuova shell per l' ~/bash_historyaggiornamento. Ovviamente per il monitoraggio di un server non funzionerà, come indicato nelle altre risposte.

Il mio utilizzo in particolare è:

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

Lo script hby.shquindi estrae tutte le voci univoche da tutti i ~/.bash_history*file.



1

Crea uno script chiamato script.shcome di seguito. Crea uno script chiamato X e inserisce Y Numero di righe della cronologia.

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

Quindi, se si desidera creare uno script per eseguire un'attività denominata "attività" su cui si è lavorato per le ultime 14 righe eseguite

script.sh task 14

Quindi ripulisci la tua storia per creare una bella sceneggiatura!


histtest.sh: 5: set: Illegal option -o history
Ken Sharp

1

Il comando history è disabilitato di default sullo script bash ed è per questo che anche il comando history non funziona nel file .sh. per il suo reindirizzamento, reindirizza gentilmente il file bash_history all'interno del file .sh.

oppure è possibile abilitare il meccanismo cronologico anche menzionando il file cronologico e modificando i parametri di runtime come indicato di seguito

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

nota: sopra menzionato due righe nella parte superiore del file di script. ora il comando history funzionerà nella storia.


0

Ogni utente ha il proprio file di cronologia che è il risultato del comando di cronologia. Invece di usare il comando di cronologia nello script della shell è possibile utilizzare il file di cronologia per l'utente. Ci sarà un .bash_historyfile nella home directory dell'utente, che sarà il file della cronologia per l'utente.


-1

Risposta breve :

utilizzare history -pper eseguire l'espansione della cronologia in modo esplicito.

Segue un esempio.

Un caso d'uso accade molto per me è:

  • comando precedente ottiene un elenco di nomi di file e stampa su stdout,
  • Devo modificare quei file con vim.

Dal momento che il mio bash è stato set -o histexpand, di solito quello che ho fatto è digitare

vim $(!!)

per modificare i file elencati dal comando precedente.

Purtroppo a volte si verificano errori, quindi abilito la verifica entro shopt -s histverify.

Ora posso verificare l'espansione, con il costo di una Returnchiave aggiuntiva .

Oggi voglio avvolgere quei dettagli in una funzione bash poiché li uso molto,

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

Qui uso due nidificati command substitution, quello interno per espandere !!al comando precedente, quello esterno per eseguirlo e ottenere l'output.

Ora posso ottenere lo stesso effetto, con solo tre tasti, e uno di questi è Return!

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.