112

Tôi muốn có thể lập trình thêm một công việc định kỳ mới, cách tốt nhất để làm điều này là gì?

Từ nghiên cứu của tôi , có vẻ như tôi có thể đổ crontab hiện tại và sau đó nối thêm một cái mới, đưa nó trở lại vào crontab:

(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -

Có cách nào tốt hơn?

|
14

Nó luôn hoạt động tốt với tôi.

Bạn nên xem xét một kịch bản phức tạp hơn một chút có thể làm ba việc.

  1. Nối một dòng crontab; đảm bảo rằng nó không tồn tại. Thêm khi nó đã tồn tại là xấu.

  2. Loại bỏ dòng crontab. Có lẽ chỉ cảnh báo nếu nó không tồn tại.

  3. Một sự kết hợp của hai tính năng trên để thay thế dòng crontab.

|
110

Cách tốt nhất nếu bạn đang chạy bằng root, là thả tệp vào /etc/cron.d

nếu bạn sử dụng trình quản lý gói để đóng gói phần mềm của mình, bạn có thể chỉ cần đặt các tệp trong thư mục đó và chúng được hiểu như thể chúng là crontabs, nhưng có thêm một trường cho tên người dùng, ví dụ:

Tên tệp: /etc/cron.d/per_minute

Nội dung: * * * * * root /bin/sh /home/root/script.sh

|
  • 1

    Chỉ cần đảm bảo phiên bản của cron đang sử dụng hỗ trợ /etc/cron.d/. Hầu hết các bản phân phối Linux hiện đại đều có.

    – Vũ Gia Hiệp 11:09:56 06/03/2009
  • 1

    Đây là giải pháp đơn giản nhất, thanh lịch nhất. Nhịp đập chắc chắn phải phân tích và chỉnh sửa một crontab hiện có với các mục không liên quan khác.

    – Hồ Quốc Uy 14:01:06 07/10/2011
  • 1

    Một cảnh báo tiềm năng cho điều này là tần suất mà cron nhận thêm các bổ sung mới vào thư mục này (một lần mỗi giờ). Nếu bạn đang mong đợi công việc của mình bắt đầu chạy ngay lập tức, hãy cẩn thận.

    – Hoàng Yến My 02:53:14 17/04/2014
  • 1

    @JonathanK, bạn có biết cron có thể được yêu cầu quét lại /etc/cron.d/*không? Thật khó để biết nếu một cái gì đó đang hoạt động nếu người ta phải chờ một giờ để kiểm tra!

    – Ngô Vân Ngọc 15:57:58 09/12/2014
  • 1

    Làm thế nào perms thiết lập cho tập tin này? chmod + x /etc/cron.d/per_minute?

    – Quế Quế 09:03:10 03/09/2017
84

Giải pháp của OP có một lỗi, nó có thể cho phép các mục được thêm hai lần, sử dụng bên dưới để khắc phục.

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
|
21

Để thêm một cái gì đó vào cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -

Để loại bỏ điều này khỏi cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh |  sort | uniq | crontab -

hy vọng sẽ giúp được ai đó

|
  • 1

    Đây chính xác là những gì tôi đang tìm kiếm tôi sẽ chỉ cần thêm điều này: | grep -v '^ #' | để lọc ra các bình luận

    – Dương Cao Sĩ 17:01:53 29/08/2014
  • 1

    Thật tuyệt vời, chúc mừng!

    – Hoàng Công Hoán 00:54:55 22/07/2015
  • 1

    Bạn thực sự không cần thiết 2>&1 | grep -v "no crontab"bởi vì khi không có crontab, dòng đầu ra crontab: no crontab for...được gửi đến stderr. Không có lý do để nắm bắt đầu ra đó, gửi nó đến thiết bị xuất chuẩn, và sau đó lọc nó ra bằng grep. Nếu mục tiêu của bạn là tránh nhìn thấy crontab: no crontab for...trong đầu ra của bạn, thì hãy sử dụng2> /dev/null | sort.... .

    – Võ Đức Khang 13:43:06 02/09/2016
6

Nếu bạn đang dự định thực hiện nó cho một kịch bản chạy một lần chỉ để quên một cái gì đó, hãy xem 'tại'

|
5

Chỉ cần thay đổi trình chỉnh sửa thành lệnh tee:

export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e
|
4

Giả sử rằng đã có một mục trong crontab của bạn, lệnh sau sẽ hoạt động tương đối tốt. Lưu ý rằng $CMDbiến chỉ có ở đó để dễ đọc. Sắp xếp trước khi lọc trùng lặp là rất quan trọng, bởi vì uniqchỉ hoạt động trên các dòng liền kề.

CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -

Nếu bạn hiện có một crontab trống, bạn sẽ nhận được lỗi sau để stderr:

no crontab for user

Nếu bạn muốn tránh điều này, bạn có thể thêm một chút phức tạp thêm làm một cái gì đó như thế này:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -
|
2

Bạn cũng có thể chỉnh sửa trực tiếp tệp văn bản bảng cron, nhưng giải pháp của bạn có vẻ hoàn toàn chấp nhận được.

|
  • 1

    Tôi sẽ không hài lòng về điều này do lo ngại về cơ hội chỉnh sửa đồng thời gây ra tham nhũng tệp. Sử dụng lệnh crontab dòng lệnh nên tránh vấn đề đó.

    – Tạ Hoàng Thái 02:28:53 05/03/2009
  • 1

    Craig, không cần nghiên cứu thêm, tôi sẽ không chắc chắn rằng phiên bản dòng lệnh là nguyên tử và an toàn điều kiện chủng tộc. Có lẽ "khá an toàn" nào.

    – Trịnh Ðoan Trang 13:03:22 16/03/2011
  • 1

    "Chỉnh sửa tệp trực tiếp" không khả thi nếu không có quyền truy cập root (miễn là bạn có thể tìm ra nơi tệp crontab của người dùng tồn tại và cách đảm bảo cron daemon nhận chính xác các thay đổi của bạn) và "chỉnh sửa" theo cách lập trình là câu hỏi muốn tư vấn về nơi đầu tiên.

    – Đỗ Thuận Phong 09:12:59 19/05/2015
2

Thêm vào câu trả lời của JohnZ, đây là cú pháp để lên lịch làm root nếu bạn là người sudoer:

(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -
|
2

người đàn ông crontab cũng hữu ích:

CRONTAB (1)

TÊN

   crontab - manipulate per-user crontabs (Dillon's Cron)

TÓM TẮC

   crontab file [-u user] - replace crontab from file

   crontab - [-u user] - replace crontab from stdin

   crontab -l [user] - list crontab for user
|
1

ngoài ra, bạn có thể thêm các tác vụ của mình vào /etc/cron.*/

|
1

Hầu hết các giải pháp ở đây là để thêm dòng vào crontab. Nếu bạn cần kiểm soát nhiều hơn, bạn sẽ muốn có thể kiểm soát toàn bộ nội dung của crontab.

Bạn có thể sử dụng đường ống để làm điều này khá thanh lịch.

Để viết lại hoàn toàn crontab, hãy làm

echo "2 2 2 2 2 /bin/echo foobar" |crontab -

Điều này nên dễ dàng kết hợp với các câu trả lời khác được mô tả ở đây như

crontab -l | <something> | tee |crontab -

Hoặc, nếu bạn có nội dung trong một tệp, nó thậm chí còn đơn giản hơn

cat <file> |crontab -
|
1

Điều này sẽ kiểm tra để đảm bảo rằng lệnh của bạn không tồn tại trước khi thêm nó.

crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -

Chúc mừng.

|
1
function cronjob_exists($command){

    $cronjob_exists=false;

    exec('crontab -l', $crontab);


    if(isset($crontab)&&is_array($crontab)){

        $crontab = array_flip($crontab);

        if(isset($crontab[$command])){

            $cronjob_exists=true;

        }

    }
    return $cronjob_exists;
}

function append_cronjob($command){

    if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){

        //add job to crontab
        exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);


    }

    return $output;
}

    append_cronjob('* * * * * curl -s http://localhost/cron/test.php');
|
0

Đây là một cách khác, giúp tránh trùng lặp

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -

Và đây là một cách để thực hiện câu trả lời của JohnZ và tránh no crontab for usertin nhắn, hoặc nếu bạn cần phải hoạt động trong một set -eumôi trường loại và không thể có bất cứ điều gì trả lại thất bại (trong trường hợp đó là 2>/dev/nullphần không bắt buộc):

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -

Hoặc nếu bạn muốn chia nhỏ mọi thứ để chúng dễ đọc hơn:

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -

Hoặc tùy ý xóa mọi tham chiếu đến your_command (ví dụ: nếu lịch trình đã thay đổi, bạn chỉ muốn nó được ghi lại một lần). Trong trường hợp này, chúng tôi không còn cần uniq(thêm tiền thưởng, thứ tự chèn cũng được giữ nguyên):

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.