Salida del contenido del archivo mientras cambian

47

Quiero generar el contenido de un archivo mientras cambian, por ejemplo, si tengo el archivo foobary lo hago:

magic_command foobar

El terminal actual debe mostrar el contenido del archivo y esperar hasta que, no sé, presione ^ C.

Entonces si desde otra terminal hago:

echo asdf >> foobar

El primer terminal debería mostrar la línea recién agregada además del contenido del archivo original (por supuesto, dado que no presioné ^ C).

Marcaré esto como tarea ya que quiero explorar y aprender Linux, pero no es tarea, es solo una curiosidad mía.

Pablo
fuente
stackoverflow.com/questions/6143838/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

79

Puedes usar tail commandcon -f :

tail -f /var/log/syslog 

Es una buena solución para espectáculos en tiempo real.

Golfo pérsico
fuente
puede escribir un script y redirigir su salida a su script.
PersianGulf
66
También puede usar -F(mayúscula f), que volverá a abrir el archivo si se elimina y se vuelve a crear en el camino.
Peter
19

Si desea mostrar un archivo corto, que cabe en una pantalla de terminal, y lo que está cambiando es posiblemente todo el archivo, puede usar watch:

watch cat example.txt

Every 2.0s: cat example.txt                                Sun Aug  3 15:25:20 2014

Some text
another line

Muestra todo el archivo cada 2 segundos de forma predeterminada, incluido un encabezado opcional:

La opción -d( --differences) resaltará los cambios de la versión anterior de la salida, o de la primera versión.

Volker Siegel
fuente
9

Cuando necesito detectar cambios en el archivo y hacer algo diferente a lo tail -f filenameque hago, lo he usado inotifywaiten un script para detectar el cambio y actuar en consecuencia. Un ejemplo de uso se muestra a continuación. Consulte man inotifywaitpara otros nombres de eventos e interruptores. Es posible que deba instalar el inotify-toolspaquete, por ejemplo a través de sudo apt-get install inotify-tools.

Aquí está el script de ejemplo, llamado 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

En dos consolas ingresé los comandos de la siguiente manera (donde A> significa entrada en la consola A y B> significa entrada en la consola 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

El siguiente resultado de cat tapareció en la consola 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 siguiente salida de exec-on-changeapareció en la consola 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

El exec-on-changeguión terminado cuando me rm'd t.

James Waldby - jwpat7
fuente
8

lesstiene un modo de seguimiento similar a tail -f: simplemente presiona Fcuando lo tengas abierto.

Peterph
fuente
4

Tengo tres soluciones:

1) tail -f es una buena idea

2) también tenemos tailfque usar

3) el tercero es 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
MLSC
fuente