Bagaimana membuat CRON menelepon dengan PATH yang benar

124

Saya mencoba membuat cron memanggil dengan PATH yang benar. Ketika saya menjalankan skrip Python dari shell, skrip tersebut berjalan dengan baik karena menggunakan PATH yang ditetapkan di bashrc tetapi ketika saya menggunakan cron semua PATH tidak digunakan dari bashrc. Apakah ada file yang bisa saya masukkan ke PATH untuk cron seperti bashrc atau cara untuk memanggil PATH dari bashrc?

Maaf saya tidak berpikir saya mengucapkan ini dengan benar, saya bisa mendapatkan skrip yang benar untuk dijalankan (artinya PATH ke skrip di crontab bukan masalah di sini), hanya ketika skrip itu berjalan saya menjalankan build dan ini menggunakan PATH diatur .bashrc. Ketika saya menjalankan skrip saat saya masuk, .bashrcPATH ditarik masuk. Karena cron tidak berjalan di shell per mengatakan itu tidak menarik .bashrc. Apakah ada cara untuk menarik ini tanpa harus menulis pembungkus skrip bash?

chrissygormley.dll
sumber
lihat juga saran yang diberikan di sini untuk cara membuat pengaturan bashrc berfungsi untuk cronjobs: stackoverflow.com/q/15557777/1025391
moooeeeep
2
Perintah ajaib, sederhana dan benar untuk memasukkan profil Anda ke dalam lingkungan saat ini adalah source /etc/profile, ia harus makan .bashrcdan banyak hal lain yang berpotensi hilang untuk Anda. Sumber profil eksplisit menjadi sangat berguna jika Anda ingin beberapa skrip berjalan "mandiri", itu juga melindungi dari lingkungan yang aneh dan sebagainya ...
exa
1
@exa +100 Ini membuat shskrip yang dipanggil oleh crontab berfungsi. Anda dapat mengonfirmasikannya memperbarui jalur dengan menambahkan pekerjaan seperti * * * * * echo $PATH > ~/crontab_path.txtdan memeriksa file setelah satu menit.
geotheory

Jawaban:

177

Saya dulu /etc/crontab. Saya menggunakan vidan memasukkan PATH yang saya butuhkan ke dalam file ini dan menjalankannya sebagai root. Crontab normal menimpa PATH yang telah Anda siapkan. Tutorial yang bagus tentang cara melakukan ini .

File cron di seluruh sistem terlihat seperti ini:

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
chrissygormley.dll
sumber
17
Ini berfungsi dengan crontab -e di tingkat pengguna dan lebih aman juga.
Robert Brisita
2
Bisakah saya menggunakan bash sebagai pengganti sh?
qed
1
aneh (bagi saya) bahwa PATH default yang disetel di / etc / crontab seperti yang ditunjukkan oleh @chrissygormley, dan juga disetel di crontab (Ubuntu) saya, berbeda dari jalur di / etc / environment, khususnya itu menempatkan / sbin dan / bin di depan / usr / sbin dan / usr / bin. Sekarang saya telah mengubahnya di / etc / crontab saya agar sama dengan lingkungan pengguna.
scoobydoo
Tidak bekerja untuk saya .. Saya mengeluarkan konten cron ke sebuah file. Cron berjalan, membuat file tetapi tidak memasukkan konten apa pun di dalamnya.
Volatil3
2
Tampaknya tidak semua jalur yang disetel /etc/crontabtersedia untuk cron saat dijalankan sebagai root di Ubuntu 14.04. ( sudo crontab -e)
David Oliver
50

Kemungkinan besar, cron berjalan di lingkungan yang sangat jarang. Periksa variabel lingkungan yang digunakan cron dengan menambahkan pekerjaan tiruan yang akan dibuang envke file seperti ini:

* * * * * env > env_dump.txt

Bandingkan dengan keluaran env sesi shell normal.

Anda dapat menambahkan variabel lingkungan Anda sendiri ke crontab lokal dengan menentukannya di bagian atas crontab Anda.

Berikut perbaikan cepat untuk menambahkan $PATHcrontab saat ini:

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

Crontab yang dihasilkan akan terlihat mirip dengan jawaban chrissygormley, dengan PATH yang ditentukan sebelum aturan crontab.

joemaller
sumber
22

Anda harus meletakkan jalur lengkap di file crontab. Itu pilihan teraman.
Jika Anda tidak ingin melakukan itu, Anda dapat meletakkan skrip pembungkus di sekitar program Anda, dan mengatur PATH di sana.

