Apa 'direktori kerja' ketika cron menjalankan suatu pekerjaan?

170

Saya memiliki skrip yang berfungsi saat saya menjalankannya dari baris perintah, tetapi ketika saya menjadwalkannya dengan cronsaya mendapatkan kesalahan sehingga tidak dapat menemukan file atau perintah. Pertanyaan saya ada dua:

  1. Ketika saya menjadwalkan penggunaan tugas cron crontab -e, apakah ia menggunakan ID pengguna saya sebagai dasar untuk izinnya? Atau apakah ia menggunakan ID pengguna cron dari beberapa jenis dan izin yang terkait?

  2. Ketika pekerjaan cron diluncurkan, apa itu direktori kerja? Apakah ini direktori tempat saya menentukan skrip untuk dijalankan, atau direktori lain?

Inilah pekerjaan cron saya:

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

Berikut ini skrip yang sebenarnya:

vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`"
echo "$vIP_ADDR"
sed "s/IPADDR/$vIP_ADDR/g" template.txt > emailmsg.txt
ssmtp [email protected] < emailmsg.txt

Berikut adalah kesalahan yang saya dapatkan ketika saya melihat mailpesan yang dihasilkan oleh 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

Itu tidak dapat menemukan template.txttetapi itu berada di direktori yang sama dengan skrip. Itu juga tidak bisa berjalan ssmtp, tetapi saya bisa sebagai pengguna saya. Apa yang saya lewatkan agar ini berfungsi dengan baik?

Amatir Profesional
sumber

Jawaban:

158

Tambahkan cd /home/xxxx/Documents/Scripts/jika Anda ingin pekerjaan Anda berjalan di direktori itu. Tidak ada alasan mengapa cron akan berubah ke direktori tertentu. Cron menjalankan perintah Anda di direktori home Anda.

Adapun ssmtp, mungkin tidak dalam standar Anda PATH. Jalur default cron adalah tergantung dari implementasi, jadi halaman manual Anda, tetapi dalam semua kemungkinan ssmtpadalah di /usr/sbinmana tidak di default PATH, hanya 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
Gilles
sumber
@ Giles - Terima kasih, apakah cronitu miliknya sendiri PATHatau dapatkah saya memeriksa pengguna saya PATH? Saya mengatur ssmtp untuk memilikinya sendiri userdan wheelizin berpikir itu akan memungkinkan siapa saja untuk menggunakannya (termasuk cron). Jika ini membantu saya di CENTOS 6.2
ProfessionalAmateur
3
@ProfessionalAmateur Masalah Anda bukan karena Anda tidak diizinkan untuk menggunakan ssmtp, tetapi bahwa pekerjaan cron Anda tidak menemukan executable yang dipanggil ssmtpkarena tidak ada dalam Anda PATH. Tidak ada yang namanya "pengguna Anda PATH"; ini adalah pengaturan per proses, bukan pengaturan per pengguna. Anda dapat mengatur jalur untuk semua pekerjaan cron Anda dengan meletakkan PATH=…garis di crontab Anda.
Gilles
Saya harus menambahkan MAILTO='[email protected] 'juga untuk membuatnya bekerja bersama dengan pengaturan PATH. Wierd tetapi itu berhasil untuk saya.
mac
Untuk ssmtp kita bisa menggunakan; ´which ssmtp´ ...
Fredrick Gauss
@FredrickGauss Jadikan itutype ssmtp
Gilles
20

Jika cronjob Anda adalah skrip bash, yang berikut ini akan CD ke lokasi skrip Anda (dengan asumsi bahwa Anda menggunakan path absolut dalam definisi cron Anda):

cd "$(dirname "$0")";
Hugo
sumber
14

Untuk menjawab pertanyaan 1: jika Anda menjalankan crontab -esebagai pengguna Anda sendiri, pekerjaan akan dijadwalkan di crontab pengguna tersebut dan karenanya akan dijalankan dengan izin dari pengguna tersebut.

Tetapi Anda perlu mempertimbangkan bahwa pekerjaan akan berjalan dalam shell non-interaktif yang berarti bahwa $ PATH mungkin berbeda dari yang Anda miliki saat menjalankan skrip dari baris perintah.

Yang terbaik adalah selalu menggunakan path lengkap dalam skrip, terutama jika Anda berencana untuk menjadwalkannya melalui di / cron dll.

Saya juga merekomendasikan menggunakan path lengkap ke semua file untuk menghindari masalah yang Anda lihat.

Untuk mencegah kondisi ras dan masalah keamanan lainnya, Anda juga harus menggunakan mktempuntuk memastikan file yang Anda baca tidak diubah oleh apa pun di luar skrip Anda.

Jadi saya akan mengubah skrip ke sesuatu seperti:

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 [email protected] < $mailmsg
/bin/rm $mailmsg
Bram
sumber
7

cronmenjalankan pekerjaan terjadwal masing-masing pengguna sebagai pengguna itu. Ini seharusnya cukup bagi kami untuk mengetahui bahwa skrip Anda dijalankan relatif terhadap direktori home Anda.

Jika Anda perlu menjalankannya dari lokasi yang berbeda, cukup gunakan cddi skrip Anda untuk pergi ke lokasi itu.

ssmtpmungkin tidak dalam cronPATH default (ini diatur menjadi sangat sempit dengan desain pada sebagian besar platform). Anda dapat menentukan path lengkap ke ssmtpdalam skrip Anda, atau Anda dapat secara eksplisit mengatur PATH di a) file crontab Anda, yang akan tersedia untuk semua skrip Anda, atau b) di setiap skrip.

D_Bye
sumber
3

Periksa utas ini bagaimana Anda dapat dengan mudah mengetahui lingkungan cron, ini jauh lebih sedikit daripada yang biasa Anda gunakan dalam shell interaktif. Yang terbaik adalah mengasumsikan tidak ada yang ditetapkan dan secara eksplisit mengaturnya sendiri.

jippie
sumber
1

Direktori kerja default untuk cronmenjalankan pekerjaan adalah direktori home, biasanya /home/your-user-name.

Mengadopsi @Kusalananda komentar luar biasa.

Orang Cerdas Membantu Orang Lain
sumber
1
Tidak. Tergantung pada tempat sistem menyimpan direktori home. /homejauh dari universal.
Kusalananda
1
@ Kusalananda Standar LSB mengatakan /home.
peterh
1
@peterh Yah, penggunaan macOS /Usersdan riwayat penggunaan Sejarah /usr, dan bahkan di Linux, direktori home pengguna sistem mungkin berada di suatu tempat di bawah /varatau di tempat lain.
Kusalananda
1
@ Kusalananda Itu benar.
peterh
Terima kasih, Anda satu-satunya orang yang benar-benar menjawab pertanyaan ini :)
OwN
0

Beberapa orang telah mengisyaratkan atau menautkannya tetapi cara terbaik untuk mengetahuinya karena saya tidak dapat menemukannya di man docs untuk distro saya hanya menambahkan ini ke cron

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

Dalam kasus saya, default Ubuntu hanya menggunakan /usr/bin:/binyang menyebabkan beberapa masalah.

mschuett
sumber