Scrittura di condizionali Python per crontab

Aug 21 2020

Come funziona un'istruzione if di Python quando la si modifica in crontab? Usare python 3.6.3

Utilizzando linux crontab sto cercando di ottenere un conteggio della quantità di file nascosti all'interno di una directory (diversi dalle directory "." E "..") in modo da poter programmare un avviso. Quanto segue ottiene l'importo in formato stringa:

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)

Allora voglio qualcosa di simile

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

Qualsiasi aiuto è apprezzato.

Risposte

1 tripleee Aug 21 2020 at 14:43

Una soluzione molto migliore è evitare completamente un sottoprocesso. (E anche se usi un sottoprocesso, non usarlo lsnegli script.)

from pathlib import Path

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

In realtà, non c'è una reale necessità di controllare la lunghezza; si può dire

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

Un po 'oscuramente, ma più succintamente, potresti invece iterare sul generatore; il corpo del ciclo verrà eseguito solo se c'è almeno un file che corrisponde. Questa è un'ottimizzazione se ti interessa solo se c'è almeno un file, poiché si ferma una volta trovato il primo;

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

A Python non importa se esegui crono meno lo script (anche se a volte devi organizzare l'ambiente per Python nel tuo cronlavoro se hai librerie installate in posizioni non standard). Ma perché stai usando Python qui se tutta la tua logica aziendale è negli script della shell? (Anche se il tuo script di shell potrebbe anche trarre vantaggio dallo studio di alcuni antipattern da evitare.)

Ecco il tutto interamente in script di shell, utilizzando una logica simile:

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

Bash offre shopt -s nullglobdi evitare di entrare nel ciclo se il carattere jolly non ha corrispondenza; ma croncorre she non è del tutto difficile evitare i bashismi qui (anche se il comportamento globbing in caso di nessuna corrispondenza è sorprendente).

Se vuoi tutte le corrispondenze in uno script di shell, puoi dire

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

Se usi Bash o ksh, potresti raccogliere le corrispondenze in un array;

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

La tua egrepregex corrisponderebbe solo alle directory di punti ; Ho pensato che fosse un errore.

Oneiros Aug 21 2020 at 14:03

la stampa res.stdoutti mostrerà che contiene un carattere di fine riga.

>>>res.stdout
'0\n'

quindi rimuovi il carattere "\ n":

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

In alternativa, lancialo come numero intero:

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