Ecrire des conditions Python pour crontab
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
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.
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)