J'essaie de créer un script bash qui enregistrera l'historique du terminal dans un fichier appelé hist.txt. L'utilisation history > hist.txt
ne semble pas fonctionner dans le script bash, mais fonctionne très bien lorsqu'elle est exécutée dans la ligne de commande.
Tout conseil est grandement apprécié.
Merci Judy
~/.bash_history
fichier de l'utilisateur .Réponses:
Réponse courte
Exécutez le script avec
source
ou.
:ou
Ce dernier est légèrement plus compatible entre différents coques.
Longue réponse
Cette question met en évidence un point important, à savoir que les scripts shell sont exécutés dans leur propre contexte. Pour voir ce que cela signifie, considérez le script shell suivant:
Si vous exécutez ceci, vous obtiendrez une sortie quelque chose comme ceci:
Mais vous remarquerez qu'après avoir exécuté le script, vous êtes toujours dans le répertoire dans lequel vous vous trouviez avant de l'exécuter: l'
cd /
intérieur du script n'a pas réellement affecté votre session - il n'a affecté que le contexte dans lequel le script s'exécutait, ce qui est créé pour que le script s'exécute et détruit une fois qu'il est revenu.La
source
commande «lira et exécutera les commandes à partir de l'argument du nom de fichier dans le contexte shell actuel», donc toutes les commandes comme à l'cd
intérieur affecteront votre session en cours. Si vous deviez exécuter le script ci-dessus en le passant,source
vous découvririez que vous vous retrouviez dans le répertoire racine après son exécution.Dans ce cas, le problème est que la
history
commande vous donne l'historique du contexte shell actuel; le contexte shell dans lequel votre script s'exécute sans utilisersource
n'a pas d'historique, il n'écrit donc rien dans le fichier de sortie. Si vous l'utilisez,source
il s'exécutera dans le bon contexte et fonctionnera comme prévu.NB:
source
est un shell intégré, pas un programme en soi - dans Bash,source
est synonyme de.
, mais dans certains shells ne.
fonctionnera que - j'ai utilisésource
dans cette réponse parce qu'il est plus facile à lire que.
, mais pour une compatibilité maximale,.
devrait être utilisé.la source
Tout d'abord, notez que votre historique est déjà dans un fichier. Si vous utilisez bash, son nom est généralement
~/.bash_history
. Plus précisément, c'est ce que vous avez défini pour la variableHISTFILE
. Si vous souhaitez le copier dans un autre fichier, lancez simplementcat "$HISTFILE" > hist.txt
Maintenant, pour savoir pourquoi la
history
commande ne fonctionne pas dans un script shell bash, c'est parce que les scripts sont exécutés dans un shell enfant non interactif de votre session shell actuelle. Les shells enfants n'héritent pas de tout l'environnement du parent (donc pas toutes les variables définies), seulement les variables qui ont été exportées. Pour illustrer, le script ci-dessous fera écho à la valeur de la variable$var
:Maintenant, définissez
$var
quelque chose et exécutez le script:Ensuite, exportez d'abord la variable:
Comme vous pouvez le voir, lorsque la variable a été exportée, elle est disponible pour les shells enfants.
Comme je l'ai mentionné précédemment, l'historique est stocké dans le fichier pointé par la variable
$HISTFILENAME
. Parce que ce n'est pas exporté par défaut, il n'est pas défini lors de l'exécution d'un script:Comme vous pouvez le voir dans l'exemple ci-dessus, la variable
HISTFILE
est définie dans ma session shell normale, mais est vide lors de l'exécution du script.Donc, pour obtenir l'historique, vous avez quelques options:
La
HISTFILE
valeur par défaut est$HOME/.bash_history
. Si vous n'avez pas changé cela, vous pouvez simplement exécuter cette commande dans votre script:Vous pouvez passer la
$HISTFILE
variable à votre script etcat
cela:Enregistrez ce qui précède sous
foo.sh
et exécutez comme ceci:Assurez-vous que la variable est exportée. Ajoutez cette ligne à vos fichiers
~/.bash_profile
(si elle existe) ou~/.profile
(si elle~/.bash_profile
n'existe pas):Ensuite, déconnectez-vous et reconnectez-vous et vous devriez pouvoir exécuter à
history > hist.txt
partir d'un script comme prévu. C'est parce queexport VAR
signifie "rendre $ VAR disponible pour les shells enfants". Concrètement, cela signifie que la valeur deHISTFILE
sera héritée par le shell non interactif que vous utilisez pour exécuter votre script.Maintenant, alors que le
HISTFILE
sera défini, il n'a pas été lu par le shell exécutant le script. Donc, pour le faire fonctionner, vous devez d'abord le lirehistory -r
. Le script entier ressemblerait à ceci:Vous pouvez également l'exporter manuellement avant d'exécuter le script:
Mais vous en aurez toujours besoin
history -r
dans le script.Vous pouvez le
source
faire comme suggéré par la réponse de @ p0llard .la source