Crontab için python koşullarını yazma

Aug 21 2020

Bir python if ifadesi crontab'da düzenlenirken nasıl çalışır? Python 3.6.3'ü kullanma

Linux crontab kullanarak bir uyarı programlayabilmek için bir dizindeki ("." Ve ".." dizinlerinden başka) gizli dosyaların miktarını almaya çalışıyorum. Aşağıdakiler, miktarı dize biçiminde alır:

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)

O zaman şöyle bir şey istiyorum

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

Herhangi bir yardım takdir edilmektedir.

Yanıtlar

1 tripleee Aug 21 2020 at 14:43

Çok daha iyi bir çözüm, bir alt işlemden tamamen kaçınmaktır. (Bir alt işlem kullansanız bile , komut dosyalarında kullanmayın ls.)

from pathlib import Path

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

Aslında uzunluğu kontrol etmeye gerçekten gerek yoktur; söyleyebilirsin

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

Biraz belirsiz ama daha kısa bir şekilde, bunun yerine oluşturucu üzerinde yineleme yapabilirsiniz; döngü gövdesi yalnızca eşleşen en az bir dosya varsa çalıştırılacaktır. Bu, en az bir dosya olup olmadığını önemsiyorsanız, birincisini bulduğunda durduğu için bir optimizasyondur;

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

Python, betiğinizi çalıştırıp çalıştırmamanızı önemsemez cron(ancak bazen cronstandart olmayan konumlarda yüklü kitaplıklarınız varsa işinizde Python için ortamı düzenlemeniz gerekir ). Peki, tüm iş mantığınız kabuk betiklerinde ise neden Python kullanıyorsunuz? (Kabuk betiklemeniz , kaçınmak için bazı antipatternleri incelemekten de fayda sağlayabilir .)

İşte tüm bunlar, benzer mantık kullanılarak, tamamen kabuk betiğinde:

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

Bash shopt -s nullglob, joker karakterde eşleşme yoksa döngüye girmekten kaçınmayı önerir; ama cronçalışır shve onu (hiçbir maçta durumunda globbing davranış olsa burada bashisms önlemek için tamamen zor değil edilir şaşırtıcı).

Tüm eşleşmeleri bir kabuk komut dosyasında istiyorsanız, diyebilirsiniz

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

Bash veya ksh kullanırsanız, eşleşmeleri bir dizi halinde toplayabilirsiniz;

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

Kişisel egrepregex sadece nokta üzerinde eşleşir dizinleri; Bunun bir hata olduğunu varsaydım.

Oneiros Aug 21 2020 at 14:03

yazdırma res.stdout, içinde bir son satır karakteri olduğunu gösterecektir.

>>>res.stdout
'0\n'

bu yüzden '\ n' karakterini çıkartın:

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

Alternatif olarak, onu bir tam sayı olarak çevirin:

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