Crontab'ın kullanacağı ortam değişkenlerini nerede ayarlayabilirim?


266

Her saat başı çalışan bir crontab'ım var. Onu çalıştıran .bash_profilekullanıcı, işi işi terminalden çalıştırdığında değişken bir ortama sahiptir , ancak açıkçası bunlar çalışırken crontab tarafından alınmaz.

Onları yerleştirmeyi denedim .profileve .bashrchala alınmıyorlar. Crontab'ın alabileceği ortam değişkenlerini nereye koyabileceğimi bilen var mı?

Yanıtlar:


88

'Cron' komutunu çalıştırmadan önce ortamı ayarlayan bir kabuk betiği çalıştırın.

Her zaman.

#   @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
#   Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min     Hour    Day     Month   Weekday Command
#-----------------------------------------------------------------------------
0        *       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1        1       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23       1       *       *       1-5     /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2        3       *       *       0       /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21       3       1       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/monthly

~ / Bin / Cron'daki komut dosyalarının tümü, şöyle görünen tek bir komut dosyası olan 'runcron'a bağlanır:

:       "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
#       Commands to be performed by Cron (no debugging options)

#       Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile

base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base

if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi

exec $cmd ${@:+"$@"}

(Eski bir kodlama standardı kullanılarak yazılmıştır - bugünlerde başlangıçta bir # # ''!!

'~ / .Cronfile' profilimde cron tarafından kullanılmak üzere bir varyasyon - titizlikle etkileşimli olmayan ve gürültülü olma uğruna yankılanmıyor. Bunun yerine .profile ve benzerlerini yürütebilirsiniz. (REAL_HOME şeyler ortamımın bir eseri - $ HOME ile aynı olduğunu iddia edebilirsiniz.)

Bu nedenle, bu kod uygun ortamı okur ve sonra ana dizinimden komutun Cron olmayan sürümünü çalıştırır. Örneğin, 'hafta içi' komutum şöyle görünüyor:

:       "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
#       Commands to be done each weekday

# Update ICSCOPE
n.updics

'Günlük' komutu daha basittir:

:       "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
#       Commands to be done daily

# Nothing -- most things are done on weekdays only

exit 0

246

crontab -eKomut satırından çalıştırırken ortam değişkenlerini crontab içinde tanımlayabilirsiniz .

LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h  dom mon dow   command

* * * * * sleep 5s && echo "yo"

Bu özellik yalnızca belirli cron uygulamaları için kullanılabilir. Ubuntu ve Debian şu anda bunların crontab dosyasında (GNU mcron ) bildirilmesine izin veren vixie -cron kullanıyor .

Arch Linux ve RedHat kullanımı Cronie gelmez ortam değişkenleri ilan edilmesi için izin ve cron.log sözdizimi hata verir. Giriş başına geçici çözüm yapılabilir:

# m h  dom mon dow   command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"

58
Kabuktaki gibi değişken ikameyi kullanamayacağınızı unutmayın, bu nedenle PATH = / usr / local / bin: $ PATH gibi bir bildirim tam anlamıyla yorumlanır.
Zac

8
Crontab'daki ortam değişkenlerini RedHat 4.4.7-3 ve cronie-1.4.4-15.el6.x86_64
Bruno Lange

7
Değişkenler yalnızca komut içinde kullanılıyorsa, değişkenleri dışa aktarmanız gerekmez, sadece komutunuzdan önce ekleyin. "* * * * * uyku 5s; LC_ALL = nb_NO.UTF-8 echo $ LC_ALL"
vutran

1
cronie şimdi @bruno'nun dediği gibi crontab'dan birkaç ortam değişkeni hariç tümünü kopyalıyor.
mtd

@BrunoLange paylaşmak için nasıl başardınız pelase olabilir?
Newskooler

145

Bu sorun için bir çözüm daha var:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

Bu durumda, $HOME/.profiledosyanızda tanımlanan tüm ortam değişkenini seçer .

Tabii ki $HOMEde ayarlanmadı, onu tam yolunuzla değiştirmeniz gerekir $HOME.


Cevabı bulmak için çok uğraştıktan sonra bu benim için çalıştı, teşekkürler!
vladimir montealegre

5
$ HOME'dan önceki dönemi terk ettiğimi fark edene kadar bu benim için işe yaramadı. Tam olarak o dönem ne yapar?
flymike

9
Süre "kaynak" komutuna eşdeğerdir: tldp.org/LDP/abs/html/special-chars.html#DOTREF
Jeff W

@PeterLee, bahsedilen herhangi bir şey sizin için çalıştı mı? Bunu, yukarıda belirtilen çözümlerin benim için etkili olmadığı için yazdım. Yukarıda belirtilen çözüm işe yaramazsa, sebebini bulmak için biraz araştırma yapmak zorunda kalacağım. ;-)
Vishal

