CRON'un doğru PATH'ları aramasını sağlama


124

Cron'un doğru PATH'leri aramasını sağlamaya çalışıyorum. Kabuktan bir Python betiği çalıştırdığımda, betik, bashrc'de ayarlanan PATH'leri kullandığından sorunsuz çalışıyor, ancak cron kullandığımda tüm PATH'ler bashrc'den kullanılmıyor. Bashrc gibi cron için PATH'leri girebileceğim bir dosya veya bashrc'den PATH'leri çağırmanın bir yolu var mı?

Maalesef bunu doğru yazdığımı sanmıyorum, çalıştırmak için doğru betiği alabiliyorum (burada sorun crontab'daki betiğe giden PATH değil), sadece o komut dosyası çalışırken bir yapı çalıştırıyorum ve bu PATH'ler ayarlandı .bashrc. Betiği oturum açtığımda çalıştırdığımda, .bashrcPATH'ler içeri çekiliyor. Cron bir kabukta çalışmadığı için içeri çekmiyor .bashrc. Bunu bir bash betiği sarmalayıcısı yazmak zorunda kalmadan almanın bir yolu var mı?


cronjobs için bashrc ayarlarının nasıl çalıştırılacağına dair burada verilen öneriye de bir göz atın: stackoverflow.com/q/15557777/1025391
moooeeeep

2
Profilinizin mevcut ortama dahil edilmesi için sihirli, basit ve doğru komut, sizin için source /etc/profileyemek yemeli .bashrcve diğer birçok potansiyel olarak eksik şeydir. Açık profil kaynak kullanımı, bazı komut dosyalarının "bağımsız" çalışmasını istiyorsanız oldukça yararlı olur, aynı zamanda garip ortamlardan korur ve bu yüzden ...
exa

1
@exa +100 Bu, shcrontab tarafından çağrılan betikleri çalıştırır. * * * * * echo $PATH > ~/crontab_path.txtBir dakika sonra dosya gibi bir iş ekleyerek ve kontrol ederek yolu güncellediğini onaylayabilirsiniz .
geotheory

Yanıtlar:


177

Kullandım /etc/crontab. viİhtiyacım olan PATH'leri kullandım ve bu dosyaya girdim ve root olarak çalıştırdım. Normal crontab, kurduğunuz PATH'lerin üzerine yazar. Bunun nasıl yapılacağına dair iyi bir öğretici .

Sistem genelinde cron dosyası şuna benzer:

This has the username field, as used by /etc/crontab.
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file.
# This file also has a username field, that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user   command
42 6 * * *   root    run-parts --report /etc/cron.daily
47 6 * * 7   root    run-parts --report /etc/cron.weekly
52 6 1 * *   root    run-parts --report /etc/cron.monthly
01 01 * * 1-5 root python /path/to/file.py

17
Bu, kullanıcı düzeyinde crontab -e ile çalışır ve bu şekilde de daha güvenlidir.
Robert Brisita

2
Sh yerine bash kullanabilir miyim?
2013

1
/ etc / crontab içinde @chrissygormley tarafından gösterildiği gibi ve ayrıca benim (Ubuntu) crontab içinde ayarlanan varsayılan PATH ayarının / etc / environment içindeki yoldan farklı olması (bana göre) garip, özellikle / sbin koyuyor ve / usr / sbin ve / usr / bin önündeki / bin. Bunu kullanıcı ortamıyla aynı yapmak için / etc / crontab dosyamda değiştirdim.
scoobydoo

Benim için çalışmıyor ... cron içeriğini bir dosyaya gönderiyorum. Cron çalıştırır, dosya oluşturur ancak içerisine herhangi bir içerik koymaz.
Volatil3

2
Görünüşe göre, /etc/crontabUbuntu 14.04'te root olarak çalışırken, içinde ayarlanan yolların tümü cron için uygun değil. ( sudo crontab -e)
David Oliver

50

Büyük olasılıkla, cron çok seyrek bir ortamda çalışıyor. Cron'un kullandığı ortam değişkenlerini, aşağıdaki envgibi bir dosyaya dökülen bir kukla iş ekleyerek kontrol edin :

* * * * * env > env_dump.txt

Bunu envnormal bir kabuk oturumundaki çıktısı ile karşılaştırın .

Kendi ortam değişkenlerinizi crontab'inizin en üstünde tanımlayarak yerel crontab'a ekleyebilirsiniz.

İşte $PATHmevcut crontab'ın başına eklenecek hızlı bir düzeltme :

# echo PATH=$PATH > tmp.cron
# echo >> tmp.cron
# crontab -l >> tmp.cron
# crontab tmp.cron

Ortaya çıkan crontab, chrissygormley'in cevabına benzer görünecek ve PATH, crontab kurallarından önce tanımlanacaktır.


22

Tam yolları koymalısınız crontab. En güvenli seçenek bu.
Bunu yapmak istemiyorsanız, programlarınızın etrafına bir sarmalayıcı komut dosyası koyabilir ve oradaki PATH'i ayarlayabilirsiniz.

Örneğin

01 01 * * * command

dönüşür:

01 01 * * * /full/path/to/command

Ayrıca den çağrılan her şey cronçalıştırdığı programlar konusunda çok dikkatli olmalı ve muhtemelen PATHdeğişken için kendi seçimini yapmalıdır .

DÜZENLE:

which <command>Kabuğunuzdan çalıştırmak istediğiniz komutun nerede olduğunu bilmiyorsanız, size yolu söyleyecektir.

EDIT2:

Bu nedenle, programınız bir kez çalıştığında, yapması gereken ilk şey , komut dosyasının çalışması için gerekli olan değerlere ayarlamak PATHve diğer gerekli değişkenleri (örneğin LD_LIBRARY_PATH) ayarlamaktır .
Temel olarak, programınıza / betiğinize daha uygun hale getirmek için cron ortamını nasıl değiştireceğinizi düşünmek yerine - başladığında uygun bir ortam ayarlayarak betiğinizin verildiği ortamı işlemesini sağlayın.


1
Eğer yolunuzda 'hangi komutu' kullanırsanız size tam yolu verecektir
Paul Whelan

@Douglas Leeder - Tüm yolları cron'a koy dediğinizde, onu crontab'a mı yoksa başka bir dosyaya mı koymak istiyorsunuz? Eğer cron komutu: '01 01 * * * command 'ise, bunu nasıl yapardınız. Teşekkürler
chrissygormley

@chrissygormley - Evet crontab.
Douglas Leeder

Üzgünüm, biraz karışıklık olmalı. Yukarıdaki soruyu yeniden ifade ettim.
chrissygormley

16

PATH'i crontab'ımdaki komut satırından hemen önce ayarlamak benim için çalıştı:

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing

bu yolu tercih et. veya komut dosyasının tam yolunu belirtin.
zw963

5
Yolun büyümeye devam edeceğini sanmıyorum, her koşusu
PATH'ın

@ Jjcf89'un doğru olduğunu onaylayabilir, PATH her çalıştırmada yenidir.
electrovir

14

Kullanıcı crontab dosyasına doğru değerlerle bir PATH tanımı eklemek yardımcı olacaktır ... Benimkini şu şekilde doldurdum:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Ve tüm komut dosyalarımı çalıştırmam yeterli ... Gerekirse oraya herhangi bir özel yol ekleyin.


1
Bir kullanıcı crontab için bu doğru cevap olmalıdır. Bir sistemdeki herkes düzenleme yapamaz /etc/crontab. Bu, kullanıcı seviyesindeki en kolay cevaptır. İyi iş @ Treviño. Kabul ediyorsanız buna oy verin.
frederickjh

14

Değişkenlerinizin sizin için çalışmasını sağlayın, bu erişime izin verecektir.

YOLUNUZU /etc/profile.d/*.sh içinde tanımlayın

Sistem genelinde ortam değişkenleri

/Etc/profile.d dizinindeki .sh uzantısına sahip dosyalar, bir bash oturum açma kabuğu girildiğinde (örneğin konsoldan veya ssh üzerinden oturum açarken) ve masaüstü oturumu yüklendiğinde DisplayManager tarafından çalıştırılır.

Örneğin /etc/profile.d/myenvvars.sh dosyasını oluşturabilir ve aşağıdaki gibi değişkenleri ayarlayabilirsiniz:

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$JAVA_HOME/bin

Giriş seçeneği ile crontab'ı çalıştırın!

CRONTAB, Ortam Değişkenleri ile komut dosyası veya komut çalıştırır

0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c 'php -f ./download.php'
0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c download.sh

11

Sorun

Komut dosyanız konsoldan çalıştırdığınızda çalışır ancak cron'da başarısız olur.

Sebep olmak

Crontab'ınız doğru yol değişkenlerine (ve muhtemelen kabuk) sahip değil

Çözüm

Mevcut kabuğunuzu ekleyin ve crontab'ı yönlendirin

Bunu sizin için yapacak komut dosyası

#!/bin/bash
#
# Date: August 22, 2013
# Author: Steve Stonebraker
# File: add_current_shell_and_path_to_crontab.sh
# Description: Add current user's shell and path to crontab
# Source: http://brakertech.com/add-current-path-to-crontab
# Github: hhttps://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

# function that is called when the script exits (cleans up our tmp.cron file)
function finish { [ -e "tmp.cron" ] && rm tmp.cron; }

#whenver the script exits call the function "finish"
trap finish EXIT

########################################
# pretty printing functions
function print_status { echo -e "\x1B[01;34m[*]\x1B[0m $1"; }
function print_good { echo -e "\x1B[01;32m[*]\x1B[0m $1"; }
function print_error { echo -e "\x1B[01;31m[*]\x1B[0m $1"; }
function print_notification { echo -e "\x1B[01;33m[*]\x1B[0m $1"; }
function printline { 
  hr=-------------------------------------------------------------------------------------------------------------------------------
  printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"
}
####################################
# print message and exit program
function die { print_error "$1"; exit 1; }

####################################
# user must have at least one job in their crontab
function require_gt1_user_crontab_job {
        crontab -l &> /dev/null
        [ $? -ne 0 ] && die "Script requires you have at least one user crontab job!"
}


####################################
# Add current shell and path to user's crontab
function add_shell_path_to_crontab {
    #print info about what's being added
    print_notification "Current SHELL: ${SHELL}"
    print_notification "Current PATH: ${PATH}"

    #Add current shell and path to crontab
    print_status "Adding current SHELL and PATH to crontab \nold crontab:"

    printline; crontab -l; printline

    #keep old comments but start new crontab file
    crontab -l | grep "^#" > tmp.cron

    #Add our current shell and path to the new crontab file
    echo -e "SHELL=${SHELL}\nPATH=${PATH}\n" >> tmp.cron 

    #Add old crontab entries but ignore comments or any shell or path statements
    crontab -l | grep -v "^#" | grep -v "SHELL" | grep -v "PATH" >> tmp.cron

    #load up the new crontab we just created
    crontab tmp.cron

    #Display new crontab
    print_good "New crontab:"
    printline; crontab -l; printline
}

require_gt1_user_crontab_job
add_shell_path_to_crontab

Kaynak

https://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

Örnek Çıktı

add_curent_shell_and_path_to_crontab.sh örnek çıktı


3

Benim AIX cronumda, çevresel değişkenleri / etc / environment'dan alır ve.

Düzenleme: Ayrıca çeşitli yaşlardaki birkaç Linux kutusunu da kontrol ettim ve bunların da bu dosyaya sahip olduğu görülüyor, bu nedenle bu AIX'e özgü değil.

Bunu joemaller'ın cron önerisini kullanarak ve / etc / environment içindeki PATH değişkenini düzenlemeden önce ve sonra çıktıyı kontrol ettim.


3

Aynı düzenlemeleri çeşitli yerlerde yapmak zorunda kalmak istemiyorsanız, kabaca şunu yapın:

* * * * * . /home/username/.bashrc && yourcommand all of your args

. boşluk ve sonra .bashrc yolu ve && komutu, ortamınızın çalışan bash kabuğuna değişmesini sağlamak için sihirdir. Ayrıca, kabuğun gerçekten bash olmasını istiyorsanız, crontab'ınızda bir satır olması iyi bir fikirdir:

SHELL=/bin/bash

Umarım birine yardımcı olur!


2

Cron işleri için varsayılan ortam çok seyrektir ve python betiklerinizi geliştirdiğiniz ortamdan çok farklı olabilir. Cron'da çalıştırılabilecek bir betik için, bağlı olduğunuz herhangi bir ortam açıkça ayarlanmalıdır. Cron dosyasının kendisinde, python çalıştırılabilir dosyalarına ve python komut dosyalarınıza giden tam yolları ekleyin.


2

Bunun zaten yanıtlandığını biliyorum, ama onun bazılarına faydalı olacağını düşündüm. Yakın zamanda çözdüğüm ( burada bulduğum ) benzer bir sorunla karşılaştım ve işte bu soruyu yanıtlamak için attığım adımların önemli noktaları:

  1. Çalıştığından emin olmak için betiğinizi test etmek istediğiniz herhangi bir kabuk için .profile veya .bash_profile içinde PYTHONPATH'de (burada ve burada ve daha fazla bilgi için burada bulabilirsiniz) ihtiyacınız olan değişkenlere sahip olduğunuzdan emin olun.

  2. crontab dosyanızı bir cron işinde çalıştırmak için gereken dizinleri içerecek şekilde düzenleyin (burada ve burada bulunur)

    a) burada açıklandığı gibi, kök dizini PATH değişkenine (.) dahil ettiğinizden emin olun (temel olarak, komutunuzla bir yürütülebilir dosya çalıştırıyorsanız, kökü veya yürütülebilir dosyanın depolandığı dizini bulabilmesi gerekir) ve muhtemelen bunlar (/ sbin: / bin / usr / sbin / usr / bölme)

  3. crontab dosyanızda, dizini daha önce komut dosyasını başarıyla çalıştırdığınız dizine değiştirecek bir cronjob oluşturun (yani Kullanıcılar / kullanıcı / Belgeler / foo)

    a) Bu, aşağıdaki gibi görünecektir:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    

2

@Trevino: Cevabınız sorunumu çözmeme yardımcı oldu. Bununla birlikte, yeni başlayanlar için adım adım bir yaklaşım vermeye çalışıyor.

  1. Mevcut java kurulumunuzu şu adresten edinin: $ echo $JAVA_HOME
  2. $ crontab -e
  3. * * * * * echo $PATH- bu, şu anda crontab tarafından kullanılan PATH değerinin ne olduğunu anlamanızı sağlar. Crontab'ı çalıştırın ve crontab tarafından kullanılan $ PATH değerini alın.
  4. Şimdi, istediğiniz java bin yolunu ayarlamak için crontab'ı yeniden düzenleyin: a) crontab -e; b) PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin(bu bir örnek yol); c) şimdi planlanan işiniz / komut dosyanız gibi */10 * * * * sh runMyJob.sh &; d) echo $PATHartık gerekli olmadığı için crontab'den kaldırın .

