Menulis python conditionals untuk crontab

Aug 21 2020

Bagaimana cara kerja pernyataan if python saat mengeditnya di crontab? Menggunakan python 3.6.3

Menggunakan crontab linux Saya mencoba menghitung jumlah file tersembunyi di dalam direktori (selain direktori "." Dan "..") sehingga saya bisa menjadwalkan peringatan. Berikut ini adalah jumlah dalam format string:

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)

Lalu saya ingin sesuatu seperti

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

Setiap bantuan dihargai.

Jawaban

1 tripleee Aug 21 2020 at 14:43

Solusi yang jauh lebih baik adalah menghindari subproses seluruhnya. (Dan bahkan jika Anda menggunakan subproses, jangan gunakan lsdalam skrip.)

from pathlib import Path

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

Sebenarnya, tidak perlu memeriksa panjangnya; bisa dibilang

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

Agak kabur, tetapi lebih ringkas, Anda dapat melakukan iterasi melalui generator sebagai gantinya; badan loop akan dijalankan hanya jika ada setidaknya satu file yang cocok. Ini adalah pengoptimalan jika Anda hanya peduli apakah ada setidaknya satu file, karena akan berhenti setelah menemukan yang pertama;

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

Python tidak peduli apakah Anda menjalankan skrip Anda dari cronatau tidak (meskipun terkadang Anda perlu mengatur lingkungan untuk Python dalam cronpekerjaan Anda jika Anda memasang pustaka di lokasi yang tidak standar). Tetapi mengapa Anda sama sekali menggunakan Python di sini jika semua logika bisnis Anda ada dalam skrip shell? (Meskipun skrip shell Anda juga bisa mendapatkan keuntungan dari mempelajari beberapa antipattern yang harus dihindari.)

Inilah semuanya sepenuhnya dalam skrip shell, menggunakan logika yang serupa:

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

Bash menawarkan shopt -s nullglobuntuk menghindari memasuki loop jika wildcard tidak cocok; tetapi cronberjalan shdan tidak terlalu sulit untuk menghindari bashisme di sini (meskipun perilaku global dalam kasus tidak ada kecocokan cukup mengejutkan).

Jika Anda ingin semua kecocokan dalam skrip shell, Anda dapat mengatakan

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

Jika Anda menggunakan Bash atau ksh, Anda bisa mengumpulkan kecocokan ke dalam 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

egrepRegex Anda hanya akan cocok di direktori titik ; Saya berasumsi bahwa ini adalah kesalahan.

Oneiros Aug 21 2020 at 14:03

pencetakan res.stdoutakan menunjukkan kepada Anda bahwa ia memiliki karakter garis akhir di dalamnya.

>>>res.stdout
'0\n'

jadi hapus saja karakter '\ n':

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

Atau, cukup gunakan sebagai integer:

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