Làm cách nào để tạo một công việc định kỳ bằng Bash tự động mà không cần trình soạn thảo tương tác?


395

Liệu crontab có một đối số để tạo các công việc cron mà không cần sử dụng trình soạn thảo (crontab -e). Nếu vậy, mã sẽ tạo ra một cronjob từ tập lệnh Bash là gì?



5
Đáng buồn thay, hầu hết các câu trả lời hàng đầu ở đây chỉ là cách sửa đổi crontab - mặc dù theo những cách hợp lý an toàn - nhưng tôi nghĩ rằng đó là cách tiếp cận sai. Tốt hơn, an toàn hơn và đơn giản hơn là thả một tệp vào {{cron.d}} và có (hiện tại) các câu trả lời bỏ phiếu thấp giải thích cách thực hiện nếu bạn nhìn xuống dưới.
gregmac

Câu trả lời:


539

Bạn có thể thêm vào crontab như sau:

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron

Giải thích dòng cron

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Nguồn nixCraft .


14
Bạn nên sử dụng tempfile hoặc mktemp
Paweł Polewicz

166
(crontab -l; echo "00 09 * * 1-5 echo xin chào") | crontab -
Edo

32
(crontab -l ; echo "00 09 * * 1-5 echo hello") | crontab -- dễ dàng hơn để sao chép câu trả lời của Edo
WBAR

8
Tôi đề nghị thay đổi điều đó ;với &&tư cách là người bảo vệ an toàn trước vụ kiện nếu crontab -lthất bại. vì vậy, như:(crontab -l && echo "0 0 0 0 0 some entry") | crontab -
MacUsers

12
@MacUsers, crontab -lkhông thành công nếu không có crontab, vì vậy việc sử dụng &&khiến tập lệnh không thể thêm mục nhập đầu tiên vào crontab.
JPhi1618

312

Bạn có thể làm điều đó một cách nhanh chóng

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -

crontab -lliệt kê các công việc crontab hiện tại, catin nó, echoin lệnh mới và crontab -thêm tất cả các công cụ in vào tệp crontab. Bạn có thể thấy hiệu quả bằng cách làm mới crontab -l.


3
cảm ơn, bạn có thể giải thích cú pháp hoặc trỏ đến một url giải thích nó không?
trang web

9
crontab -lliệt kê các công việc crontab hiện tại, catin nó, echoin lệnh mới và crontab -thêm tất cả các công cụ in vào tệp crontab. Bạn có thể thấy hiệu quả bằng cách thực hiện mớicrontab -l
nha

3
Làm việc một điều trị cho tôi. Nếu người dùng không có crontab hiện tại, bạn sẽ thấy no crontab for <username>, nhưng dù sao nó cũng hoạt động.
fazy

21
không hoạt động trên ví dụ Amazon EC2 của tôi. Thay vào đó, (crontab -l ; echo "00 09 * * 1-5 echo hello") | crontab -làm việc.
Stéphane Bruckert

11
Điều này trông giống như một ứng cử viên cho một UUcatA .
ceving

86

Cái ngắn hơn này không yêu cầu tệp tạm thời, nó miễn nhiễm với nhiều lần chèn và nó cho phép bạn thay đổi lịch trình của một mục hiện có.

Nói rằng bạn có những điều này:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"

Để thêm nó vào crontab, không trùng lặp:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -

Để xóa nó khỏi crontab bất kể lịch trình hiện tại của nó là gì:

( crontab -l | grep -v -F "$croncmd" ) | crontab -

Ghi chú:

  • grep -F khớp với chuỗi theo nghĩa đen, vì chúng tôi không muốn diễn giải nó như một biểu thức thông thường
  • Chúng tôi cũng bỏ qua việc lập lịch trình thời gian và chỉ tìm kiếm lệnh. Cách này; lịch trình có thể được thay đổi mà không có nguy cơ thêm một dòng mới vào crontab

@moeseth: bạn có thể giải thích không?
MoonCactus

bạn nên thử nó trên máy tính của mình
từ

2
@moeseth: Tôi rõ ràng đã thử nó trên máy tính của tôi (linux). Tôi sẽ không đề xuất công cụ không hoạt động ngẫu nhiên: /
MoonCactus

