Linux中crontab任务计划不执行的问题分析

在使用配置crontab过程中一直不能执行配置的任务,折腾了半夜没有解决,随找到如下文章,查问题的思路很清晰,帮我找到了问题,直接转:

crond是Linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

使用权限:
root用户和crontab文件的所有者
语法:
crontab [-e [UserName]|-l [UserName]|-r [UserName]|-v [UserName]|File ]
说明:
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。-u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。
参数:
-e [UserName]: 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
-r [UserName]: 删除目前的时程表
-l [UserName]: 列出目前的时程表
-v [UserName]:列出用户cron作业的状态
自拉起脚本很简单,随便写几行就搞定了:
Shell
#!/bin/bash
processcount=$(pgrep my_app|wc -l)
cd $(cd $(dirname $0) && pwd)
if [[ 0 -eq $processcount ]]
then
echo “[ $(date) ] : my_app is down, start it!” | tee -ai ./checkprocess.log
bash ./start.sh #这里是项目的重启脚本
else
echo my_app is OK!
fi
然后丢到 crontab,1分钟执行一次:
Shell

* * * * * bash /data/app_server/checkprocess.sh >/dev/null 2>&1
本以为万事大吉了,结果还是坑了,进程再一次挂了,尼玛什么鬼?
一、检查日志
根据经验,先看一下crontab的日志:
tail /var/log/messages
没发现相关日志,看来不是打印到了这,于是查看了下crontab的默认日志位置:
tail /var/log/cron

Mar 25 21:40:01 li733-135 CROND[1959]: (root) CMD (sh /data/app_server/checkprocess.sh >/dev/null 2>&1)
Mar 25 21:40:01 li733-135 CROND[1960]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Mar 25 21:40:01 li733-135 CROND[1961]: (root) CMD (/usr/sbin/ntpdate pool.ntp.org > /dev/null 2>&1)
Mar 25 21:41:01 li733-135 CROND[2066]: (root) CMD (sh /data/app_server/checkprocess.sh >/dev/null 2>&1)
很明显,任务计划确实在正常执行着,看来问题在脚本上了。
二、检查脚本

①、直接执行
检查脚本第一步,直接按照crontab里面的命令行,执行脚本:
sh /data/app_server/checkprocess.sh
[ Fri Mar 25 21:25:01 CST 2016 ] : my_app is down, start it!

sh /data/app_server/checkprocess.sh
my_app is OK!
结果进程正常拉起了!
直接执行成功,而放到crontab就失败,经验告诉我肯定的脚本环境变量有问题了!
②、环境变量
于是在脚本里面载入环境变量:
#!/bin/bash
#先载入环境变量
source /etc/profile
#其他代码不变
然后手工把进程杀死,等待自拉起,结果… 还是不行!
③、系统邮件
经验告诉我,crontab执行失败,如果没有屏蔽错误的话,会产生一个系统邮件,
位置在 /var/spool/mail/root
所以,我把crontab里面的 2>&1 这个屏蔽错误先取消掉,等待几分钟查看邮件。
cat /var/spool/mail/root 发现有如下报错:

From root@free-node-us.localdomain Fri Mar 25 21:30:02 2016
Return-Path: <root@app_server.localdomain>
X-Original-To: root
Delivered-To: root@app_server.localdomain
Received: by app_server.localdomain (Postfix, from userid 0)
id 78DB5403E2; Fri, 25 Mar 2016 21:19:02 +0800 (CST)
From: root@app_server.localdomain (Cron Daemon)
To: root@app_server.localdomain
Subject: Cron <root@app_server> bash /data/app_server/checkprocess.sh >/dev/null
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>
Message-Id: <20160325131902.78DB5403E2@app_server.localdomain>
Date: Fri, 25 Mar 2016 21:19:02 +0800 (CST)

start.sh: line 4: /sbin/sudo: No such file or directory #sudo命令找不到!我次奥·~
居然是脚本里面的sudo执行失败了,找不到这个文件。看来单纯的载入 profile 不一定靠谱啊!
③、修复脚本
知道问题所在,解决就简单了,粗暴点,直接写入sudo的绝对路径 /usr/bin/sudo
继续测试自拉起,结果… 还是不行!R了G了!!
三、最终解决
继续查看了下系统邮件,发现如下信息:
Subject: Cron <root@free-node-us> source /etc/profile;bash /data/app_server/checkprocess.sh >/dev/null
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>
Message-Id: <20160325132403.0E8E1403E2@app_server.localdomain>
Date: Fri, 25 Mar 2016 21:24:03 +0800 (CST)

sudo: sorry, you must have a tty to run sudo #原来是这个问题!
很明显,提示了sudo必须需要tty才能执行,解决很简单,取消这个限制即可!
编辑 /etc/sudoers ,找到 Defaults requiretty, 然后注释掉这行:

vim /etc/sudoers

#Defaults requiretty
最后使用 :x! 或 :wq! 强制保存即可。
结果观察还是报了相同的错误!原来改完这个sudo并不会影响已经运行的crontab,所以需要重启crontab服务刷新下设置:

service crond restart
这下终于可以了!

四、分析总结
Linux系统里面计划任务,crontab 没有如期执行这是运维工作中比较常见的一种故障了,根据经验,大家可以从如下角度分析解决:

