Commande d'historique dans le script bash

20

L'historique est une commande intégrée au shell que je ne pouvais pas utiliser dans un script BASH. Alors, existe-t-il un moyen d'y parvenir en utilisant le script BASH?
Ici, nous allons mon script pour vous:

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

Réponses:

32

Bash désactive l'historique dans les shells non interactifs par défaut, mais vous pouvez l'activer.

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

Mais si vous essayez de surveiller l'activité sur ce serveur, l'historique du shell est inutile (il est trivial d'exécuter des commandes qui n'apparaissent pas dans l'historique). Voir Comment puis-je enregistrer tous les lancements de processus sous Linux .

Si vous déboguez un script, l'historique du shell n'est pas le meilleur moyen d'obtenir des informations utiles. Un bien meilleur outil est la fonction de trace de débogage: placée set -xprès du haut du script. La trace est écrite sur l'erreur standard.

Gilles 'SO- arrête d'être méchant'
la source
Cela refuse de travailler dans un script:histtest.sh: 5: set: Illegal option -o history
Ken Sharp
4
@KenSharp C'est parce que vous avez essayé de l'utiliser dans un script sh (et votre shtiret est à en juger par la formulation exacte du message d'erreur). Pour accéder à l'historique de bash, vous devez utiliser bash (script commençant par #!/bin/bashou #!/usr/bin/env bash).
Gilles 'SO- arrête d'être méchant'
1
@KenSharp Oui, c'est ça. Vous l'avez évidemment exécuté sous dash, étant donné le message d'erreur. Bash n'a pas le message d'erreur Illegal option(il dirait set: history: invalid option name).
Gilles 'SO- arrête d'être méchant'
le problème avec cela est qu'il ajoute toutes les commandes suivantes set -o history à l'historique qui va ensuite être bourré d'entrées comme if [... vars=$(...etc.
nath
1
@nath C'est ce que la question demandait. C'est à peu près inutile, comme je le souligne. La surveillance de l'activité est un problème difficile que l'historique du shell ne résoudra pas. Si vous déboguez un script, set -xc'est beaucoup plus utile.
Gilles 'SO- arrête d'être méchant'
6

Je ne sais pas s'il utilise réellement la capacité d'historique lors de l'exécution de manière non interactive, sinon chaque script shell que vous exécutez encombrerait votre historique de commandes.

Pourquoi ne pas aller directement à la source ${HOME}/.bash_history, remplacer history | tail -100par tail -100 ${HOME}/.bash_history. (Si vous utilisez des horodatages, vous devrez probablement faire quelque chose dans le sens de grep -v ^# ${HOME}/.bash_history | tail -100).

Kjetil Jorgensen
la source
En effet, avec les horodatages, vous devriez en fait greq -v '^#[0-9]\+$'(
j'exécute
Et en fait, dans mon cas, j'ai besoin d'utiliser le bon numéro de ligne d'historique , mais il y a une différence entre la sortie de historyet la sortie de la grepméthode ...
PlasmaBinturong
Ok, le correctif est de synchroniser la liste de l' histoire avec le fichier historique comme celui - ci: history -a; history -c; history -r. (ajouter, effacer, lire)
PlasmaBinturong
2

Si vous souhaitez utiliser la sortie de la historycommande à partir d'une session shell active dans un script, vous pouvez utiliser un alias pour exécuter la commande en premier. Ensuite, dans le même alias, vous pouvez appeler le reste du script. Avec une telle configuration, vous pouvez obtenir essentiellement le même résultat que d'avoir la historycommande dans le script réel.

Par exemple, vous pouvez créer un alias comme celui-ci, en supposant que le nom du script est script.sh:

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

Et changez le script en ceci:

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

J'ai trouvé cette question lors de l'écriture d'un processus pour combiner, trier et synchroniser des ~/bash_historyfichiers sur deux ordinateurs, il sera donc facile de rechercher les commandes que j'ai utilisées dans le passé.

Il est beaucoup moins compliqué de mettre à jour mon fichier d'historique cumulatif sans avoir à se connecter à un nouveau shell pour l'avoir ~/bash_historymis à jour. Pour surveiller un serveur, cela ne fonctionnera évidemment pas, comme mentionné dans les autres réponses.

Mon utilisation en particulier est:

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

Le script hby.shextrait ensuite toutes les entrées uniques de tous les ~/.bash_history*fichiers.

clk
la source
1

Créez un script nommé script.shcomme ci-dessous. Il crée un script nommé X et y met Y Nombre de lignes de votre historique.

#!/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;
~

Ensuite, si vous souhaitez créer un script pour accomplir une tâche nommée "tâche" sur laquelle vous avez travaillé pendant les 14 dernières lignes exécutées

script.sh task 14

Ensuite, nettoyez votre historique pour faire un joli script!

Eric
la source
histtest.sh: 5: set: Illegal option -o history
Ken Sharp
1

La commande history est désactivée par défaut sur le script bash, c'est pourquoi même la commande history ne fonctionnera pas dans le fichier .sh. pour sa redirection, veuillez rediriger le fichier bash_history à l'intérieur du fichier .sh.

ou le mécanisme d'historique peut également être activé en mentionnant le fichier d'historique et en modifiant les paramètres d'exécution comme indiqué ci-dessous

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

note: mentionné ci-dessus deux lignes en haut du fichier script. maintenant la commande history fonctionnera dans l'histoire.

linux.cnf
la source
0

Chaque utilisateur possède son propre fichier d'historique qui est le résultat de la commande d'historique.Au lieu d'utiliser la commande d'historique dans votre script shell, vous pouvez utiliser le fichier d'historique pour l'utilisateur. Il y aura un .bash_historyfichier dans le répertoire personnel de l'utilisateur, qui sera le fichier historique de l'utilisateur.

amit singh
la source
-1

Réponse courte :

à utiliser history -ppour effectuer explicitement l'expansion de l'historique.

Un exemple suit.

Un cas d'utilisation qui se produit souvent pour moi est:

  • commande précédente obtenir une liste de noms de fichiers et imprimer sur stdout,
  • J'ai besoin de modifier ces fichiers avec vim.

Depuis que mon bash a été set -o histexpand, généralement ce que je faisais est de taper

vim $(!!)

pour modifier les fichiers répertoriés par la commande précédente.

Malheureusement, il arrive parfois qu'une erreur se produise, donc j'active la vérification par shopt -s histverify.

Maintenant, je peux vérifier l'extension, avec le coût d'une Returnclé supplémentaire .

Aujourd'hui, je veux envelopper ces détails dans une fonction bash car je les utilise beaucoup,

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

Ici, j'utilise deux imbriqués command substitution, celui interne pour développer la !!commande précédente, celui externe pour l'exécuter et obtenir la sortie.

Maintenant, je peux obtenir le même effet, avec seulement trois touches, et l'une d'elles est Return!

qeatzy
la source