2
Nhân tiện, 27 người không thể sai (tính đến hôm nay). Vì vậy, vui lòng mô tả lý do tại sao nó không hoạt động cho thiết lập của bạn, vì vậy chúng tôi có thể giúp đỡ.
MoonCactus

2
Nó có thể là vấn đề OSX.
moeseth

40

Cảm ơn mọi người đã giúp đỡ. Ghép lại những gì tôi tìm thấy ở đây và những nơi khác tôi đã nghĩ ra điều này:

Mật mã

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -

Tôi không thể tìm ra cách loại bỏ sự cần thiết của hai biến mà không cần lặp lại.

commandrõ ràng là lệnh tôi muốn lên lịch. jobmất $commandvà thêm dữ liệu lập lịch. Tôi cần cả hai biến riêng biệt trong dòng mã làm việc.

Chi tiết

  1. Tín dụng cho duckyflip, tôi sử dụng điều hướng nhỏ này ( <(*command*)) để biến đầu ra crontab -lthành đầu vào cho fgreplệnh.
  2. fgrepsau đó lọc ra bất kỳ kết quả khớp nào của $command( -vtùy chọn), không phân biệt chữ hoa chữ thường ( -itùy chọn).
  3. Một lần nữa, điều hướng nhỏ ( <(*command*)) được sử dụng để biến kết quả trở lại thành đầu vào cho catlệnh.
  4. Các catlệnh cũng nhận echo "$job"(tự giải thích), một lần nữa, thông qua việc sử dụng thingy chuyển hướng (<(*command*) ).
  5. Vì vậy, đầu ra được lọc từ crontab -lvà đơn giản echo "$job", kết hợp, được dẫn ('|') crontab -đến cuối cùng được viết.
  6. Và tất cả họ sống hạnh phúc mãi mãi về sau!

Tóm lại:

Dòng mã này lọc ra bất kỳ công việc cron nào khớp với lệnh, sau đó viết ra các công việc cron còn lại với công việc mới, hoạt động hiệu quả như chức năng "thêm" hoặc "cập nhật". Để sử dụng điều này, tất cả những gì bạn phải làm là trao đổi các giá trị cho các biến commandjob.


5
Vì lợi ích của người khác khi đọc, ưu điểm của phương pháp này là bạn có thể chạy nó nhiều lần mà không phải lo lắng về các mục trùng lặp trong crontab (không giống như tất cả các giải pháp khác). Đó là vìfgrep -v
aleemb

5
Nếu bạn thích cách truyền thống từ trái sang phải truyền thống, hãy thay thế dòng cuối cùng bằng: crontab -l | fgrep -i -v "$command" | { cat; echo "$job"; } | crontab -l
Antoine Lizée

1
@ AntoineLizée, cuối cùng bạn trả lời có thêm "l", không nên ở đó.
Henry

26

EDIT (ghi đè cố định):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -

Điều này sẽ thay thế bất kỳ nội dung crontab nào
TheBotto

1
@TheBotto oh tôi hiểu rồi, tôi đã sửa nó ngay bây giờ vì vậy nó nên
PHỤC HỒI

3
Hãy nhớ rằng, quá trình thay thế quy trình của Bash nuốt lỗi. Nếu crontab -lthất bại, nhưng crontab -thành công, crontab của bạn sẽ là một lớp lót.
ceving

13

Đã có rất nhiều câu trả lời hay xung quanh việc sử dụng crontab, nhưng không đề cập đến một phương pháp đơn giản hơn, chẳng hạn như sử dụng cron.

Việc sử dụng cronsẽ tận dụng các tệp và thư mục hệ thống tại /etc/crontab, /etc/cron.daily,weekly,hourlyhoặc /etc/cron.d/:

cat > /etc/cron.d/<job> << EOF
SHELL=/bin/bash 
PATH=/sbin:/bin:/usr/sbin:/usr/bin 
MAILTO=root HOME=/  
01 * * * * <user> <command>
EOF

Trong ví dụ trên, chúng tôi đã tạo một tệp trong /etc/cron.d/, cung cấp các biến môi trường để lệnh thực thi thành công và cung cấp usercho lệnh vàcommand chính nó. Không nên thực hiện tệp này và tên chỉ nên chứa số alpha và dấu gạch nối (chi tiết bên dưới).

