Làm thế nào để có được CRON để gọi đúng PATH


124

Tôi đang cố gắng để có được cron để gọi đúng PATHs. Khi tôi chạy tập lệnh Python từ shell, tập lệnh chạy tốt vì nó sử dụng tập hợp PATH được đặt trong bashrc nhưng khi tôi sử dụng cron thì tất cả các PATH không được sử dụng từ bashrc. Có một tập tin nào tôi có thể nhập PATH vào cho cron như bashrc hay cách gọi PATH từ bashrc không?

Xin lỗi tôi không nghĩ rằng tôi đã nói từ này một cách chính xác, tôi có thể chạy tập lệnh chính xác (nghĩa là PATH cho tập lệnh trong crontab không phải là vấn đề ở đây), đó là khi tập lệnh đó đang chạy tôi chạy một bản dựng và nó sử dụng ĐƯỜNG thiết lập trong .bashrc. Khi tôi chạy tập lệnh khi tôi đăng nhập, .bashrcPATH được kéo vào. Vì cron không chạy trong shell cho biết nó không kéo vào .bashrc. Có cách nào để kéo cái này vào mà không phải viết một trình bao bọc bash script không?


cũng có một cái nhìn về gợi ý được đưa ra ở đây để biết cách để cài đặt bashrc hoạt động cho cronjobs: stackoverflow.com/q/15557777/1025391
moooeeeep

2
Điều kỳ diệu, đơn giản và chính xác để đưa hồ sơ của bạn vào môi trường hiện tại là source /etc/profile, nó nên ăn .bashrcvà rất nhiều thứ có khả năng thiếu khác cho bạn. Tìm nguồn cung cấp hồ sơ rõ ràng trở nên khá hữu ích nếu bạn muốn một số tập lệnh chạy "độc lập", nó cũng bảo vệ khỏi các môi trường kỳ lạ và vì vậy ...
exa

1
@exa +100 Điều này làm cho shcác tập lệnh được gọi bởi crontab hoạt động. Bạn có thể xác nhận nó cập nhật đường dẫn bằng cách thêm một công việc như * * * * * echo $PATH > ~/crontab_path.txtvà kiểm tra tệp sau một phút.
địa lý

Câu trả lời:


177

Tôi đã sử dụng /etc/crontab. Tôi đã sử dụng vivà nhập vào PATHs tôi cần vào tệp này và chạy nó dưới quyền root. Các crontab bình thường ghi đè lên PATH mà bạn đã thiết lập. Một hướng dẫn tốt về cách làm điều này .

Tệp cron toàn hệ thống trông như thế này:

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
Điều này hoạt động với crontab -e ở cấp độ người dùng và nó cũng an toàn hơn theo cách đó.
Robert Brisita

2
Tôi có thể sử dụng bash thay vì sh?
qed

1
Thật lạ (với tôi) rằng PATH mặc định được đặt trong / etc / crontab như được hiển thị bởi @chrissygormley và cũng được đặt trong crontab (Ubuntu) của tôi, khác với đường dẫn trong / etc / môi trường, cụ thể là đặt / sbin và / bin trước / usr / sbin và / usr / bin. Bây giờ tôi đã thay đổi điều này trong / etc / crontab để làm cho nó giống với môi trường người dùng.
scoobydoo

Không làm việc cho tôi..Tôi đang xuất nội dung cron vào một tệp. Cron chạy, tạo tệp nhưng nó không đưa bất kỳ nội dung nào vào đó.
Volatil3

2
Dường như không phải tất cả các đường dẫn được thiết lập /etc/crontabđều có sẵn cho cron khi chạy bằng root trong Ubuntu 14.04. ( sudo crontab -e)
David Oliver

50

Nhiều khả năng, cron đang chạy trong một môi trường rất thưa thớt. Kiểm tra các biến môi trường mà cron đang sử dụng bằng cách nối thêm một công việc giả envđể chuyển sang một tệp như thế này:

* * * * * env > env_dump.txt

So sánh với đầu ra của envtrong một phiên shell thông thường.

Bạn có thể thêm các biến môi trường của riêng bạn vào crontab cục bộ bằng cách xác định chúng ở đầu crontab của bạn.

Đây là một sửa chữa nhanh chóng để thêm vào $PATHcrontab hiện tại:

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

Kết quả crontab sẽ trông tương tự như câu trả lời của chrissygormley, với PATH được xác định trước các quy tắc crontab.


22

Bạn nên đặt đường dẫn đầy đủ trong của bạn crontab. Đó là lựa chọn an toàn nhất.
Nếu bạn không muốn làm điều đó, bạn có thể đặt tập lệnh bao quanh các chương trình của mình và đặt PATH ở đó.

ví dụ

01 01 * * * command

trở thành:

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

