Ecrire des conditions Python pour crontab

Aug 21 2020

Comment fonctionne une instruction python if lors de sa modification dans crontab? Utilisation de python 3.6.3

En utilisant linux crontab, j'essaye d'obtenir un compte de la quantité de fichiers cachés dans un répertoire (autre que les répertoires "." Et "..") afin de pouvoir planifier une alerte. Ce qui suit obtient le montant au format chaîne:

import subprocess
res = subprocess.run('ls -Ap | egrep "^\..*/$" | wc -l', shell=True, universal_newlines=True, stdout=subprocess.PIPE);
print(res.stdout)

output>>> (integer type string)

Alors je veux quelque chose comme

if res.stdout != "0":
   (executeAlert.sh script)
else:
   (ignore)

Toute aide est appréciée.

Réponses

1 tripleee Aug 21 2020 at 14:43

Une bien meilleure solution consiste à éviter complètement un sous-processus. (Et même si vous utilisez un sous-processus, ne l'utilisez pas lsdans les scripts.)

from pathlib import Path

dotfiles = Path().glob('.[!.]*')
if len(list(dotfiles)) > 0:
    do_things()

En fait, il n'y a pas vraiment besoin de vérifier la longueur; tu peux dire

dotfiles = list(Path().glob('.[!.]*'))
if dotfiles:
    do_things('The files which matched are %s' % dotfiles)

De manière un peu obscure, mais plus succincte, vous pouvez plutôt parcourir le générateur; le corps de la boucle ne sera exécuté que s'il y a au moins un fichier correspondant. Il s'agit d'une optimisation si vous vous souciez seulement de savoir s'il y a au moins un fichier, car il s'arrête une fois qu'il trouve le premier;

for file in Path().glob('.[!.]*'):
    do_things()
    break

Python ne se soucie pas de savoir si vous exécutez votre script à partir cronou non (bien que vous ayez parfois besoin d'organiser l'environnement pour Python dans votre crontravail si vous avez des bibliothèques installées dans des emplacements non standard). Mais pourquoi utilisez-vous Python ici si toute votre logique métier est dans des scripts shell? (Bien que votre script shell puisse également bénéficier de l'étude de certains anti-modèles à éviter.)

Voici le tout entièrement en script shell, en utilisant une logique similaire:

for file in .[!.]*; do
    test -e "$file" || break  # cf nullgbob
    executeAlert.sh
    break
done

Bash propose shopt -s nullglobd'éviter d'entrer dans la boucle si le joker n'a pas de correspondance; mais cronfonctionne shet il n'est pas tout à fait difficile d'éviter les bashismes ici (bien que le comportement de globbing en cas d'absence de correspondance soit surprenant).

Si vous voulez toutes les correspondances dans un script shell, vous pouvez dire

set -- .[!.]*
if [ "$@" != ".[!.]*" ]; then
    executeAlert.sh "$@"   # argument is list of matching files
fi

Si vous utilisez Bash ou ksh, vous pouvez collecter les correspondances dans un tableau;

shopt -s nullglob
dotfiles=(.[!.]*)
for file in "${dotfiles[@]}"; do
   echo "Here's one dotfile: $file" done if [[ "${#dotfiles[@]}" > 0 ]]; then
     executeAlert.sh "${dotfiles[@]}"
fi

Votre egrepregex ne correspondrait qu'aux répertoires dot ; J'ai supposé que c'était une erreur.

Oneiros Aug 21 2020 at 14:03

L'impression res.stdoutvous montrera qu'il contient un caractère de fin.

>>>res.stdout
'0\n'

alors supprimez simplement le caractère '\ n':

res = res.stdout.strip('\n')
if res == "0":
    (executeAlert.sh script)

Sinon, convertissez-le simplement en entier:

if int(res.stdout) == 0:
    (executeAlert.sh script)