①、检查crontab服务是否正常
这个一般通过查看日志来检查,也就是前文提到的 /var/log/cron 或 /var/log/messages,如果里面没有发现执行记录,那么可以重启下这个服务:service crond restart
②、检查脚本的执行权限
一般来说,在crontab中建议使用 sh 或 bash 来执行shell脚本,避免因脚本文件的执行权限丢失导致任务失败。当然,最直接检查就是人工直接复制crontab -l 里面的命令行测试结果。
③、检查脚本需要用到的变量
和上文一样,通常来说从crontab里面执行的脚本和人工执行的环境变量是不一样的,所以对于一些系统变量,建议写绝对路径,或使用witch动态获取,比如 sudo_bin=$(which sudo) 就能拿到 sudo在当前系统的绝对路径了。
④、放大招:查看日志
其实,最直接最有效的就是查看执行日志了,结合crontab执行记录,以及crontab执行出错后的系统邮件,一般都能彻底找到失败的原因了!当然,要记住在crontab中如果屏蔽了错误信息,就不会发邮件了。
这又让我想起了如果crontab未屏蔽日志,可能会导致硬盘 inode 爆满

CentOS 7 使用阿里云的yum源

1. 备份原来的yum源

sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
2.设置aliyun的yum源

sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

3.添加EPEL源

sudo wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo

4.清理缓存并生成新的缓存

sudo yum clean all
sudo yum makecache

Gogs配置安装

0、确认是否安装了git,如果没有安装

    yum install git

1wget http://7d9nal.com2.z0.glb.qiniucdn.com/gogs_v0.9.97_linux_amd64.zip

     解压到/usr/local/gogs

2、配置nginx

  server {

    listen 80;

    server_name 域名;

        location / {

             proxy_pass http://127.0.0.1:3000;

          }

      }

     加载配置

     nginx -s reload

4、添加git用户

>useradd -d /home/git git

>mkdir /opt/git

>mkdir /opt/git/data      #存放gogs数据库

>mkdir /opt/git/repositories   #git数据仓库

分配权限:

chown git:git /home/git -R

chown git:git /usr/local/gogs -R

chown git:git /opt/git -R

chown git:git /opt/git/data -R

chown git:git /opt/git/repositories -R

5、切换用户 >su git

6、进入/usr/local/gogs

      >./gogs web

7、访问

      域名开始配置 

      配置sqlite数据库/opt/git/data

     数据仓库opt/git/repositories

8、调试没有问题了直接后台运行

     nohup ./gogs web &

centos安装go最新版本

1、卸载原版本  yum -y remove go

2、去https://golang.org/dl/下载最新的包,例如:

# tar zxvf go1.7.1.linux-amd64.tar.gz -C /usr/local

新建GOPATH目录
# mkdir -p /mnt/wwwroot/gofile
# vim /etc/profile

export GOROOT=/usr/local/go
export GOBIN=$GOROOT/bin
export PATH=$PATH:$GOBIN
export GOPATH=/mnt/wwwroot/gofile
:wq保存

使其生效
#source /etc/profile

查看是否配置成功
# go version
go version go1.7.1 linux/amd64

简单测试:
# cd /mnt/wwwroot/gofile
# vim hello.go
package main
import “fmt”
func main() {
fmt.Println(“Hello, 世界”)
}
# go run hello.go
Hello, 世界

删除linux中的乱码文件

【转】
[root@192_168_100_35 musicwap]# ls
??,?K?k?ͨa*.?J]?k?Φ??P???Z?b?A?R???X??u??.?????*H@B?T???xS*查看乱码文件的i结点
[root@192_168_100_35 musicwap]# ls -liaha
54263996 -rw-rw-r– 1 musicwap musicwap    0 Sep 20 16:57 ??,?K?k?ͨa*.?J]?k?Φ??P???Z?b?A?R???X??u??.?????*H@B?T???xS*
使用find命令找文件删除
[root@192_168_100_35 musicwap]# find . -inum 54263996 -exec rm {} -rf \;
[root@192_168_100_35 musicwap]# ls -a
. ..
现在已经删除了。

linux操作系统常见问题汇总

0、暂时锁定用户

或者使用如下命令关闭用户账号:
passwd liwf –l

重新释放:
passwd liwf –u

1、设置开机启动
vi  /etc/rc.d/rc.local

2、查看系统版本
lsb_release -a

3、查看修改时间

命令 : “date”

设置日期命令 : “date -s 11/03/2009”

设置时间命令 : “date -s 17:55:55”

将当前时间和日期写入BIOS,避免重启后失效:命令 : “hwclock -w”

注:

date
不加参数可以直接看到当前日期时间

cal
不加参数可以直接看到本月月历

4、查看CPU信息

1. 查看物理CPU的个数
#cat /proc/cpuinfo |grep “physical id”|sort |uniq|wc -l

2. 查看逻辑CPU的个数
#cat /proc/cpuinfo |grep “processor”|wc -l

3. 查看CPU是几核
#cat /proc/cpuinfo |grep “cores”|uniq

4. 查看CPU的主频
#cat /proc/cpuinfo |grep MHz|uniq

# uname -a
Linux euis1 2.6.9-55.ELsmp #1 SMP Fri Apr 20 17:03:35 EDT 2007 i686 i686 i386 GNU/Linux
(查看当前操作系统内核信息)

# cat /etc/issue | grep Linux
Red Hat Enterprise Linux AS release 4 (Nahant Update 5)
(查看当前操作系统发行版信息)

# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
8 Intel(R) Xeon(R) CPU E5410 @ 2.33GHz
(看到有8个逻辑CPU, 也知道了CPU型号)

# cat /proc/cpuinfo | grep physical | uniq -c
4 physical id : 0
4 physical id : 1
(说明实际上是两颗4核的CPU)

# getconf LONG_BIT
32
(说明当前CPU运行在32bit模式下, 但不代表CPU不支持64bit)

# cat /proc/cpuinfo | grep flags | grep ‘ lm ‘ | wc -l
8
(结果大于0, 说明支持64bit计算. lm指long mode, 支持lm则是64bit)