crontab執行失敗的多種緣由

crontab是Linux下執行定時任務的常見方法。
這裏總結一下本身遇到的或者被問到的相關問題, 諸如"爲何crontab執行失敗", "爲何crontab沒有執行"。python

在分析以前, 咱們先確認一個前提: 操做命令自己的執行並無問題, 在shell下可正常運行;
不存在權限問題, 更沒有參數缺乏的問題。
也便是說,使用crontab -l輸出該命令時,直接複製到shell中是能夠正常執行的,可是在crontab中事與願違。shell

在以上的前提下,多是以下的幾個緣由,致使了crontab不能正常執行。編碼

crontab中包含非法字符

好比這個命令:spa

echo `date +%Y%m%d`

該命令在shell下直接執行是沒問題的,可是在crontab中就有問題. 緣由是crontab中不能出現非法字符%.
%字符若是沒有跟在轉義字符\以後,將會被當作換行符,第一個%字符以後的內容將會視爲該行命令的標準輸入。操作系統

經過 man 5 crontab 查看到該問題的說明, 以下圖:
非法字符的說明3d

解決方法也很簡單:rest

  • 既能夠將命令寫在另外一個sh文件中,而後再來執行該文件
  • 也可使用\符號對非法字符進行轉義

/etc/crontab 與 contab -e 兩種格式混淆

定時任務有兩種編輯方法,一種是root用戶下編輯/etc/crontab文件: vi /etc/crontab;
一種是在特定用戶身份下(多是root,可能非root),執行crontab -e 進行編輯.日誌

前者的格式相比於後者, 多了一個表示執行命令的「用戶身份」的字段.以下圖:
前者的格式code

這很好理解, /etc/crontab 對全部用戶都是同一個文件,固然須要指明是以哪一個用戶來執行命令了.blog

echo "right" >> /tmp/output_right.txt 命令爲例:
在編輯/etc/crontab時須要寫成:

*/1 * * * * root echo "right" >> /tmp/output_right.txt

crontab -e的狀況下則要寫成:

*/1 * * * * echo "right" >> /tmp/output_right.txt

crond服務未啓動

這個就太好檢查了, 執行service crond status 查看該服務的運行狀態.
若是進程已經dead,重啓一下便可:

service crond start

標準/錯誤輸出中包含不支持字符(好比中文)

這僅僅是一個可能的緣由, 不一樣環境上的表現可能不同, 跟操做系統支持的編碼有關.

好比下面一段簡單的python代碼:

# -*- coding: utf-8 -*-
print(u'中文')

將以上代碼保存爲文件demo.py. 在shell中執行 python demo.py 是沒問題的, 可是在crontab就可能出現問題.

總之避免在日誌輸出中包含中文吧。

缺乏環境變量或者未使用絕對路徑

環境變量在/etc/crontab 頂部的PATH中指定了。默認狀況下,PATH=/sbin:/bin:/usr/sbin:/usr/bin

假設你安裝了supervisorctl(一個守護進程的軟件)到路徑/usr/local/bin/supervisorctl, 而後定義了天天一次的定時任務:

0 1 * * * supervisorctl restart all

該定時任務並不會生效。

緣由在於,PATH中並無將/usr/local/bin加入環境變量。執行supervisorctl時找不到該文件。
解決方法有:

  • /usr/local/bin加入PATH
  • 或者使用絕對路徑 0 1 * * * /usr/local/bin/supervisorctl restart all
相關文章
相關標籤/搜索