运行多个shell命令的有效方法?

时间:2012-09-20 22:34:57

标签: shell scripting

Shell脚本newb在这里。 首先,感谢您提前帮助我解决这个问题。

我需要创建一个shell脚本和一个cron作业来删除存储在自定义目录中的/ tmp和会话。

我已经学习了几天的基础知识,并且正在尝试我的第一个shell脚本和cron作业。

最难以运行多个shell命令,这些命令允许命令通过,即使其他命令失败。我还想要为那些失败的命令发送日志报告和电子邮件。

我知道我可以使用&符号(和&&) 或分号。我也知道&符号允许退出错误检查,而分号则不允许。

这是我的剧本

TmpPurge.sh

#!/bin/bash
find /home/username/sessions -iname 'sess_*' -mmin +480 -exec rm -rf {} \; &&
find /home/username/sessions -iname 'sess_*' -mmin +240 -exec rm -rf {} \; &&
/usr/sbin/tmpwatch -umc 5 /home/username/sessions &&
/usr/sbin/tmpwatch -umc 6 /var/tmp &&
/usr/sbin/tmpwatch -umc 12 /var/cache/eaccelerator

if [ $? = 0 ];
then
echo "$(date) Tmp purge completed successfully with error code: $?.  " >> /home/username/logs/TmpPurge.log
else
echo "$(date) Tmp purge exited with error code: $?.  " >> /home/username/logs/TmpPurge.log
fi
echo -e "\r" >> /home/username/logs/TmpPurge.log

Cron工作:

20 3 * * * /bin/sh /home/username/scriptsdir/TmpPurge.sh > /home/username/logs/TmpPurge.log 2>&1

问题1:脚本是否正确? 问题2:运行多个命令的最佳方法是什么?它会是上面还是

find /home/username/sessions -iname 'sess_*' -mmin +480 -exec rm -rf {} \;
find /home/username/sessions -iname 'sess_*' -mmin +240 -exec rm -rf {} \;
/usr/sbin/tmpwatch -umc 5 /home/username/sessions;
/usr/sbin/tmpwatch -umc 6 /var/tmp;
/usr/sbin/tmpwatch -umc 12 /var/cache/eaccelerator

/usr/sbin/tmpwatch -umc 5 /home/username/sessions\%
/usr/sbin/tmpwatch -umc 6 /var/tmp\%
/usr/sbin/tmpwatch -umc 12 /var/cache/eaccelerator\%

2 个答案:

答案 0 :(得分:1)

第一种方法是,将命令与&&链接在一起,将在第一个错误处停止,并报告该错误。如果您使用分号;(如果您将每个命令放在一个新行上,则实际上是不必要的),那么它们都会运行,无论它们是否有任何失败,并且您的if [ $? -eq 0 ]检查只会如果 last 命令有错误,请注意并报告错误。所以我认为这不是你想要的。

或者,您可以在每个命令后添加if [ $? -ne 0 ]个检查。也许尝试看起来最清晰,最容易理解的东西。

此外,如果cron作业是多用户系统,那么使用cron作业和find以及-exec rm -rf {}清除tmp可能会很危险,只需google around即可查看我的意思。有人可能会得到一些你可以看到的好的,安全的代码。

答案 1 :(得分:1)

检查错误的另一种方法是通过“||”操作

 command || exit 1    # Will exit with return code 1 if command fails

这个想法很简单:

&安培;&安培;和||用于将命令链接在一起(不像“;”,用于分隔命令)。

&安培;&安培;是AND运算符,意味着每个连续的命令只有在前面的命令成功时才会运行(以0退出)。

||是OR运算符,意味着每个连续的命令只会在前一个命令失败时运行(以不同于0的值退出)。

用于结束命令(或命令链)。如果一条线突然结束,那么shell(至少我所知道的大多数壳)假定该线以a结尾。如果你不想这样,你需要用\结束这一行,但是shell会将这些行连接在一起,然后再将它作为一行运行。

另请注意,您可以将这些链接在一起:

 echo a && echo b && ls /dir/doesnt/exist && echo c; echo d || echo e; ls /dir/doesnt/exist || echo f

将打印:

 a
 b
 d
 f

另请注意,您还可以以左联方式混合各种&& s和|| s:

 echo a && ls /dir/doesnt/exist || echo b

打印:

 a
 b