'Thư mục làm việc' là gì khi cron thực thi một công việc?


170

Tôi có một kịch bản hoạt động khi tôi chạy nó từ dòng lệnh, nhưng khi tôi lên lịch với nó, crontôi gặp lỗi mà nó không thể tìm thấy tệp hoặc lệnh. Câu hỏi của tôi có hai mặt:

  1. Khi tôi lên lịch cho một công việc định kỳ bằng cách sử dụng crontab -e, nó có sử dụng ID người dùng của tôi làm cơ sở cho các quyền của nó không? Hoặc nó sử dụng ID người dùng cron của một số loại và các quyền liên quan của nó?

  2. Khi một công việc định kỳ được khởi chạy, thư mục làm việc là gì? Đây có phải là thư mục nơi tôi chỉ định tập lệnh để chạy hoặc một thư mục khác không?

Đây là công việc định kỳ của tôi:

15 7 * * * /home/xxxx/Documents/Scripts/email_ip_script.sh

Đây là kịch bản thực tế:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
sed "s/IPADDR/$vIP_ADDR/g" template.txt > emailmsg.txt
ssmtp XXXXX@gmail.com < emailmsg.txt

Dưới đây là các lỗi tôi gặp phải khi xem mailthông báo được tạo bởi cron:

sed: can't read template.txt: No such file or directory
/home/xxxx/Documents/Scripts/email_ip_script.sh: line 15: ssmtp: command not found

Nó không thể tìm thấy template.txtnhưng nó nằm trong cùng thư mục với tập lệnh. Nó cũng không thể chạy ssmtp, nhưng tôi có thể là người dùng của mình. Tôi còn thiếu gì để làm việc này đúng cách?

Câu trả lời:


158

Thêm cd /home/xxxx/Documents/Scripts/nếu bạn muốn công việc của bạn chạy trong thư mục đó. Không có lý do tại sao cron sẽ thay đổi thư mục cụ thể đó. Cron chạy các lệnh của bạn trong thư mục nhà của bạn.

Đối với ssmtp, nó có thể không có trong mặc định của bạn PATH. Đường dẫn mặc định Cron là thực hiện phụ thuộc, vì vậy kiểm tra trang người đàn ông của bạn, nhưng trong tất cả các khả năng ssmtplà trong /usr/sbinđó không có trong mặc định của bạn PATH, chỉ có root.

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
15 7 * * * cd /home/xxxx/Documents/Scripts && ./email_ip_script.sh

@Giles - Cảm ơn, tôi sẽ cronsở hữu nó PATHhay tôi có thể kiểm tra người dùng của mình PATHkhông? Tôi thiết lập ssmtp để sở hữu nó userwheelcho phép nó nghĩ rằng nó sẽ cho phép bất cứ ai sử dụng nó (bao gồm cả cron). Nếu nó giúp Im trên CENTOS 6.2
ProfessionalAm Nghiệp

3
@Prof ProfessionAm Nghiệp Vấn đề của bạn không phải là bạn không được phép sử dụng ssmtp, mà là công việc định kỳ của bạn không tìm thấy bất kỳ lệnh thực thi nào được gọi ssmtpvì nó không nằm trong bạn PATH. Không có những điều như “người dùng của bạn của PATH”; đây là cài đặt theo quy trình, không phải cài đặt theo người dùng. Bạn có thể đặt đường dẫn cho tất cả các công việc định kỳ của mình bằng cách đặt một PATH=…dòng trong crontab của bạn.
Gilles

Tôi đã phải thêm MAILTO='XXXX @ gmail 'để nó hoạt động cùng với thiết lập PATH. Wierd nhưng nó làm việc cho tôi.
mac

Đối với ssmtp người ta có thể sử dụng; ´which ssmtp´ ...
Fredrick Gauss


20

Nếu cronjob của bạn là tập lệnh bash, phần sau sẽ ghi CD vào vị trí tập lệnh của bạn (giả sử rằng bạn đang sử dụng đường dẫn tuyệt đối trong định nghĩa cron của bạn):