Để đưa ra câu trả lời thấu đáo, chúng ta hãy xem sự khác biệt giữa crontabvs cron/crond:

crontab -- maintain tables for driving cron for individual users

Đối với những người muốn điều hành công việc trong bối cảnh người dùng của họ trên hệ thống, sử dụng crontabcó thể có ý nghĩa hoàn hảo.

cron -- daemon to execute scheduled commands

Đối với những người sử dụng quản lý cấu hình hoặc muốn quản lý công việc cho người dùng khác, trong trường hợp đó chúng ta nên sử dụng cron .

Một đoạn trích nhanh từ các trang hướng dẫn cung cấp cho bạn một vài ví dụ về những việc nên và không nên làm:

/ etc / crontab và các tệp trong /etc/cron.d phải được sở hữu bởi root và không được thuộc nhóm hoặc có thể ghi khác. Ngược lại với khu vực bộ đệm, các tệp trong /etc/cron.d hoặc các tệp trong /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly và /etc/cron.monthly cũng có thể là symlink, với điều kiện là cả symlink và tập tin mà nó trỏ đến đều được sở hữu bởi root. Các tệp trong /etc/cron.d không cần phải được thực thi, trong khi các tệp trong /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly và /etc/cron.monthly làm, như chúng được chạy bởi các bộ phận chạy (xem phần chạy (8) để biết thêm thông tin).

Nguồn: http://manpages.ubfox.com/manpages/trusty/man8/cron.8.html

Quản lý các crons theo cách này dễ dàng hơn và có thể mở rộng hơn từ góc độ hệ thống, nhưng sẽ không phải luôn luôn là giải pháp tốt nhất.


1
Điều đáng nói là <job>không nên bao gồm phần mở rộng tập tin.
jww

7

Có thể bạn đang tự động hóa việc này và bạn không muốn một công việc được thêm hai lần. Trong trường hợp đó sử dụng:

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")

Điều này chỉ hoạt động nếu bạn đang sử dụng BASH. Tôi không biết shcú pháp DASH ( ) chính xác .

Cập nhật: Điều này không hoạt động nếu người dùng chưa có crontab. Một cách đáng tin cậy hơn sẽ là:

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 

Ngoài ra, nếu bản phân phối của bạn hỗ trợ nó, bạn cũng có thể sử dụng một tệp riêng:

echo "1 2 3 4 5 /root/bin/backup.sh" |sudo tee /etc/crond.d/backup

Tìm thấy những người trong một câu hỏi SO khác .


Sử dụng sh thay vì bash có thể?
kvz

Vẫn đang sh: 1: Syntax error: "(" unexpectedsử dụng sh .
Batandwa

Điều này chỉ hoạt động nếu bạn đang sử dụng BASH. Tôi không biết cú pháp DASH (sh) chính xác. Cũng cập nhật câu trả lời
kvz

