crontabのPython条件を書く

Aug 21 2020

crontabで編集するときにpythonifステートメントはどのように機能しますか?Python3.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)

ややあいまいですが、もっと簡潔に言えば、代わりにジェネレーターを反復処理することができます。ループ本体は、一致するファイルが少なくとも1つある場合にのみ実行されます。これは、最初のファイルが見つかると停止するため、少なくとも1つのファイルがあるかどうかだけを気にする場合の最適化です。

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

Pythonは、スクリプトを実行するかどうかを気にしませcronん(ただし、cronライブラリが非標準の場所にインストールされている場合は、ジョブでPythonの環境を調整する必要がある場合があります)。しかし、すべてのビジネスロジックがシェルスクリプトであるのに、なぜここでPythonを使用しているのでしょうか。(シェルスクリプトは、回避するためにいくつかのアンチパターンを研究することからも恩恵を受ける可能性があります。)

同様のロジックを使用して、すべてをシェルスクリプトで完全に説明します。

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

Bashはshopt -s nullglob、ワイルドカードに一致するものがない場合にループに入らないようにすることを提案します。しかし、cron実行されsh、ここでバシズムを回避することはまったく難しいことではありません(ただし、一致しない場合のグロブ動作驚くべきことです)。

シェルスクリプトですべての一致が必要な場合は、次のように言うことができます

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)