misalnya

01 01 * * * command

menjadi:

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

Juga apa pun yang dipanggil dari cronharus sangat berhati-hati tentang program yang dijalankannya, dan mungkin mengatur pilihannya sendiri untuk PATHvariabel.

EDIT:

Jika Anda tidak tahu di mana perintah yang ingin Anda jalankan which <command> dari shell Anda dan itu akan memberi tahu Anda jalannya.

EDIT2:

Jadi, setelah program Anda berjalan, hal pertama yang harus dilakukan adalah mengatur PATHdan variabel lain yang diperlukan (misalnya LD_LIBRARY_PATH) ke nilai yang diperlukan untuk menjalankan skrip.
Pada dasarnya, alih-alih memikirkan cara memodifikasi lingkungan cron agar lebih sesuai untuk program / skrip Anda - buat skrip Anda menangani lingkungan yang diberikan, dengan menyetel yang sesuai saat dimulai.

Douglas Leeder
sumber
1
jika di jalur Anda gunakan 'perintah yang mana' dan itu akan memberi Anda jalur lengkap
Paul Whelan
@ Douglas Leeder - Saat Anda mengatakan letakkan jalur lengkap ke dalam cron, apakah maksud Anda memasukkannya ke crontab atau file lain? Jika ini adalah bagaimana Anda melakukannya jika perintah cron adalah: '01 01 * * * command '. Terima kasih
chrissygormley
@chrissygormley - Ya crontab.
Douglas Leeder
Maaf pasti ada kebingungan. Saya telah mengubah pertanyaan di atas.
chrissygormley
16

Mengatur PATH tepat sebelum baris perintah di crontab saya berfungsi untuk saya:

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing
myrho
sumber
lebih suka cara ini. atau tentukan jalur lengkap skrip.
zw963
5
Saya tidak berpikir jalurnya akan terus berkembang, setiap kali jalannya akan menjadi lingkungan baru, dengan salinan baru PATH ...
jjcf89
Dapat mengonfirmasi bahwa @ jjcf89 benar, PATH selalu baru setiap kali dijalankan.
electrovir
14

Menambahkan definisi PATH ke crontab pengguna dengan nilai yang benar akan membantu ... Saya telah mengisi milik saya hanya dengan:

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

Dan itu cukup untuk membuat semua skrip saya berfungsi ... Sertakan jalur khusus apa pun di sana jika Anda perlu.

Treviño
sumber
1
Untuk pengguna crontab ini harus menjadi jawaban yang benar. Tidak semua orang di sistem dapat mengedit /etc/crontab. Ini adalah jawaban termudah di tingkat pengguna. Kerja bagus @ Treviño. Beri suara jika Anda setuju.
frederickjh
14

Buat variabel Anda bekerja untuk Anda, ini akan memungkinkan akses t

