Написание условных выражений Python для crontab
Как работает оператор 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)
Любая помощь приветствуется.
Ответы
Гораздо лучшее решение - полностью избегать подпроцесса. (И даже если вы используете подпроцесс, не используйте его 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регулярное выражение будет соответствовать только каталогам точек ; Я предположил, что это была ошибка.
печать 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)