web-dev-qa-db-fra.com

Comment puis-je arrêter la commande de queue dans le script

Ce que je veux faire - Commencez à capturer les modifications dans un fichier journal à l'aide d'un code de client ssh personnalisé ***. Après un certain temps (ce qui n’est pas une valeur fixe et est basé sur un événement), émettez une commande pour arrêter la mise en file C’est la commande que j’utilise pour capturer les dernières modifications apportées à un fichier journal - tail -f logfile.txt

Je veux pouvoir y mettre fin avec quelque chose comme :q que je peux sortir d'un script. Je ne veux pas utiliser des commandes telles que ctrl + c.

*** Pseudo-code pour mon code client ssh personnalisé (écrit dans un langage oop)

include ssh-api
ssh = getSSHConnection();
cmd = 'cd to folder';
ssh.command(cmd);
cmd = 'tail -f log.txt';
ssh.command(cmd);
wait for special event to occur...
cmd = 'stop the tail now!'
out = ssh.command(cmd);
print "the changes made to log file were\n"  + out;

Je n'ai aucun accès en écriture sur le serveur où se trouve le fichier journal.

Ce que j'ai essayé - http://www.linuxquestions.org/questions/red-hat-31/how-to-stop-tail-f-in-scipt-529419/

Je ne suis pas capable de comprendre la solution là-bas (c'est dans post 2). Quelqu'un peut-il s'il vous plaît expliquer la solution ou suggérer une autre façon de le faire?

Je vous remercie.

12
Borat Sagdiyev

Dans votre script, vous pouvez utiliser la variable $!.

# run tail -f in background
tail -f /var/log/sample.log > out 2>&1 &

# process id of tail command
tailpid=$!

# wait for sometime
sleep 10

# now kill the tail process
kill $tailpid

$! Développe l'ID de processus de la commande d'arrière-plan (asynchrone) exécutée le plus récemment.

20
anubhava

Certains moyens que j'utilise pour contourner tail -f, en utilisant bash .

En attente de l'arrivée spécifique:

Je l'utilise souvent:

sed -une '
    /DHCPOFFER/{
        s/^\(.*\) [^ ]\+ dhcpd: DHCPOFFER on \([0-9.]\+\) to \([0-9a-f:]\+\) .*$/\1 \3 -> \2/p;
        q;
    }' < <(
      tail -f /var/log/syslog
    )

Avec cette commande, je pouvais attendre le prochain client DHCP} et obtenir l'heure de l'événement, l'adresse MAC et l'adresse IP proposée.

Dans un script:

#!/bin/bash

read rMac rIp rDate < <(
  sed -une '
    /DHCPOFFER/{
      s/^\(.*\) [^ ]\+ dhcpd: DHCPOFFER on \([0-9.]\+\) to \([0-9a-f:]\+\) .*$/\3 \2 \1/p;
      q;
    }' < <(
      tail -n0 -f /var/log/syslog
))

printf "Date:\t%s\nMac:\t%s\nIP:\t%s\n" "$rDate" $rMac $rIp

Pour avoir arrêté un script à distance:

La façon fifo:

mkfifo /tmp/holder
tail -f /var/log/syslog &
TailPid=$!
cat >/dev/null /tmp/holder
kill -9 $TailPid

... puis d'ailleurs:

echo >/tmp/holder

terminera la commande de queue.

La méthode lockpid

#!/bin/bash

[ -e /tmp/lockfile ] && exit
echo $$ >/tmp/lockfile
[ $(</tmp/lockfile) -ne $$ ] && exit
cd /var/log
tail -f syslog &
export tPid=$!
trap "kill $tPid;rm /tmp/lockfile;exit 0" 12
wait $tPid

Ensuite, d’ailleurs:

kill -USR2 $(</tmp/lockfile)

Via SSH

La deuxième méthode fonctionne bien avec ssh:

ssh -T root@remoteMachine /bin/bash <<"eocmd"
    [ -e /tmp/lockfile ] && exit
    echo $$ >/tmp/lockfile
    [ $(</tmp/lockfile) -ne $$ ] && exit
    cd /var/log
    tail -f syslog &
    export tPid=$!
    trap "kill $tPid;rm /tmp/lockfile;exit 0" 12
    wait $tPid
eocmd

(se soucier de la double citation autour de balise de script en ligne)

Ensuite, d’ailleurs:

ssh root@remoteMachine '/bin/bash -c "kill -USR2 $(</tmp/lockfile)"'

(attention à la citation et à la citation double, dans cet ordre)

Nota sur les considérations de sécurité : Cela ne prend pas en compte les problèmes de sécurité! Avoir ce genre de lockfile _ situé dans /tmp pourrait être une mauvaise idée ...

4
F. Hauri

Vous pouvez exécuter tail en arrière-plan tout en redirigeant sa sortie vers un autre fichier (par exemple /tmp/mylog) et écrire le pid du processus quelque part dans un fichier pid (par exemple ~/mytail.pid):

tail -f logfile > /tmp/mylog & echo $! > ~/mytail.pid

Ensuite, lorsque vous voulez l'arrêter, exécutez simplement:

kill `cat ~/mytail.pid`

Ensuite, vous pouvez voir le contenu du journal que vous avez rassemblé entre-temps (c’est aussi une bonne idée de le supprimer plus tard):

cat /tmp/mylog
rm /tmp/mylog # just don't forget it there
3
lp_

Le message n ° 2 auquel vous faites référence a les effets suivants:a la bonne réponse.

Ça dit:

tail -f /etc/httpd/logs/access_log & # This starts tailing the file in background (see & at the end)
kill `ps | grep tail | awk '{print $1;}'` # This finds the process running above tail command and kills it

Vous voudrez peut-être introduire sleep 100 ou quelque chose selon votre besoin, sinon, les deux commandes ci-dessus entraîneront une mise au point juste une fraction de temps avant de le tuer.

1
Gaurav

Selon votre commentaire à @psmears, vous pouvez utiliser CTRL+C

@ psmears - sûrement. cela fonctionnerait aussi. Tout ce que je veux faire, c'est dire à unix de mettre un fichier sur un fichier, d'arrêter de le mettre à tout moment, et de me donner le résultat entre le début et la fin du fichier. Merci. - Borat Sagdiyev il y a 2 jours 

Vous pouvez donc simplement lancer votre commande dans le paramètre ssh.

 ssh username@remotehost tail -f /var/log/remotelog.txt | tee result.log

Et lorsque vous avez terminé, appuyez sur CTRL+C

Dans la commande précédente, j'ai utilisé la commande tee afin de voir les nouvelles lignes dans mon terminal et de les stocker dans le fichier.

Si vous voulez que ce soit scriptable

Vous pouvez faire ce qui suit:

 ## store result to file
 FILE=result.log

 ## launch tail remote log, and store result to result.log
 ssh -n username@remote-Host tail -f /path/to/remote.log > $FILE &

 ## store pid
 SSHPID=$!

 ## wait for ":q" command
 while [ "$cmd" != ":q" ]; do
    echo -ne "\n$ "
    read -n 2 cmd
 done

 ## kill ssh when you've enough
 kill $SSHPID

 ## read result
 echo "the changes made to log file were\n"
 cat $FILE

Notez que si vous voulez séparer les scripts de démarrage et d'arrêt, il vous suffit de stocker SSHPID dans un fichier dans le script.

 echo $SSHPID > ~/.sshpid

et le récupérer à partir du second

 SSHPID=`cat ~/.sshpid`
1
Adam

Mieux vaut tuer que de laisser la queue sortir correctement:

tail -n0 --pid=$(($BASHPID+1)) -F logfile | sed '/special event string in the log/q'

Lors du transfert, les PID sont séquentiels, le pid de la queue sera donc $ BASHPID et le pid du fichier sed sera $ BASHPID + 1. Le commutateur --pid provoquera la fermeture de tail (correctement!) Lorsque la commande sed se fermera. Évidemment, c'est un pashisme.

0
Christian Herr