Soạn thảo crontab từ xa

Soạn thảo crontab là một công việc cần chính xác, vì vậy nếu có thể thì kết nối với RPI qua ssh và chạy lệnh crontab -e.

Trong trường hợp không thể ssh thì soạn thảo qua email hay SMS với từ khóa qui ước tương tự như

crontab user list|remove|file|cronjob
   user là system user của RPI như root, pi. Soạn thảo tác dụng trên crontab của user đó.
   list trả về crontab hiện hành
   remove xóa crontab
   file dùng file kèm theo để làm crontab
   cronjob là chuỗi có dạng '* * * * * command'

Ta cần một file PHP và một file Bash

  1. File PHP dùng để phân tích nội dung email hay tin nhắn SMS tìm từ khóa cho lệnh crontab. (Có thể định kỳ lấy mail /SMS hay dùng MailGun /event RunOnReceive của gammu)
  2. File Bash dùng để gọi lệnh crontab với các tham số thích hợp (PHP phải có thể gọi file Bash này với quyền root)

Dùng PHP và Regular Expression để tìm và phân tích lệnh trong nội dung $content được gởi đến.

+ Mẫu cronjob

const cronjob = '[-/*0-9]+\s+[-/*0-9]+\s+[-/*0-9]+\s+[-/*0-9]+\s+[-/*0-9]+\s.+';

+ Biểu thức Regular Expression tìm từ khóa

$keyword='/\bcrontab\s+([0-9a-z]+)\s+(list|remove|file|' . self::cronjob .')\b/i';

+ Phân tích lệnh trong nội dung $content

if (preg_match($keyword, $content, $m)){
    $user = $m[1];
    $job = $m[2];
    if ($job == 'file' && count($_FILES)){
        $keys = array_keys($_FILES);
        $job = $_FILES[$keys[0]]['tmp_name'];
    } else exit;
    exec("sudo /path/to/php-crontab {$user} '{$job}'");
}

+ Dòng lệnh exec gọi file Bash php-crontab đã được visudo để gọi crontab trên RPI cập nhật dữ liệu mới

#!/bin/bash
if [ $# -ne 2 ]; then
   echo "Remote control Crontab"
   echo "Usage: $(basename $0) user list|remove|filename|cronjob"
   exit 1
fi
usr="$1"
cmd="$2"
case $cmd in
   l|list)
      cmd="-l"
      ;;
   r|remove)
      cmd="-r"
      ;;
   *) #crontab or filename
      if [[ "$cmd" =~ [-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]]+[-/*0-9]+[[:blank:]].+ ]]; then
         tmpfile=$(mktemp)
         crontab -l > $tmpfile
         echo "$cmd" >> $tmpfile
         cmd=$tmpfile
      elif [[ ! -f "$cmd" ]]; then
         exit 1
      fi
      ;;
esac
crontab -u $usr $cmd
exit $?

Leave a Comment

Filed under Software

Leave a Reply