Ngoài ra, bất cứ điều gì được gọi từ cronnên rất cẩn thận về các chương trình mà nó chạy và có thể đặt lựa chọn riêng cho PATHbiến.

BIÊN TẬP:

Nếu bạn không biết lệnh mà bạn muốn thực thi which <command>từ trình bao của mình và nó sẽ cho bạn biết đường dẫn.

EDIT2:

Vì vậy, một khi chương trình của bạn đang chạy, điều đầu tiên cần làm là đặt PATHvà bất kỳ biến bắt buộc nào khác (ví dụ LD_LIBRARY_PATH) thành các giá trị được yêu cầu cho tập lệnh chạy.
Về cơ bản thay vì suy nghĩ làm thế nào để sửa đổi môi trường cron để làm cho nó phù hợp hơn với chương trình / tập lệnh của bạn - làm cho tập lệnh của bạn xử lý môi trường mà nó đưa ra, bằng cách đặt một môi trường phù hợp khi nó khởi động.


1
nếu nó trong đường dẫn của bạn sử dụng 'lệnh nào' và nó sẽ cung cấp cho bạn đường dẫn đầy đủ
Paul Whelan

@Doumund Leeder - Khi bạn nói đặt đường dẫn đầy đủ vào cron, bạn có nghĩa là đặt nó vào crontab hoặc tệp khác? Nếu đó là cách bạn sẽ thực hiện điều đó nếu lệnh cron là: '01 01 * * * lệnh '. Cảm ơn
chrissygormley

@chrissygormley - Vâng crontab.
Douglas Leeder

Xin lỗi phải có một số nhầm lẫn. Tôi đã đặt lại câu hỏi ở trên.
chrissygormley

16

Đặt PATH ngay trước khi dòng lệnh trong crontab của tôi hoạt động với tôi:

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

thích cách này hoặc chỉ định đường dẫn đầy đủ của tập lệnh.
zw963

5
Tôi không nghĩ rằng con đường sẽ tiếp tục phát triển, mỗi lần chạy của nó sẽ là một môi trường mới, với một bản sao mới của PATH ...
jjcf89

Có thể xác nhận rằng @ jjcf89 là chính xác, PATH mới trên mỗi lần chạy.
Electrovir

14

Thêm một định nghĩa PATH vào crontab của người dùng với các giá trị chính xác sẽ giúp ... Tôi đã điền vào chỉ với:

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

Và nó đủ để làm cho tất cả các tập lệnh của tôi hoạt động ... Bao gồm bất kỳ đường dẫn tùy chỉnh nào ở đó nếu bạn cần.


1
Đối với người dùng crontab, đây là câu trả lời chính xác. Không phải tất cả mọi người trên một hệ thống có thể chỉnh sửa /etc/crontab. Đây là câu trả lời dễ nhất ở cấp độ người dùng. Làm tốt lắm @ Treviño. Bỏ phiếu này nếu bạn đồng ý.
frederickjh

14

Làm cho các biến của bạn làm việc cho bạn, điều này sẽ cho phép truy cập t

