Viết điều kiện python cho crontab

Aug 21 2020

Câu lệnh python if hoạt động như thế nào khi chỉnh sửa nó trong crontab? Sử dụng python 3.6.3

Sử dụng linux crontab Tôi đang cố gắng đếm số lượng tệp ẩn trong một thư mục (ngoài các thư mục "." Và "..") để tôi có thể lên lịch cảnh báo. Sau đây là số tiền ở định dạng chuỗi:

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)

Sau đó, tôi muốn một cái gì đó như

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

Bất kỳ trợ giúp được đánh giá cao.

Trả lời

1 tripleee Aug 21 2020 at 14:43

Một giải pháp tốt hơn nhiều là tránh hoàn toàn một quy trình con. (Và ngay cả khi bạn sử dụng một quy trình con, không sử dụng lstrong các tập lệnh.)

from pathlib import Path

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

Trên thực tế, không cần thiết phải kiểm tra độ dài; bạn có thể nói

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

Hơi khó hiểu, nhưng ngắn gọn hơn, bạn có thể lặp lại trình tạo; phần thân của vòng lặp sẽ chỉ được thực thi nếu có ít nhất một tệp phù hợp. Đây là một cách tối ưu hóa nếu bạn chỉ quan tâm xem có ít nhất một tệp hay không, vì nó sẽ dừng lại khi tìm thấy tệp đầu tiên;

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

Python không quan tâm đến việc bạn có chạy tập lệnh của mình từ cronhay không (mặc dù đôi khi bạn cần sắp xếp môi trường cho Python trong croncông việc của mình nếu bạn đã cài đặt các thư viện ở những vị trí không chuẩn). Nhưng tại sao bạn lại sử dụng Python ở đây nếu tất cả logic nghiệp vụ của bạn nằm trong các tập lệnh shell? (Mặc dù tập lệnh shell của bạn cũng có thể có lợi khi nghiên cứu một số phản vật chất cần tránh.)

Đây là toàn bộ mọi thứ hoàn toàn trong tập lệnh shell, sử dụng logic tương tự:

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

Bash đề nghị shopt -s nullglobtránh nhập vòng lặp nếu ký tự đại diện không khớp; nhưng vẫn cronchạy shvà hoàn toàn không khó để tránh những cú đánh bóng ở đây (mặc dù hành vi nhấp nháy trong trường hợp không có trận đấu đáng ngạc nhiên).

Nếu bạn muốn tất cả các kết quả khớp trong một tập lệnh shell, bạn có thể nói

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

Nếu bạn sử dụng Bash hoặc ksh, bạn có thể thu thập các kết quả phù hợp thành một mảng;

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 của bạn sẽ chỉ khớp trên các thư mục dấu chấm ; Tôi đã cho rằng đây là một sai lầm.

Oneiros Aug 21 2020 at 14:03

việc in res.stdoutsẽ cho bạn thấy rằng nó có một ký tự cuối bên trong nó.

>>>res.stdout
'0\n'

vì vậy chỉ cần loại bỏ ký tự '\ n':

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

Ngoài ra, chỉ cần truyền nó dưới dạng số nguyên:

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