小知识:Linux中crontab输出重定向不生效问题的解决方法

问题

在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron]。cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间。

cron的配置文件称为“crontab”,是“cron table”的简写。

近期在crontab中添加了一个定时任务,该任务执行之后默认会有正常输出。为了确保在任务执行过程中的异常信息也可以捕获,方便问题定位,因此在crontab中我写了这么一条命令:

?
1
01 09 * * * cd /opdir/test/ && ./test.sh &>>test.log

以上命令非常好理解,每天9:01执行test.sh 脚本并且将脚本的标准错误输出、标准输出全部重定向到文件 test.log中。最终发现脚本是正常执行了,但是test.log 这个日志文件中却没有任何内容。

为了解决和解释这个问题,接下来我们先简单介绍下linux系统中重定向的问题

概念

Linux系统中:

1: 表示标准输出(stdout),默认输出到屏幕

2:表示标准错误输出(stderr),默认输出到屏幕

在平时我们经常使用如下方法将脚本执行结果重定向:

?
1
2
3
4
bash test.sh >test.out //脚本的标准输出写入到文件test.out ,标准错误输出直接打印在屏幕 等价于:bash test.sh 1>test.out
bash test.sh >test.out 2>&1 //标准输出和标准错误输出都写入到test.out并且不会互相覆盖,等价于 bash test.sh &>test.out
bash test.sh >test.out 2>test.out //标准输出和标准错误输出都写入到test.out,会出现互相覆盖的问题,正常情况不推荐这样使用
bash test.sh &>test.out //等价于第二种方法

比较一下以上几种的效果:

第一种:错误输出在屏幕,正常输出在文件test.out

?
1
2
3
4
5
6
7
8
9
root@mengalong:~/opdir/mengalong/t/t# cat test.sh
#!/bin/bash
t
date
root@mengalong:~/opdir/mengalong/t/t# bash test.sh >test.out
test.sh: line 2: t: command not found
root@mengalong:~/opdir/mengalong/t/t# cat test.out
Wed Oct 31 11:07:24 CST 2018

第二种:错误输出和正常输出均重定向到文件test.out中

?
1
2
3
4
root@mengalong:~/opdir/mengalong/t/t# bash test.sh >test.out 2>&1
root@mengalong:~/opdir/mengalong/t/t# cat test.out
test.sh: line 2: t: command not found
Wed Oct 31 11:09:02 CST 2018

第三种:错误输出和正常输出互相覆盖

?
1
2
3
4
root@mengalong:~/opdir/mengalong/t/t# bash test.sh >test.out 2>test.out
root@mengalong:~/opdir/mengalong/t/t# cat test.out
Wed Oct 31 11:10:36 CST 2018
ot found

第四种,特殊情况,比较一下bash test.sh 2>&1 >test.out 和 bash test.sh >test.out 2>&1 的区别:

?
1
2
3
4
root@mengalong:~/opdir/mengalong/t/t# bash test.sh 2>&1 >test.out
test.sh: line 2: t: command not found
root@mengalong:~/opdir/mengalong/t/t# cat test.out
Wed Oct 31 11:12:13 CST 2018

这里只是把 2>&1 放在了 >test.out 前边,但是结果却不是像我们想象的那样,错误和正常输出都进入test.out 文件。这是因为, bash test.sh 2>&1 >test.out 这个命令中, 2>&1 的时候,只是把错误输出重定向到了标准输出,而此时标准输出的默认值是屏幕,因此实际等价于标准错误输出被重定向到了屏幕,而非文件。因此重定向需要注意顺序。

问题解决

接下来再回过头来看看,我写的crontab任务:

?
1
01 09 * * * cd /opdir/test/ && ./test.sh &>>test.log

按照上边的概念分析,这种写法应该等价于./test.sh >test.log 2>&1 ,脚本执行的输出和标准错误输出全部重定向到 test.log。但是实际情况却是test.log文件中并没有任何内容。

这是因为 crontab 默认使用的shell环境为 /bin/sh, 而/bin/sh 并不支持 &>>test.log 这种重定向方法,因此我们看到的效果是test.log 中没有内容。

因此解决问题的方法就是将crontab的重定向方法进行修改:

?
1
01 09 * * * cd /opdir/test/ && ./test.sh >>test.log 2>&1

啰嗦一句

crontab执行过程中,如果脚本输出没有重定向,那么会默认给系统用户发邮件,邮件内容一般存储在 /var/mail/$user 中,如果不清理就会打满服务器根分区,最终导致机器无法登陆。因此推荐的crontab命令写法如下:

?
1
01 09 * * * cd /opdir/test/ && ./test.sh >>test.log 2>&1 </dev/null &

具体后边增加了 </dev/null & ,这个的含义就不多说了,感兴趣的可以自己分析一下

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:http://mengalong.github.io/2018/10/31/crontab-redirect/

声明: 猿站网有关资源均来自网络搜集与网友提供,任何涉及商业盈利目的的均不得使用,否则产生的一切后果将由您自己承担! 本平台资源仅供个人学习交流、测试使用 所有内容请在下载后24小时内删除,制止非法恶意传播,不对任何下载或转载者造成的危害负任何法律责任!也请大家支持、购置正版! 。本站一律禁止以任何方式发布或转载任何违法的相关信息访客发现请向站长举报,会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。本网站的资源部分来源于网络,如有侵权烦请发送邮件至:2697268773@qq.com进行处理。
建站知识

小知识:在Linux中如何一次重命名多个文件详解

2023-3-21 5:57:01

建站知识

小知识:Linux 文件压缩和打包简介

2023-3-21 6:22:01

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索