Xác định PATH của bạn trong /etc/profile.d/*.sh

Biến môi trường toàn hệ thống

Các tệp có phần mở rộng .sh trong thư mục /etc/profile.d được thực thi bất cứ khi nào một vỏ đăng nhập bash được nhập (ví dụ: khi đăng nhập từ bảng điều khiển hoặc qua ssh), cũng như bởi DisplayManager khi tải phiên máy tính để bàn.

Ví dụ, bạn có thể tạo tệp /etc/profile.d/myenvvars.sh và đặt các biến như thế này:

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

Thực hiện crontab với tùy chọn đăng nhập!

CRONTAB chạy tập lệnh hoặc lệnh với Biến môi trường

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

Vấn đề

Kịch bản của bạn hoạt động khi bạn chạy nó từ bảng điều khiển nhưng không thành công.

Nguyên nhân

Crontab của bạn không có các biến đường dẫn đúng (và có thể cả vỏ)

Giải pháp

Thêm shell hiện tại của bạn và đường dẫn crontab

Kịch bản để làm điều đó cho bạn

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

Nguồn

https://github.com/ssstonebraker/braker-scripts/blob/master/usiness-scripts/add_cản_shell_and_path_to_crontab.sh

Đầu ra mẫu

đầu ra ví dụ add_curent_shell_and_path_to_crontab.sh


3

Trên cron AIX của tôi chọn ra các biến môi trường từ / etc / môi trường bỏ qua những gì được đặt trong .profile.

Chỉnh sửa: Tôi cũng đã kiểm tra một vài hộp Linux ở nhiều độ tuổi khác nhau và chúng cũng có tệp này, vì vậy đây có thể không phải là AIX cụ thể.

Tôi đã kiểm tra điều này bằng cách sử dụng đề xuất cron của joemaller và kiểm tra đầu ra trước và sau khi chỉnh sửa biến PATH trong / etc / môi trường.


3

Nếu bạn không muốn thực hiện các chỉnh sửa giống nhau ở nhiều nơi, thì hãy thực hiện điều này:

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

Các . không gian và sau đó đường dẫn đến .bashrc và lệnh && là phép màu để biến môi trường của bạn thành vỏ bash đang chạy. Ngoài ra, nếu bạn thực sự muốn shell bị bash, thì nên có một dòng trong crontab của bạn:

SHELL=/bin/bash

Hy vọng nó sẽ giúp được ai đó!


2

Môi trường mặc định cho các công việc cron rất thưa thớt và có thể rất khác với môi trường bạn phát triển các tập lệnh python của bạn. Đối với một tập lệnh có thể chạy trong cron, bất kỳ môi trường nào bạn phụ thuộc đều phải được đặt rõ ràng. Trong chính tệp cron, bao gồm các đường dẫn đầy đủ đến các tệp thực thi python và các tập lệnh python của bạn.


2

Tôi biết điều này đã được trả lời rồi, nhưng tôi nghĩ rằng nó sẽ hữu ích với một số người. Tôi đã có một vấn đề tương tự mà gần đây tôi đã giải quyết ( tìm thấy ở đây ) và đây là những điểm nổi bật của các bước tôi đã thực hiện để trả lời câu hỏi này:

  1. đảm bảo rằng bạn có các biến bạn cần trong PYTHONPATH (tìm thấy ở đây và ở đây và để biết thêm thông tin ở đây) bên trong .profile hoặc .bash_profile cho bất kỳ shell nào bạn muốn kiểm tra tập lệnh của mình để đảm bảo nó hoạt động.

  2. chỉnh sửa crontab của bạn để bao gồm các thư mục cần thiết để chạy tập lệnh của bạn trong công việc định kỳ (tìm thấy ở đây và ở đây)

    a) hãy chắc chắn bao gồm thư mục gốc trong biến PATH (.) như được giải thích ở đây (về cơ bản nếu bạn đang chạy một tệp thực thi với lệnh của mình, nó cần có thể tìm thấy root hoặc thư mục nơi lưu trữ thực thi được lưu trữ) và có thể những thứ này (/ sbin: / bin: / usr / sbin: / usr / bin)

  3. trong tệp crontab của bạn, tạo một cronjob sẽ thay đổi thư mục thành thư mục nơi bạn đã chạy thành công tập lệnh trước đó (ví dụ: Người dùng / người dùng / Tài liệu / foo)

    a) Điều này sẽ trông giống như sau:

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

2

@Trevino: câu trả lời của bạn đã giúp tôi giải quyết vấn đề của mình. Tuy nhiên, đối với một người mới bắt đầu, cố gắng đưa ra một cách tiếp cận từng bước.

  1. Nhận cài đặt java hiện tại của bạn thông qua $ echo $JAVA_HOME
  2. $ crontab -e
  3. * * * * * echo $PATH- điều này cho phép bạn hiểu giá trị PATH đang được sử dụng bởi crontab hiện tại. Chạy crontab và lấy giá trị $ PATH được sử dụng bởi crontab.
  4. Bây giờ chỉnh sửa lại crontab để đặt đường dẫn java bin mong muốn của bạn: a) crontab -e; b) PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin(đó là một đường dẫn mẫu); c) bây giờ công việc / kịch bản theo lịch trình của bạn như thế nào */10 * * * * sh runMyJob.sh &; d) loại bỏ echo $PATHkhỏi crontab vì nó không cần thiết bây giờ.

2

Đặt PATH cần thiết trong cron của bạn

crontab -e

Chỉnh sửa: Nhấn i

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

10 * * * * your_command

Lưu và thoát :wq


1

Cách giải quyết đơn giản nhất mà tôi thấy giống như thế này:

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

Ví dụ này gọi sulà người dùng root và khởi động hệ vỏ với môi trường đầy đủ của người dùng, bao gồm $ PATH, được đặt như thể họ đã đăng nhập. Nó hoạt động giống nhau trên các bản phát hành khác nhau, đáng tin cậy hơn so với tìm nguồn cung ứng .bashrc (không hoạt động cho tôi) và tránh các đường dẫn cụ thể mã hóa cứng có thể là vấn đề nếu bạn đang cung cấp một ví dụ hoặc công cụ thiết lập và không biết bản phân phối hoặc bố cục tệp nào trên hệ thống của người dùng.

Bạn cũng có thể chỉ định tên người dùng sau sunếu bạn muốn một người dùng khác với root, nhưng có lẽ bạn nên để lại roottham số trước sulệnh vì điều này đảm bảo sucó đủ đặc quyền để chuyển sang bất kỳ người dùng nào bạn chỉ định.


-3

Bạn nên sử dụng webminthì đây là các bước để đặt PATHgiá trị:

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
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.