3
@Vishal Aslında, şimdi benim için çalışıyor. Yapmaya çalışıyordum ve dosyamın cron işi ile çeliştiği source ~/.bashrcortaya çıkıyor .bashrc. .env_setup_rcSadece bir satır ile çok basit bir dosya kullanırsam :, export MY_ENV_VAR=my_env_valaslında çalışır. Yazımı görüntüle: stackoverflow.com/questions/15557777/…
Peter Lee

63

Ayar değişiyor /etc/environmentUbuntu benim için de çalıştı. 12.04 itibariyle, /etc/environmentcron için değişkenler yüklenir.


11
En iyi cevap, sadece yürütmek env >> /etc/environmentve mevcut env değişkenleri artık CRON işlerinde kullanılabilir.
Savageman

6
bu benim için harika çalışıyor. özellikle bir Docker Konteyner içine koşuyorum çünkü, bu yüzden "sistem çapında" etkileri umurumda değil.
Lucas Pottersky

14
@ Füzyon bombalarıyla sinekleri öldürmek gibi bir kurtarıcı, ayrıca beklenmedik davranışların payı da son derece yüksek.
Fran Marzoa

2
DİKKATLİ olun: env >> /etc/environmentortam değişkenlerinden birinde bir karma işareti varsa BAŞARISIZ olur. Uygulamamda sorun giderme konusunda en zor zamanlarım oldu. Bu adımda kısaltılan '#' içeren bir şifre olduğu ortaya çıktı.
asac

3
Seçilen cevap bu olmalıdır. İnsanların neden diğer cevaplarla ya da env >> / etc / çevre ile ilgili şeyleri karmaşık hale getirdiğini bilmiyorum. Bu env değişkenlerinin evrensel olarak kullanılabilir olmasını istiyorsanız, sadece düzenleme vb. / Ortam yanıp sönüyor: deneylerim, / etc / ortamında env vars için dışa aktarma ifadelerinin crontab ve kullanıcılar için kullanılabilir olduğunu doğruladı. SORUN: yine deneylerimden: bu env değişkenlerinin crontab içinde genişlemediği anlaşılıyor! ... yani sadece çağrılan komut dosyalarında genişletildiler!
mike kemirgen

39

Eğer cron üzerinden yürüttüğünüz komut dosyalarını başlatırsanız:

#!/bin/bash -l

~/.bash_profileOrtam değişkenlerinizi almalılar


4
Bu cevap daha fazla oy almalı ve sadece seçilen cevap olmalıdır: Çok basit ve zariftir ve sistemin her yerine atlamayı gerektirecek sayısız çamurdan kaçınır.
JakeGould

Bu yanıtı beğendim +1. Bu root'crontab' ı çalıştırırken kullanılabilir mi? /home/rootSistemimde klasör yok ve bu yüzden bunun rootcrontab ile nasıl çalışacağını göremiyorum . Fikirler?
Seamus

Betiğin kendisinde. Hangi normalde cron ile çalıştırın.
breizhmg

@Jim bu örneğe bakın , klasik yürütülebilir dosya (chmod 777) kullanın #!/bin/bash. Buradaki sihir eklemek-l
Peter Krauss

22

Daha kolay bulduğum @carestad örneğini genişletmek, betiği cron ile çalıştırmak ve betiğin içinde ortam oluşturmaktır.

Crontab -e dosyasında:

SHELL=/bin/bash

*/1 * * * * $HOME/cron_job.sh

Cron_job.sh dosyasında:

#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

.Bash_profile kaynağından sonraki tüm komutlar, giriş yapmış gibi ortamınıza sahip olacaktır.


16

Benim için bir php uygulaması için ortam değişkenini ayarlamak zorunda kaldı. Benim crontab aşağıdaki kodu ekleyerek resloved.

$ sudo  crontab -e

crontab:

ENVIRONMENT_VAR=production

* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php

ve doSomethingWonderful.php içinde çevre değeri ile alabilirim:

<?php     
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"

Umarım bu yardımcı olur!


Bu benim için işe yaramadı. Ortam değişkeni, crontab içinde çağrılan komut dosyasında mevcut değildi.
Nikhil

12

Ayarladığınız her şey crontabdoğrudan ve komut dosyalarındaki değişkenleri kullanarak cronjobs'ta kullanılabilir.

Onları cronjob tanımında kullanın

Daha crontabsonra can cronjob tarafından kullanılacak değişkenleri ayarlayacak şekilde yapılandırabilirsiniz :

$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello

Şimdi dosya /tmp/helloşuna benzer:

$ cat /tmp/hello 
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016

Onları cronjob tarafından çalıştırılan komut dosyasında kullanın

crontabKomut dosyalarının kullanabileceği değişkenleri ayarlayacak şekilde yapılandırabilirsiniz :

$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh

Ve betiğin şöyle olduğunu söyle /tmp/myscript.sh:

echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res

