cron:bash構文が機能しない

cron:bash構文が機能しない

crontabに次のコマンドを追加しようとしています。

I=1; for X in $(/bin/ls -r /var/tmp/*); do [ $((I++)) -le 28 ] && echo "lower" || echo "higher"; done

このコマンドは、コマンドライン(bash)で実行すると正しく機能します。しかし、crontabにその行を追加して実行すると、cronは次のように文句を言います。

/bin/sh: 1: arithmetic expression: expecting primary: "I++"

cronで別の構文を使用する必要がありますか?

編集1:私はそれをsh次に置き換えましたbash/etc/crontab

SHELL=/bin/bash

再起動しましたが、cron次のcron行はまだ実行されません。

(I=1; for X in $(/bin/ls -r /var/tmp/*); do [ $((I++)) -le 28 ] && echo "lower" || echo "higher"; done)

/bin/shエラーは、次の代わりにまだ解釈されていることを示しています/bin/bash

/bin/sh: 1: arithmetic expression: expecting primary: "I++"

答え1

私の記憶が正しい場合、Cronのデフォルトは/bin/sh.check/etc/crontab/行ですSHELL=/bin/sh()に設定されている可能性が高いですdash。私はあなたがこれをSHELL=/bin/bashあなたのユーザーのcrontabファイル(によって編集されたcrontab -e)で設定できると思います。あるいは、スクリプトを書くこともできます。

答え2

はい、構文を使用する必要がありますsh。 Portable Standard shSyntaxの仕様を見つけることができます。そこ

この場合は、[ "$((i+=1))" -le 29 ]標準の算術演算子の完全なセットをまだサポートしていない以前のバージョンにsh基づいている場合を使用してください。ash[ "$i" -le 28 ] ...; i=$(($i + 1))

警告:/var/tmpcronで誰でも書き込み可能なディレクトリを扱うことは、ウォーム缶を開くのと同じくらい安全です。

ファイル名とそのタイプは信頼できず、非常に汚れたものとして扱う必要があります。

特に、あなたの$(/bin/ls -r /var/tmp/*)ものは、ファイル名にどの文字を含めることができるかについて多くの仮定を行い、そのどれもディレクトリやディレクトリへのシンボリックリンクではないと仮定するため、偽です。

答え3

完全に移植可能にするには、$() 構文を次のように置き換えることができます。

I=1; for X in `/bin/ls -r /var/tmp/*`; do [ $I -le 28 ] && echo "lower" || echo "higher"; I=`expr $I + 1`; done

ただし、cronジョブとグローバルに書き込み可能なディレクトリには注意してください。

関連情報