Etkileşimli düzenleyici olmadan otomatik olarak Bash kullanarak bir cron işi nasıl oluşturulur?


395

Crontab'ın editörü kullanmadan cron işleri oluşturma argümanı var mı (crontab -e). Öyleyse, kod bir Bash betiğinden bir cronjob yaratır mı?



5
Ne yazık ki, buradaki en iyi cevaplar, crontab'ın nasıl değiştirileceğini gösteriyor - makul derecede güvenli olsa da - ama genel olarak yanlış yaklaşım. Daha iyi, daha güvenli ve daha basit bir dosyayı {{cron.d}} içine bırakmak ve daha aşağıya bakarsanız nasıl yapılacağını açıklayan (şu anda) düşük oylu cevaplar vardır.
gregmac

Yanıtlar:


539

Crontab'a aşağıdaki gibi ekleyebilirsiniz:

#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

Cron hattı açıklaması

* * * * * "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)

Kaynak nixCraft .


14
Tempfile veya mktemp kullanmalısınız
Paweł Polewicz

166
(crontab -l; echo "00 09 * * 1-5 eko merhaba") | crontab -
Edo

32
(crontab -l ; echo "00 09 * * 1-5 echo hello") | crontab -- Edo'nun cevabını kopyalamak daha kolay
WBAR

8
Bunu değiştirmek için öneririm ;ile &&eğer durumunda karşı güvenli koruma olarak crontab -lbaşarısız olur. (crontab -l && echo "0 0 0 0 0 some entry") | crontab -
Yani

12
@MacUsers, crontab -lhiçbir crontab yoksa başarısız olur, bu nedenle kullanmak &&komut dosyasının crontab'a ilk girişi eklemesini imkansız hale getirir.
JPhi1618

312

Anında yapabilirsin

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

crontab -lgeçerli crontab işlerini listeler cat, echoyazdırır, yeni komutu yazdırır crontab -ve yazdırılan tüm öğeleri crontab dosyasına ekler. Yeni bir etki yaparak efekti görebilirsiniz crontab -l.


3
teşekkürler, sözdizimini açıklayabilir veya açıklayan bir URL'ye yönlendirebilir misiniz?
siteler

9
crontab -lgeçerli crontab işlerini listeler cat, echoyazdırır, yeni komutu yazdırır crontab -ve yazdırılan tüm öğeleri crontab dosyasına ekler. Yeni bir etki yaparak efekti görebilirsinizcrontab -l
nha

3
Benim için bir tedavi olur. Kullanıcının mevcut bir crontab'ı yoksa no crontab for <username>, yine de çalışır.
fazy

21
Amazon EC2 örneğimde çalışmıyor. Bunun yerine (crontab -l ; echo "00 09 * * 1-5 echo hello") | crontab -çalışır.
Stéphane Bruckert

11
Bu bir UUcatA adayı gibi görünüyor .
ceving

86

Bu kısa dosya geçici dosya gerektirmez, birden fazla eklemeye bağışıktır ve mevcut bir girişin zamanlamasını değiştirmenizi sağlar.

Bunlara sahip olduğunuzu varsayalım:

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

Çoğaltmadan crontab'a eklemek için:

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

Geçerli programı ne olursa olsun onu crontab'dan kaldırmak için:

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

Notlar:

  • grep -F, dizeyi normal bir ifade olarak yorumlamak istemediğimiz için dizeyle tam olarak eşleşir
  • Ayrıca zaman planlamasını yok sayarız ve yalnızca komutu ararız. Bu yoldan; zaman çizelgesi crontab'a yeni bir satır ekleme riski olmadan değiştirilebilir

@moeseth: ayrıntılandırabilir misin?
MoonCactus

bilgisayarınızda denemelisiniz
moeseth

2
@moeseth: Açıkçası bilgisayarımda denedim (linux). Rastgele çalışmayan şeyler
önermem

2
Bu arada, 27 kişi yanlış olamaz (bugün itibariyle). Bu yüzden lütfen kurulumunuz için neden çalışmadığını açıklayın, böylece yardımcı olabiliriz.
MoonCactus

2
OSX sorunu olabilir.
moeseth

40

Yardımlarınız için herkese teşekkürler. Burada ve başka yerlerde bulduğum parçaları bir araya getirerek bununla geldim:

Kod

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

Kendimi tekrar etmeden iki değişkene olan ihtiyacı nasıl ortadan kaldıracağımı anlayamadım.

commandAçıkçası planlamak istediğim komut. zamanlama verilerini jobalır $commandve ekler. Her iki değişken ayrı ayrı iş yapan kod satırında gerekli.

ayrıntılar

  1. Kredi için duckyflip, ben komut için girdi haline dönüştürmek için bu küçük yönlendirme thingy ( <(*command*)) kullanın.crontab -lfgrep
  2. fgrepDaha sonra herhangi eşleşmeleri filtreler $command( -visteğe bağlı), harf duyarsız ( -iseçenek).
  3. Yine, küçük yönlendirme thingy ( <(*command*)) sonucu catkomutu tekrar girişe dönüştürmek için kullanılır .
  4. catKomut ayrıca aldığı echo "$job"yönlendirme zımbırtısıyla kullanımı yoluyla, yine, (kendini açıklamaktadır) ( <(*command*)).
  5. Böylece, filtrelenmiş çıktı crontab -lve basit echo "$job", birleştirilmiş, crontab -nihayetinde yazılacak şekilde ('|') borulanır .
  6. Ve hepsi sonsuza dek mutlu yaşadılar!

Kısaca:

Bu kod satırı, komutla eşleşen tüm cron işlerini filtreler, ardından kalan cron işlerini yenisiyle yazar ve etkin bir şekilde "ekleme" veya "güncelleme" işlevi gibi davranır. Bunu kullanmak için tek yapmanız gereken, commandve jobdeğişkenlerinin değerlerini değiştirmek .


5
Başkalarının okuduğu yarar için, bu yaklaşımın avantajı, crontab'daki yinelenen girişler hakkında endişelenmeden (diğer tüm çözümlerin aksine) birden fazla kez çalıştırabilmenizdir. Bu, çünküfgrep -v
aleemb

5
Geleneksel soldan sağa borulama yöntemini tercih ediyorsanız, son satırı şu şekilde değiştirin: crontab -l | fgrep -i -v "$command" | { cat; echo "$job"; } | crontab -l
Antoine Lizée

1
@ AntoineLizée, cevapta ekstra "l" var, ki orada olmamalı.
Henry

26

EDIT (sabit üstüne yazma):

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

Bu, herhangi bir crontab içeriğinin yerini alacak
TheBonsai

1
@ TheBonsai oh Anlıyorum, şimdi düzelttim, bu yüzden mevcut crontab içeriğine yeni komutu
EKLEMELİ

3
Bash'in işlem değişikliğinin hataları yuttuğunu unutmayın. Eğer crontab -lbaşarısız, ama crontab -başarılı, sizin crontab tek astar olacaktır.
ceving

13

Crontab kullanımı konusunda birçok iyi cevap vardı, ancak kullanmak gibi daha basit bir yöntemden bahsetmedik cron.

Kullanmak , veya cronadresinde bulunan sistem dosyalarından ve dizinlerden yararlanır :/etc/crontab/etc/cron.daily,weekly,hourly/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

Yukarıdaki örnekte, içinde bir dosya oluşturduk /etc/cron.d/, komutun başarıyla yürütülmesi için ortam değişkenlerini sağladık userve komutu ve commandkendisini sağladık . Bu dosya çalıştırılabilir olmamalı ve ad yalnızca alfasayısal ve kısa çizgiler içermelidir (daha fazla ayrıntı aşağıdadır).

Yine de kapsamlı bir cevap vermek için, crontabvs arasındaki farklara bakalım cron/crond:

crontab -- maintain tables for driving cron for individual users

İşi, kullanıcıları bağlamında sistemde yürütmek isteyenler için, kullanmak crontabmantıklı olabilir.

cron -- daemon to execute scheduled commands

Yapılandırma yönetimini kullananlar veya diğer kullanıcılar için işleri yönetmek isteyenler için, bu durumda kullanmalıyız cron.

Manajlardan hızlı bir alıntı size ne yapıp yapmayacağınıza dair birkaç örnek verir:

/ etc / crontab ve /etc/cron.d içindeki dosyalar root'a ait olmalı ve grup veya diğer yazılabilir olmamalıdır. Biriktirme alanının aksine, /etc/cron.d altındaki dosyalar veya /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly ve /etc/cron.monthly altındaki dosyalar da olabilir. hem bağlantı sembolünün hem de işaret ettiği dosyanın kök sahip olması şartıyla. /Etc/cron.d altındaki dosyaların yürütülebilir olması gerekmezken, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly ve /etc/cron.monthly altındaki dosyalar, bunlar çalışma parçaları tarafından çalıştırılır (daha fazla bilgi için çalışma parçaları (8) 'e bakınız).

Kaynak: http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

Crons'u bu şekilde yönetmek, sistem açısından daha kolay ve ölçeklenebilirdir, ancak her zaman en iyi çözüm olmayacaktır.


1
<job>Bir dosya uzantısı içermemesi gerektiğini belirtmek gerekebilir .
jww

7

Muhtemelen bunu otomatikleştiriyorsunuz ve tek bir işin iki kez eklenmesini istemiyorsunuz. Bu durumda şunları kullanın:

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

Bu yalnızca BASH kullanıyorsanız çalışır. Doğru DASH ( sh) sözdiziminin farkında değilim .

Güncelleme: Kullanıcının henüz bir crontab'ı yoksa bu çalışmaz. Daha güvenilir bir yol:

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

Alternatif olarak, dağıtımınız destekliyorsa, ayrı bir dosya da kullanabilirsiniz:

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

Bunları başka bir SO sorusunda buldum .


Bash yerine sh kullanmak belki?
kvz

Hala shsh: 1: Syntax error: "(" unexpected kullanıyorum .
Batandwa

Bu yalnızca BASH kullanıyorsanız çalışır. Doğru DASH (sh) sözdiziminin farkında değilim. Cevabı da güncelledi
kvz