1
fwiw, tôi gặp lỗi này khi sử dụng bash nếu có khoảng trắng giữa <(. Điều đó có nghĩa là < (thất bại nhưng <(hoạt động, trừ khi có dấu hoa thị trong lịch trình của bạn ...
gỡ rối vào

Tôi tin rằng đây là cách chính xác:cat <(crontab -l |grep -v "${CRON}") <(echo "${CRON}") | crontab -
Stanislav

5

Để tạo / thay thế một crontab nhanh chóng và bẩn thỉu bằng tập lệnh BASH, tôi đã sử dụng ký hiệu này:

crontab <<EOF
00 09 * * 1-5 echo hello
EOF

5

Một biến thể chỉ chỉnh sửa crontab nếu không tìm thấy chuỗi mong muốn ở đó:

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")

3

Nếu bạn đang sử dụng Vixie Cron, ví dụ như trên hầu hết các bản phân phối Linux, bạn chỉ có thể đặt một tệp trong /etc/cron.d với từng cronjob riêng lẻ.

Điều này chỉ hoạt động cho root tất nhiên. Nếu hệ thống của bạn hỗ trợ điều này, bạn sẽ thấy một số ví dụ trong đó. (Lưu ý tên người dùng được bao gồm trong dòng, theo cùng một cú pháp như cũ / etc / crontab)

Thật đáng tiếc trong cron rằng không có cách nào để xử lý việc này như một người dùng thông thường và rất nhiều việc triển khai cron không có cách nào để xử lý việc này.


2

Vì vậy, trong Debian, Ubuntu và nhiều bản phân phối dựa trên Debian tương tự ...

Có một cơ chế kết nối tác vụ cron lấy một tệp cấu hình, gói chúng lại và thêm chúng vào dịch vụ cron của bạn đang chạy.

Bạn có thể đặt một tệp dưới /etc/cron.d/somefilename trong đó somefilename là bất cứ thứ gì bạn muốn.

sudo echo "0,15,30,45 * * * * ntpdate -u time.nist.gov" >> /etc/cron.d/vmclocksync

Hãy tháo rời cái này:

sudo - vì bạn cần các đặc quyền nâng cao để thay đổi cấu hình cron trong thư mục / etc

echo - một phương tiện để tạo đầu ra trên std out. printf, cat ... cũng sẽ làm việc

"- sử dụng doublequote ở đầu chuỗi của bạn, bạn là một chuyên gia

0,15,30,45 * * * * - lịch chạy cron tiêu chuẩn, chương trình này chạy cứ sau 15 phút

ntpdate -u time.nist.gov - lệnh thực tế tôi muốn chạy

"- bởi vì dấu ngoặc kép đầu tiên của tôi cần một người bạn để đóng dòng đang được xuất

>> - chuyển hướng kép nối thêm thay vì ghi đè *

/etc/cron.d/vmclocksync - vmclocksync là tên tệp tôi đã chọn, nó có trong /etc/cron.d/


* nếu chúng tôi sử dụng chuyển hướng>, chúng tôi có thể đảm bảo chúng tôi chỉ có một mục nhập nhiệm vụ. Nhưng, chúng tôi sẽ có nguy cơ thổi bay mọi quy tắc khác trong một tệp hiện có. Bạn có thể tự quyết định nếu việc hủy có thể xảy ra với> là trùng lặp đúng hoặc có thể với >> là dành cho bạn. Ngoài ra, bạn có thể làm một cái gì đó phức tạp hoặc liên quan để kiểm tra xem tên tệp có tồn tại không, nếu có bất cứ thứ gì trong đó và liệu bạn có thêm bất kỳ loại trùng lặp nào không - nhưng, tôi có việc phải làm và tôi không thể làm điều đó cho bạn ngay bây giờ


2

Bash script để thêm công việc cron mà không cần trình soạn thảo tương tác. Mã dưới đây giúp thêm một cronjob bằng các tệp linux.

#!/bin/bash

cron_path=/var/spool/cron/crontabs/root

#cron job to run every 10 min.
echo "*/10 * * * * command to be executed" >> $cron_path

#cron job to run every 1 hour.
echo "0 */1 * * * command to be executed" >> $cron_path

1
Tôi biết đó là một thời gian loooong, nhưng đây vẫn là câu trả lời tốt duy nhất, vì tất cả những người được bình chọn nhiều nhất đều loại bỏ những con dơi cũ thay vì chỉ nối thêm cái mới.
AFE

1
Cái này không cài đặt cron. Nó chỉ thêm nó vào một tập tin. Bạn sẽ phải bằng cách nào đó thông báo cho quá trình cron để cài đặt mục mới.
Apoorv Parijat

1

Đây là một hàm bash để thêm lệnh vào crontabmà không trùng lặp

function addtocrontab () {
  local frequency=$1
  local command=$2
  local job="$frequency $command"
  cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -
}
addtocrontab "0 0 1 * *" "echo hello"

1
CRON="1 2 3 4 5 /root/bin/backup.sh" 
cat < (crontab -l) |grep -v "${CRON}" < (echo "${CRON}")

thêm tham số -w vào lệnh grep chính xác, không có tham số -w thêm "kiểm tra" cronjob gây ra xóa công việc cron "tests123"

chức năng kịch bản để thêm / loại bỏ cronjobs. không có mục trùng lặp:

cronjob_editor () {         
# usage: cronjob_editor '<interval>' '<command>' <add|remove>

if [[ -z "$1" ]] ;then printf " no interval specified\n" ;fi
if [[ -z "$2" ]] ;then printf " no command specified\n" ;fi
if [[ -z "$3" ]] ;then printf " no action specified\n" ;fi

if [[ "$3" == add ]] ;then
    # add cronjob, no duplication:
    ( crontab -l | grep -v -F -w "$2" ; echo "$1 $2" ) | crontab -
elif [[ "$3" == remove ]] ;then
    # remove cronjob:
    ( crontab -l | grep -v -F -w "$2" ) | crontab -
fi 
} 
cronjob_editor "$1" "$2" "$3"

thử nghiệm :

$ ./cronjob_editor.sh '*/10 * * * *' 'echo "this is a test" > export_file' add
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

Nếu bạn có cùng một lệnh trong crontab hai lần (chạy vào các thời điểm khác nhau), việc xóa sẽ xóa cả hai dòng.
Michaelkay

1

Giải pháp ưa thích của tôi cho việc này sẽ là:

(crontab -l | grep . ; echo -e "0 4 * * * myscript\n") | crontab -

Điều này sẽ đảm bảo bạn đang xử lý dòng mới trống ở phía dưới một cách chính xác. Để tránh các vấn đề với crontab, bạn thường kết thúc tệp crontab bằng một dòng mới trống. Và tập lệnh ở trên đảm bảo trước tiên nó xóa bất kỳ dòng trống nào bằng "grep." một phần, và sau đó thêm vào một dòng trống mới ở cuối với "\ n" ở cuối tập lệnh. Điều này cũng sẽ ngăn không cho một dòng trống phía trên lệnh mới của bạn nếu tệp crontab hiện tại của bạn kết thúc bằng một dòng trống.



0

Không, không có tùy chọn trong crontab để sửa đổi các tệp cron.

Bạn phải: lấy tệp cron hiện tại (crontab -l> newfile), thay đổi nó và đặt tệp mới vào vị trí (crontab newfile).

Nếu bạn quen thuộc với perl, bạn có thể sử dụng mô-đun này Cấu hình :: Crontab .

LLP, Andrea


0

chức năng kịch bản để thêm cronjobs. kiểm tra các mục trùng lặp, biểu thức có thể sử dụng *> "

cronjob_creator () {         
# usage: cronjob_creator '<interval>' '<command>'

  if [[ -z $1 ]] ;then
    printf " no interval specified\n"
elif [[ -z $2 ]] ;then
    printf " no command specified\n"
else
    CRONIN="/tmp/cti_tmp"
    crontab -l | grep -vw "$1 $2" > "$CRONIN"
    echo "$1 $2" >> $CRONIN
    crontab "$CRONIN"
    rm $CRONIN
fi
}

thử nghiệm :

$ ./cronjob_creator.sh '*/10 * * * *' 'echo "this is a test" > export_file'
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

nguồn: bộ não của tôi;)


-5

Bạn có thể thay đổi trình chỉnh sửa mặc định thành ed và sử dụng một di sản để chỉnh sửa.

EDITOR=ed
export EDITOR

crontab -e << EOF
> a
> * * * * * Myscript
> * * * * * AnotherScript
> * * * * * MoreScript
> .
> w
> q
> EOF

Lưu ý hàng đầu > trong mã đó có nghĩa là phím return / enter được nhấn để tạo một dòng mới.

Các một phương tiện Nối để nó không làm bất cứ điều gì ghi đè.

Các . có nghĩa là bạn đã chỉnh sửa xong.

Các w có nghĩa là VIẾT những thay đổi.

Các q phương tiện QUIT hoặc thoát ed.

bạn có thể kiểm tra nó

crontab -l

Bạn có thể xóa một mục quá.

EDITOR=ed
export EDITOR

crontab -e << EOF
> /Myscript/
> d
> .
> w
> q
> EOF

Điều đó sẽ xóa mục crontab với Myscript trong đó.

Các d phương tiện xóa mô hình bên trong / / .

Không kiểm tra lại

crontab -l

Giải pháp này hoạt động bên trong một tập lệnh quá ít > tất nhiên :-)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.