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:我已经 替换shbash/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.检查/etc/crontab/线路SHELL=。很可能设置为/bin/sh( dash)。我相信你可以SHELL=/bin/bash在你自己的用户crontab文件(由编辑的crontab -e)中设置。或者您可以编写脚本。

答案2

是的,您需要使用sh语法。您可以找到可移植标准sh语法的规范那里

在这种情况下,您想要[ "$((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 作业和全局可写目录。

相关内容