web-dev-qa-db-fra.com

Continuez à courir la commande jusqu'à ce que la sortie diffère de la course précédente à bash

J'ai un script que je veux exécuter toutes les x secondes jusqu'à ce que la sortie change. Avec un simple ou jusqu'à la boucle, je sais comment vérifier la sortie pour une chaîne particulière à l'aide de Grep, mais ce que je veux faire est de continuer à itération de la boucle jusqu'à ce que la sortie de l'itération actuelle ne soit pas égale à la sortie de l'itération précédente.

Comment puis-je y parvenir à Bash?

Le plus proche que j'ai obtenu est ci-dessous, où la commande est exécutée deux fois dans chaque itération, mais cela produit des points supplémentaires car la boucle tandis que la boucle ne peut pas se souvenir de la sortie de l'itération précédente.

while [ "$(command)" = "$(command)" ]; do sleep 10m; done
25
Mr. T

De man 1 watch :

-g, --chgexit
[.____] Sortez lorsque la sortie de change.

watch n'est pas requis par POSIX mais c'est assez courant de toute façon. Dans Debian ou Ubuntu, il est dans le package procps avec kill et ps (et peu d'autres outils).

Exemple:

watch -g -n 5 'date +%H:%M'
55
Kamil Maciorowski

Cela devrait faire le tour - explications en ligne:

#!/usr/bin/env bash

# Exit if any errors occur or any undefined variables are dereferenced
set -o errexit -o nounset

# Store the outputs in a separate directory
output_directory="$(mktemp --directory)"
last_output_file="${output_directory}/last"
current_output_file="${output_directory}/current"
touch "$current_output_file"
ln --symbolic "$current_output_file" "$last_output_file"
# The count is just here to show that we always run at least twice, and that
# after that we run the command a random number of times.
count=0

while true
do
    echo "$((++count))"

    # This is our command; it prints 0 or 1 randomly
    if [[ "$RANDOM" -gt 16383 ]]
    then
        echo 0 > "$current_output_file"
    else
        echo 1 > "$current_output_file"
    fi

    # Abort the loop when the files differ
    if ! diff --brief "$last_output_file" "$current_output_file"
    then
        break
    fi

    # Shunt the current output to the last
    mv "$current_output_file" "$last_output_file"
done

Il existe probablement des façons simples de le faire, mais il a quelques fonctionnalités utiles:

  • Il évite de créer des fichiers étrangers, tels que l'utilisation mktemp pour chaque sortie.
  • En commençant par le dernier fichier de sortie étant un lien symbolique vers le fichier de sortie actuel, nous garantissons que la première commande diff voit deux fichiers identiques. Cela évite de faire dupliquer la commande que nous testons, à la charge d'une exécution supplémentaire diff.
8
l0b0