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 sh
Syntaxの仕様を見つけることができます。そこ。
この場合は、[ "$((i+=1))" -le 29 ]
標準の算術演算子の完全なセットをまだサポートしていない以前のバージョンにsh
基づいている場合を使用してください。ash
[ "$i" -le 28 ] ...; i=$(($i + 1))
警告:/var/tmp
cronで誰でも書き込み可能なディレクトリを扱うことは、ウォーム缶を開くのと同じくらい安全です。
ファイル名とそのタイプは信頼できず、非常に汚れたものとして扱う必要があります。
特に、あなたの$(/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ジョブとグローバルに書き込み可能なディレクトリには注意してください。