2

Cron'unuzda gerekli PATH'i ayarlayın

crontab -e

Düzenle: Basın i

PATH=/usr/local/bin:/usr/local/:or_whatever

10 * * * * your_command

Kaydet ve çık :wq


1

Bulduğum en basit çözüm şuna benziyor:

* * * * * root su -l -c command

Bu örnek su, kök kullanıcı olarak çağırır ve kabuğu, oturum açmış gibi ayarlanmış $ PATH dahil olmak üzere kullanıcının tam ortamıyla başlatır. Farklı dağıtımlarda aynı şekilde çalışır, .bashrc kaynak sağlamaktan daha güvenilirdir ( me) ve bir örnek veya kurulum aracı sağlıyorsanız ve kullanıcının sisteminde hangi dağıtım veya dosya düzenini bilmiyorsanız sorun olabilecek belirli yolları kodlamaktan kaçınır.

suKökten farklı bir kullanıcı istiyorsanız, sonrasında kullanıcı adını da belirtebilirsiniz , ancak bu , belirttiğiniz herhangi bir kullanıcıya geçiş yapmak için yeterli ayrıcalığa sahip olmasını sağladığından , muhtemelen komuttan rootönce parametreyi bırakmalısınız .susu


-3

Kullanmanız gerekirse webmin, PATHdeğerin nasıl ayarlanacağı şu adımlar :

System
  -> Scheduled Cron Jobs
       -> Create a new environment variable
            -> For user: <Select the user name>
            -> Variable name: PATH
            -> Value: /usr/bin:/bin:<your personal path>
            -> Add environment variable: Before all Cron jobs for user
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.