1
fwiw, <ve arasında bir boşluk varsa bash kullanarak bu hatayı alıyorum (. Bu , programınızda yıldız işareti olmadıkça < (başarısız olur, ancak <(çalışır ...
doublesharp

Bunun doğru yol olduğuna inanıyorum:cat <(crontab -l |grep -v "${CRON}") <(echo "${CRON}") | crontab -
Stanislav

5

Bir crontab'ın güzel bir hızlı ve kirli oluşturulması / bir BASH betiği ile değiştirilmesi için bu gösterimi kullandım:

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

5

Yalnızca istenen dize bulunmazsa crontab'ı düzenleyen bir varyant:

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

3

Vixie Cron kullanıyorsanız, örneğin çoğu Linux dağıtımında, tek tek cronjob ile /etc/cron.d dosyasına bir dosya koyabilirsiniz.

Bu sadece elbette kök için çalışır. Sisteminiz bunu destekliyorsa, burada birkaç örnek görmelisiniz. (Satırdaki kullanıcı adını eski / etc / crontab ile aynı sözdiziminde not edin)

Cron'da bunun normal bir kullanıcı olarak ele alınmasının bir yolu olmadığı ve birçok cron uygulamasının bununla başa çıkmanın hiçbir yolu olmadığı üzücü bir yanlıştır.


2

Yani, Debian, Ubuntu ve benzer birçok Debian tabanlı dağıtımda ...

Bir yapılandırma dosyası alan, bunları bir araya getiren ve çalışan cron hizmetinize ekleyen bir cron görev birleştirme mekanizması vardır.

/Etc/cron.d/somefilename altına bir dosya koyabilirsiniz, burada bazı dosya adı ne istersen.

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

Bunu sökelim:

sudo - / etc dizini altındaki cron yapılandırmalarını değiştirmek için yükseltilmiş ayrıcalıklara ihtiyacınız olduğu için

echo - std çıkışında çıktı oluşturmak için bir araç. printf, kedi ... iyi çalışır

"- dizenizin başında bir çift tırnak kullanın,

0,15,30,45 * * * * - standart cron çalışma programı, bu her 15 dakikada bir çalışır

ntpdate -u time.nist.gov - çalıştırmak istediğim gerçek komut

"- çünkü ilk çift tırnaklarım çıkmakta olan satırı kapatmak için bir arkadaşa ihtiyaç duyuyor

>> - üzerine yazma yerine çift yönlendirme eklenir *

/etc/cron.d/vmclocksync - vmclocksync, seçtiğim dosya adı, /etc/cron.d/


* Yönlendirmeyi> kullansaydık, yalnızca bir görev girdimiz olduğunu garanti edebilirdik. Ancak, varolan bir dosyadaki diğer kuralları ortadan kaldırma riskiyle karşı karşıya kalabiliriz. > İle yıkımın doğru olup olmadığını veya >> ile olası kopyaların sizin için uygun olup olmadığına kendiniz karar verebilirsiniz. Alternatif olarak, dosya adının var olup olmadığını, içinde bir şey olup olmadığını ve herhangi bir kopya ekleyip eklemediğinizi kontrol etmek için kıvrık veya karışmış bir şey yapabilirsiniz - ancak, yapacak işlerim var ve bunu şimdi haklısın.


2

Etkileşimli düzenleyici olmadan cron işi eklemek için Bash betiği. Aşağıdaki kod linux dosyalarını kullanarak bir cronjob eklemenize yardımcı olur.

#!/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
Loooong zamanının geldiğini biliyorum, ama bu hala tek iyi cevap, çünkü en çok oylananlar sadece yeni olanları eklemek yerine eski crons'ları kaldırıyor.
afe

1
Bu bir cron kurmaz. Sadece bir dosyaya ekler. Yeni girişi kurmak için bir şekilde cron işlemini bildirmeniz gerekecektir.
Apoorv Parijat

1

İşte crontabçoğaltma olmadan bir komut eklemek için bir bash işlevi

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}")

"Komut" cronjob ekleyerek -w parametresi olmadan grep tam komutuna -w parametresi ekleyin cron işi "testing123" silinmesine neden olur

cronjobs eklemek / kaldırmak için komut dosyası işlevi. çoğaltma girişi yok:

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"

test edildi:

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

Aynı komut crontab'da iki kez (farklı zamanlarda çalışıyorsa) varsa, kaldır her iki satırı da silecektir.
Michaelkay

1

Bu benim tercih edilen çözüm şu olurdu:

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

Bu, alttaki boş yeni satırı doğru şekilde tuttuğunuzdan emin olacaktır. Crontab ile ilgili sorunları önlemek için crontab dosyasını boş yeni bir satırla sonlandırmalısınız. Ve yukarıdaki komut dosyası önce "grep" ile boş satırları kaldırmasını sağlar. yazın ve sonuna komut dosyasının sonunda "\ n" ile yeni bir boş satır ekleyin. Bu, mevcut crontab dosyanız boş bir satırla bitiyorsa, yeni komutunuzun üzerinde boş bir satır almayı da engeller.


1
echo "0 * * * * docker system prune --force >/dev/null 2>&1" | sudo tee /etc/cron.daily/dockerprune

0

Hayır, crontab'da cron dosyalarını değiştirme seçeneği yoktur.

Yapmanız gereken: geçerli cron dosyasını almak (crontab -l> newfile), değiştirmek ve yeni dosyayı yerine koymak (crontab newfile).

Perl hakkında bilginiz varsa, Config :: Crontab modülünü kullanabilirsiniz .

LLP, Andrea


0

cronjobs eklemek için komut dosyası işlevi. yinelenen girişleri, kullanılabilir ifadeleri kontrol edin *> "

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
}

test edildi:

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

Kaynak: beynim;)


-5

Düzenlemek için varsayılan düzenleyiciyi değiştirebilir ve düzenlemek için bir yorumlu metin kullanabilirsiniz.

EDITOR=ed
export EDITOR

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

Bu koddaki > işaretinin, yeni bir satır oluşturmak için döndür / gir tuşuna basıldığı anlamına geldiğini unutmayın .

A , hiçbir şeyin üzerine yazılmayacak şekilde EKLEME anlamına gelir.

. düzenlemeyi bitirdiğiniz anlamına gelir.

Ağırlık aracı değişiklikleri YAZ.

Q aracı veya exit ed.

kontrol edebilirsin

crontab -l

Bir girişi de silebilirsiniz.

EDITOR=ed
export EDITOR

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

Bu, içindeki Myscript ile crontab girişini silecektir.

D aracı içinde modelini silmek / / .

Hayır tekrar kontrol et

crontab -l

Bu çözüm çok az bir komut dosyası içinde çalışır > tabii :-)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.