Şunları /tmp/myoutput.resgösteren bir dosya oluşturur :

$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...

7

@Robert Brisita'da genişleme sadece genişledi, ayrıca komut dosyasındaki profilin tüm değişkenlerini ayarlamak istemiyorsanız, komut dosyasının üst kısmına dışa aktarılacak değişkenleri seçebilirsiniz

Crontab -e dosyasında:

SHELL=/bin/bash

*/1 * * * * /Path/to/script/script.sh

Script.sh içinde

#!/bin/bash
export JAVA_HOME=/path/to/jdk

some-other-command

7

Onun yerine

0  *  *  *  *  sh /my/script.sh

Bash -l -c kullanın

0  *  *  *  *  bash -l -c 'sh /my/script.sh'

1
Neden sadece dosyanın üstündeki Bash beyanı kalmadan bu adres yapmak -lböyle: #!/bin/bash -l? Bu diğer cevap basit ve zariftir.
JakeGould

1
Bash değil perl / python / ruby ​​komut dosyasını çalıştırmam gerekirse ne olur? Bir python betiğinin üstüne #! / Bin / bash -l ekleyemiyorum.
Ilya Kharlamov

“Bash değil perl / python / ruby ​​betiği çalıştırmam gerekirse ne olacak?” Yeterince adil. Ama bence daha sonra Python betiğini çağıran basit bir Bash betiği yazabilirsiniz. Ben de PHP betikleri için benzer bir şey yapıyorum. Bunun nedeni, işlem kilitleme'nin Bash'ta çok daha iyi ve güvenilir olmasıdır, ancak Bash betiklemesi hala bir baş ağrısıdır. Bu yüzden karmaşık şeyler için PHP'de bir şeyler yazdım ve gerisini Bash'e bıraktım.
JakeGould

3

Oh-my-zshMacbook'umda kullanıyorum , bu yüzden crontab görevinin çalışmasını sağlamak için birçok şey denedim, ancak sonunda çözümüm .zshrcçalıştırma komutundan önce ekleniyordu .

*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js

Bu görev her 30 dakikada bir çalışır ve .zshrcdüğüm komutumu yürütmek için profili kullanır .

Var'dan önce noktayı kullanmayı unutmayın $HOME.


2

Değişkenleri "enjekte etmenin " bu cevabından esinlenilen başka bir yol da (fcron örneği):

%daily 00 12 \
    set -a; \
    . /path/to/file/containing/vars; \
    set +a; \
    /path/to/script/using/vars

Gönderen help set:

-a Dışa aktarma için değiştirilen veya oluşturulan değişkenleri işaretleyin.

- yerine + kullanılması, bu bayrakların kapatılmasına neden olur.

Yani arasındaki her şey set -ve set +ihraç envve daha sonra diğer komut dosyaları, vb için kullanılabilir set. Değişkenleri kullanmadan kaynak olsun ama setsadece yaşıyor .

Bunun yanı sıra, bir programın root dışı bir hesabın çalıştırılması gerektiğinde değişkenleri iletmek de yararlıdır, ancak diğer kullanıcının ortamında bazı değişkenlere ihtiyacınız olacaktır. Aşağıda, e-posta üstbilgisini biçimlendirmek için nullmailer vars ileten bir örnek verilmiştir:

su -s /bin/bash -c "set -a; \
                    . /path/to/nullmailer-vars; \
                    set +a; \
                    /usr/sbin/logcheck" logcheck

2

Sağlanan çözümlerin çoğunu denedim, ancak ilk başta hiçbir şey işe yaramadı. Yine de, işe yaramayan çözümler olmadığı ortaya çıktı. Görünüşe göre, dosyam ~/.bashrcaşağıdaki kod bloğuyla başlıyor:

case $- in
    *i*) ;;
    *) return;;
esac

Bu temel olarak case statement, kabuğun etkileşimli olarak çalıştığını belirlemek için geçerli kabuktaki geçerli seçenekler kümesini kontrol eden bir alandır. Kabuk etkileşimli çalışıyorsa, ~/.bashrcdosyayı kaynaklamaya devam eder . Ancak, tarafından çağrılan bir kabukta cron,$- değişken içermeyen ietkileşim gösteren değeri. Bu nedenle, ~/.bashrcdosya hiçbir zaman tam olarak kaynaklanmaz. Sonuç olarak, ortam değişkenleri hiçbir zaman ayarlanmadı. Sorununuz bu olursa, kod bloğunu aşağıdaki gibi yorumlamaktan çekinmeyin ve tekrar deneyin:

# case $- in
#     *i*) ;;
#     *) return;;
# esac

Umarım bu faydalı olur


0

Ayrıca envOrtam değişkenlerini şu şekilde enjekte etmek için komutunuzu başa getirebilirsiniz :

0 * * * *   env VARIABLE=VALUE /usr/bin/mycommand
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.