cd "$(dirname "$0")";

14

Để trả lời câu hỏi 1: nếu bạn chạy crontab -evới tư cách là người dùng của riêng mình, các công việc sẽ được lên lịch trong crontab của người dùng đó và do đó sẽ chạy với sự cho phép của người dùng đó.

Nhưng bạn cần xem xét rằng các công việc sẽ chạy trong một vỏ không tương tác có nghĩa là $ PATH có thể khác với công việc bạn có khi chạy tập lệnh từ dòng lệnh.

Tốt nhất là luôn luôn sử dụng các đường dẫn đầy đủ trong các tập lệnh, đặc biệt nếu bạn có kế hoạch lên lịch chúng qua / cron, v.v.

Tôi cũng khuyên bạn nên sử dụng đường dẫn đầy đủ đến tất cả các tệp để tránh chính xác các vấn đề bạn thấy.

Để ngăn chặn điều kiện chủng tộc và các vấn đề bảo mật khác, bạn cũng nên sử dụng mktempđể đảm bảo tệp bạn đọc không bị sửa đổi bởi bất kỳ điều gì bên ngoài tập lệnh của bạn.

Vì vậy, tôi sẽ thay đổi tập lệnh thành một cái gì đó như:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
mail_msg=`/bin/mktemp`
/bin/sed "s/IPADDR/$vIP_ADDR/g" /home/xxxx/Documents/Scripts/template.txt > $mailmsg
/path/to/ssmtp XXXXX@gmail.com < $mailmsg
/bin/rm $mailmsg

7

cronchạy mỗi công việc theo lịch trình của người dùng như người dùng đó. Điều này là đủ để chúng tôi tìm ra rằng nó chạy tập lệnh của bạn so với thư mục chính của bạn.

Nếu bạn cần nó để chạy từ một vị trí khác, chỉ cần sử dụng cdtrong tập lệnh của bạn để đi đến vị trí đó.

ssmtpcó lẽ không phải cronlà PATH mặc định (nó được đặt rất hẹp theo thiết kế trên hầu hết các nền tảng). Bạn có thể chỉ định đường dẫn đầy đủ đến ssmtptrong tập lệnh của mình hoặc bạn có thể đặt PATH một cách rõ ràng trong a) tệp crontab của bạn, sẽ có sẵn cho tất cả các tập lệnh của bạn hoặc b) trong mỗi tập lệnh.


3

Kiểm tra chủ đề này làm thế nào bạn có thể dễ dàng tìm ra môi trường của cron, nó ít hơn nhiều so với bạn đã quen trong một vỏ tương tác. Tốt nhất là giả định không có gì được thiết lập và tự đặt nó một cách rõ ràng.


1

cronThông thường, thư mục làm việc để thực hiện công việc là thư mục chính /home/your-user-name.

Thông qua @Kusalananda bình luận tuyệt vời.


1
Không. Nó phụ thuộc vào nơi hệ thống giữ các thư mục nhà. /homelà xa phổ quát.
Kusalananda

1
@Kusalananda Tiêu chuẩn LSB nói /home.
peterh

1
@peterh Vâng, macOS sử dụng /Usersvà sử dụng Unice lịch sử /usr, và thậm chí trên Linux, thư mục chính của người dùng hệ thống cũng có thể ở đâu đó bên dưới /varhoặc ở nơi khác.
Kusalananda

1
@Kusalananda Đúng vậy.
peterh

Cảm ơn, bạn là người duy nhất thực sự trả lời câu hỏi này :)
OwN

0

Một số người đã gợi ý hoặc liên kết với nó nhưng cách tốt nhất để tìm hiểu vì tôi không thể tìm thấy nó trong tài liệu của người đàn ông cho bản phân phối của tôi chỉ là thêm phần này vào một cron

* * * * * echo $PATH > /tmp/lolcronjobs

Trong trường hợp của tôi, Ubuntu mặc định chỉ sử dụng /usr/bin:/bingây ra một vài vấn đề.

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.