Написание условных выражений Python для crontab

Aug 21 2020

Как работает оператор Python if при его редактировании в crontab? Использование python 3.6.3

Используя linux crontab, я пытаюсь подсчитать количество скрытых файлов в каталоге (кроме каталогов «.» И «..»), чтобы я мог запланировать предупреждение. Следующее получает сумму в строковом формате:

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)

Тогда я хочу что-то вроде

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

Любая помощь приветствуется.

Ответы

1 tripleee Aug 21 2020 at 14:43

Гораздо лучшее решение - полностью избегать подпроцесса. (И даже если вы используете подпроцесс, не используйте его lsв сценариях.)

from pathlib import Path

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

Собственно, проверять длину нет необходимости; ты можешь сказать

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

Несколько неясно, но более лаконично, вместо этого вы можете перебирать генератор; тело цикла будет выполнено, только если есть хотя бы один соответствующий файл. Это оптимизация, если вас интересует только наличие хотя бы одного файла, поскольку она останавливается, как только находит первый;

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

Python не заботится о том, запускаете ли вы свой скрипт cronили нет (хотя иногда вам нужно организовать среду для Python в своей cronработе, если у вас есть библиотеки, установленные в нестандартных местах). Но зачем вы здесь вообще используете Python, если вся ваша бизнес-логика находится в сценариях оболочки? (Хотя ваш сценарий оболочки также может выиграть от изучения некоторых антипаттернов, которых следует избегать.)

Вот все полностью в сценарии оболочки, используя аналогичную логику:

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

Bash предлагает shopt -s nullglobизбежать входа в цикл, если подстановочный знак не соответствует; но cronработает shи это не совсем трудно избежать bashisms здесь (хотя подстановка поведение в случае отсутствия спичек это удивительно).

Если вам нужны все совпадения в сценарии оболочки, вы можете сказать

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

Если вы используете Bash или ksh, вы можете собирать совпадения в массив;

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

Ваше egrepрегулярное выражение будет соответствовать только каталогам точек ; Я предположил, что это была ошибка.

Oneiros Aug 21 2020 at 14:03

печать res.stdoutпокажет вам, что в нем есть символ завершения.

>>>res.stdout
'0\n'

так что просто удалите символ '\ n':

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

Или просто введите его как целое число:

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