Shell脚本和CRON问题

4

我为我们的本地开发服务器(运行Ubuntu服务器版本9.10)编写了一个备份脚本,它只是一个简单的脚本,用于打包和压缩本地根目录,并将其放置在备份文件夹中。

当我运行以下命令时,它可以正常工作:

$ bash backups.sh

但是当我通过crontab运行它时,它无法工作。

59 23 *  *  *  bash /home/vnc/backups/backup.sh >> /home/vnc/backups/backup.log 2> $1

我收到了错误信息。
/bin/sh: cannot create : nonexistent

脚本将tar.gz文件制作在其运行的文件夹中(/home/user1),但随后尝试通过使用fstab从网络驱动器将其复制到已挂载的共享文件夹(/home/backups,实际上是192.168.0.6/backups)。已挂载的共享文件夹权限为777,但所有者和组与运行脚本的用户不同。我使用bash而不是sh来运行脚本,以解决我过去遇到的“bad substitution”错误。
该文件的前两行为:
! /bin/bash

cd /home/vnc/backups

我可能没有提供足够的信息来完全回答这篇文章,但如果需要,我可以发布更多信息,但我不知道下一步该去哪里查找。


我猜测问题出在环境上。尝试通过setdeclare命令将环境变量转储到某个临时文件中并进行比较。很可能与工作目录或类似的东西有关。 - Maxim Sloyko
env 更适合于打印环境信息,抱歉给你带来了误导。 - Maxim Sloyko
我不确定需要比较什么?运行 env 显示我正在使用 /bin/bash/,我没有尝试在任何地方使用 /bin/sh/,所以我无法理解为什么错误与它有关。 - Pete
3个回答

6
线索在错误信息中:
/bin/sh: cannot create : nonexistent

请注意,它说“sh”。Bourne shell不支持一些特定于Bash的功能。如果您正在使用Bash功能,则需要告诉Bash运行脚本。
请将文件的第一行设置为:
#!/bin/bash

或者在您的crontab条目中执行以下操作:

* * * * * /bin/bash scriptname

如果没有看到您的crontab条目和脚本,很难提供更具体的信息。


已经添加了这两行代码!我会更新原始帖子。 - Pete
等一下,我在crontab中写了“bash”而不是“/bin/bash”,我会更新为绝对路径,看看那样是否有效...好的,这也没有任何区别。 - Pete
@Comcar:啊,我现在明白你的问题所在了。在crontab条目中,你将标准输出发送到$1,但是没有为其指定文件名。你需要指定一个文件名。在这种情况下使用$1是没有意义的。此外,在你的编辑中,你把shebang写成了"! /bin/bash",它应该是#! /bin/bash - Dennis Williamson
1
@Comcar:如果你的意思是让stderr和stdout输出到同一个地方,那么应该使用2>&1而不是"2> $1"。 - Dennis Williamson
抱歉,是的,我确实有#!,只是没有复制整行。经过这一番操作,我无法相信这只是一个打字错误。由于$ /& 错误,crontab 没有运行。我真是个傻瓜。谢谢你,Dennis! - Pete

1
也许你在 backups.sh 中应该首先插入一个 cd /home/user1crond 可能会从不同于您认为的目录执行脚本,强制它使用相同的目录可能是一个不错的起点。
另一个潜在有用的调试步骤是添加像 id > /tmp/id.$$ 这样的内容,这样您就可以看到运行脚本所使用的确切用户帐户和组。

我已经将CD放在文件的顶部,我将id >> this.log添加到脚本中作为第一行,但它甚至没有执行到那里。您建议我将其添加到crontab文件中吗? - Pete

1
在crontab中,只需将2>$1更改为2>&1。我刚刚自己完成了一个。谢谢Dennis Williamson。

这并没有真正回答为什么会出现那个错误的问题。 - abhijit
1
他的原始代码中有2>$1,解释是由Dennis Williamson回答的。 - Shusen Yi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接