Tentukan PATH Anda di /etc/profile.d/*.sh

Variabel lingkungan seluruh sistem

File dengan ekstensi .sh di direktori /etc/profile.d dieksekusi setiap kali shell login bash dimasukkan (misalnya saat login dari konsol atau melalui ssh), serta oleh DisplayManager saat sesi desktop dimuat.

Anda dapat misalnya membuat file /etc/profile.d/myenvvars.sh dan mengatur variabel seperti ini:

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

Jalankan crontab dengan opsi login!

CRONTAB menjalankan skrip atau perintah dengan Variabel Lingkungan

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
Artistan
sumber
11

Masalah

Skrip Anda berfungsi saat Anda menjalankannya dari konsol tetapi gagal di cron.

Sebab

Crontab Anda tidak memiliki variabel jalur yang benar (dan mungkin shell)

Larutan

Tambahkan shell Anda saat ini dan letakkan crontab

Script untuk melakukannya untuk Anda

#!/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

Sumber

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

Output Sampel

add_curent_shell_and_path_to_crontab.sh contoh keluaran

brakertech.dll
sumber
3

Di AIX cron saya mengambil variabel lingkungannya dari / etc / environment mengabaikan apa yang diatur dalam .profile.

Sunting: Saya juga memeriksa beberapa kotak Linux dari berbagai usia dan ini tampaknya memiliki file ini juga, jadi ini sepertinya bukan khusus AIX.

Saya memeriksa ini menggunakan saran cron joemaller dan memeriksa output sebelum dan sesudah mengedit variabel PATH di / etc / environment.

Van Amburg
sumber
3

Jika Anda tidak ingin melakukan pengeditan yang sama di berbagai tempat, lakukan ini secara kasar:

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

Itu. space dan kemudian path ke .bashrc dan perintah && adalah keajaiban di sana untuk mengubah lingkungan Anda ke dalam bash shell yang sedang berjalan. Juga, jika Anda benar-benar ingin cangkang menjadi bash, ada baiknya untuk memiliki garis di crontab Anda:

SHELL=/bin/bash

Semoga bisa membantu seseorang!

Wade Chandler
sumber
2

Lingkungan default untuk pekerjaan cron sangat jarang dan mungkin sangat berbeda dari lingkungan tempat Anda mengembangkan skrip python. Untuk skrip yang mungkin dijalankan di cron, lingkungan apa pun yang Anda andalkan harus disetel secara eksplisit. Di file cron itu sendiri, sertakan path lengkap ke file executable python dan ke skrip python Anda.

massa
sumber
2

Saya tahu ini sudah dijawab, tetapi saya pikir ini akan berguna bagi sebagian orang. Saya memiliki masalah serupa yang baru saja saya selesaikan ( ditemukan di sini ) dan berikut adalah sorotan dari langkah-langkah yang saya ambil untuk menjawab pertanyaan ini:

  1. pastikan bahwa Anda memiliki variabel yang Anda butuhkan di PYTHONPATH (ditemukan di sini dan di sini dan untuk info lebih lanjut di sini) di dalam .profile atau .bash_profile untuk shell apa pun yang Anda inginkan untuk menguji skrip Anda untuk memastikannya berfungsi.

  2. edit crontab Anda untuk memasukkan direktori yang diperlukan untuk menjalankan skrip Anda dalam pekerjaan cron (ditemukan di sini dan di sini)

    a) pastikan untuk menyertakan direktori root dalam variabel PATH (.) seperti yang dijelaskan di sini (pada dasarnya jika Anda menjalankan executable dengan perintah Anda, ia harus dapat menemukan root atau direktori tempat penyimpanan yang dapat dieksekusi) dan mungkin ini (/ sbin: / bin: / usr / sbin: / usr / bin)

  3. di file crontab Anda, buat cronjob yang akan mengubah direktori ke direktori di mana Anda telah berhasil menjalankan skrip sebelumnya (yaitu Users / user / Documents / foo)

    a) Ini akan terlihat seperti berikut:

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

@Trevino: jawaban Anda membantu saya memecahkan masalah saya. Namun, bagi seorang pemula, coba berikan pendekatan langkah demi langkah.

  1. Dapatkan penginstalan java Anda saat ini melalui $ echo $JAVA_HOME
  2. $ crontab -e
  3. * * * * * echo $PATH- ini memungkinkan Anda memahami apa nilai PATH yang digunakan oleh crontab saat ini. Jalankan crontab dan ambil nilai $ PATH yang digunakan oleh crontab.
  4. Sekarang edit crontab lagi untuk mengatur path bin java yang Anda inginkan: a) crontab -e; b)PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin (ini adalah jalur sampel); c) sekarang pekerjaan / skrip terjadwal Anda seperti */10 * * * * sh runMyJob.sh &; d) keluarkan echo $PATHdari crontab karena tidak diperlukan sekarang.
Ram Dwivedi
sumber
2

Tetapkan PATH yang diperlukan di cron Anda

crontab -e

Edit: Tekan i

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

10 * * * * your_command

Simpan dan keluar :wq

Yogesh Yadav
sumber
1

Solusi paling sederhana yang saya temukan terlihat seperti ini:

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

Contoh ini dipanggil susebagai pengguna root dan memulai shell dengan lingkungan lengkap pengguna, termasuk $ PATH, disetel seolah-olah mereka sedang login. Cara kerjanya sama pada distro yang berbeda, lebih dapat diandalkan daripada mencari .bashrc (yang tidak berfungsi untuk saya) dan menghindari jalur spesifik hardcode yang dapat menjadi masalah jika Anda memberikan contoh atau alat penyiapan dan tidak tahu distro atau tata letak file apa pada sistem pengguna.

Anda juga dapat menentukan nama pengguna setelah sujika Anda menginginkan pengguna yang berbeda dari root, tetapi Anda mungkin harus meninggalkan perintah rootparameter before sukarena ini memastikan sumemiliki hak yang cukup untuk beralih ke pengguna mana pun yang Anda tentukan.


sumber
-3

Jika Anda menggunakan webminmaka ini adalah langkah-langkah cara mengatur PATHnilainya:

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
Peter VARGA
sumber