Je veux sortir le contenu d'un fichier pendant qu'il change, par exemple si j'ai le fichier foobar
et que je fais:
magic_command foobar
Le terminal actuel devrait afficher le contenu du fichier et attendre jusqu'à ce que, je ne sais pas, j'appuie sur ^ C.
Alors si depuis un autre terminal je fais:
echo asdf >> foobar
Le premier terminal devrait afficher la ligne nouvellement ajoutée en plus du contenu du fichier d'origine (bien sûr, étant donné que je n'ai pas appuyé sur ^ C).
Vous pouvez utiliser tail command
avec -f
:
tail -f /var/log/syslog
C'est une bonne solution pour un spectacle en temps réel.
Si vous souhaitez afficher un fichier court, qui tient sur un écran de terminal, et ce qui change, c'est peut-être le fichier entier, vous pouvez utiliser watch
:
watch cat example.txt
Every 2.0s: cat example.txt Sun Aug 3 15:25:20 2014
Some text
another line
Il affiche le fichier entier toutes les 2 secondes par défaut, y compris un en-tête facultatif:
L'option -d
(--differences
) mettra en évidence les modifications par rapport à la version précédente de la sortie ou à la première version.
less
a un mode de suivi similaire à tail -f
- appuyez simplement sur F
lorsque vous l'ouvrez.
Lorsque j'ai besoin de détecter des modifications de fichiers et de faire autre chose que tail -f filename
le fait, j'ai utilisé inotifywait
dans un script pour détecter le changement et agir en conséquence. Un exemple d'utilisation est présenté ci-dessous. Voir man inotifywait
pour les autres noms d'événements et commutateurs. Vous devrez peut-être installer le inotify-tools
package, par exemple via Sudo apt-get install inotify-tools
.
Voici l'exemple de script, appelé exec-on-change
:
#!/bin/sh
# Detect when file named by param $1 changes.
# When it changes, do command specified by other params.
F=$1
shift
P="$*"
# Result of inotifywait is put in S so it doesn't echo
while S=$(inotifywait -eMODIFY $F 2>/dev/null)
do
# Remove printf if timestamps not wanted
printf "At %s: \n" "$(date)"
$P
done
Dans deux consoles, j'ai entré les commandes comme suit (où A> signifie entrée dans la console A et B> signifie entrée dans la console B.)
A> rm t; touch t
B> ./exec-on-change t wc t
A> date >>t
A> date -R >>t
A> date -Ru >>t
A> cat t; rm t
La sortie suivante de cat t
est apparu dans la console A:
Thu Aug 16 11:57:01 MDT 2012
Thu, 16 Aug 2012 11:57:04 -0600
Thu, 16 Aug 2012 17:57:07 +0000
La sortie suivante de exec-on-change
est apparu dans la console B:
At Thu Aug 16 11:57:01 MDT 2012:
1 6 29 t
At Thu Aug 16 11:57:04 MDT 2012:
2 12 61 t
At Thu Aug 16 11:57:07 MDT 2012:
3 18 93 t
Le exec-on-change
le script s'est terminé lorsque j'ai rm
'd t
.
J'ai trois solutions:
1)tail -f
est une bonne idée
2) nous avons aussi tailf
à utiliser
) le troisième est un script bash:
#!/bin/bash
GAP=10 #How long to wait
LOGFILE=$1 #File to log to
if [ "$#" -ne "1" ]; then
echo "USAGE: `basename $0` <file with absolute path>"
exit 1
fi
#Get current long of the file
len=`wc -l $LOGFILE | awk '{ print $1 }'`
echo "Current size is $len lines."
while :
do
if [ -N $LOGFILE ]; then
echo "`date`: New Entries in $LOGFILE: "
newlen=`wc -l $LOGFILE | awk ' { print $1 }'`
newlines=`expr $newlen - $len`
tail -$newlines $LOGFILE
len=$newlen
fi
sleep $GAP
done
exit 0