Cron'un PATH'i nerede belirlenir?


34

Cron, crontab olduğu kullanıcının yolunu kullanmaz ve bunun yerine kendine has bir yolu vardır. PATH=/foo/barCrontab'ın başına ekleyerek kolayca değiştirilebilir ve klasik geçici çözüm, cron tarafından çalıştırılan komutlara her zaman mutlak yollar kullanmaktır, ancak cron'un varsayılan PATH'i nerede tanımlanır?

Arch sistemimde (cronie 1.5.1-1) aşağıdaki içerikleri içeren bir crontab oluşturdum ve aynı sonuçları içeren bir Ubuntu 16.04.3 LTS kutusunda test ettim:

$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff

Bu yazdırıldı:

$ cat fff
/usr/bin:/bin

Ama neden? Varsayılan sistem genelindeki yol ayarlanır /etc/profile, ancak bu diğer dizinleri içerir:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

İlgili /etc/environmentveya başka hiçbir şey yok /etc/profile.d, muhtemelen cron tarafından okunabileceğini düşündüğüm diğer dosyalar:

$ grep PATH= /etc/profile.d/* /etc/environment
/etc/profile.d/jre.sh:export PATH=${PATH}:/usr/lib/jvm/default/bin
/etc/profile.d/mozilla-common.sh:export MOZ_PLUGIN_PATH="/usr/lib/mozilla/plugins"
/etc/profile.d/perlbin.sh:[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl

Ayrıca, hiçbir dosyada, hiçbir şeyde /etc/skelşaşırtıcı bir şekilde, ne de hiçbir /etc/cron*dosyada ayarlanmış olan hiçbir şey yoktur :

$ grep PATH /etc/cron* /etc/cron*/*
grep: /etc/cron.d: Is a directory
grep: /etc/cron.daily: Is a directory
grep: /etc/cron.hourly: Is a directory
grep: /etc/cron.monthly: Is a directory
grep: /etc/cron.weekly: Is a directory
/etc/cron.d/0hourly:PATH=/sbin:/bin:/usr/sbin:/usr/bin

Peki, cron'un kullanıcı crontab'ları için varsayılan PATH'i nerede belirleniyor? cronKendi içinde kodlanmış mı ? Bunun için bir çeşit yapılandırma dosyasını okumuyor mu?


3
Herhangi bir özel kabuğa cronbakmak /etc/profileveya ilgilenmek için hiçbir sebep yoktur . Daha iyi bir soru neden (Linux'ta) veya (on * BSD) ' dan cronokumuyor . Sanırım sonuçta bu bir uygulama detayı. PATHlogin.defslogin.conf
Satō Katsura

@ SatōKatsura, yalnızca bahsettiğim /etc/profileiçin, kendisiyle aynı sözdizimini ( var=value) kullandığı için cron, bu nedenle, yaptığım kadar kolay ve /etc/profilebildiğim kadarıyla çok yaygın olacaktı. Beni şaşırtan şey, kodlanmış gibi göründüğü için herhangi bir yerde olduğunu bulamadım. Gerçekte olduğu gibi, Stephen aşağıda açıklandığı gibi.
terdon

zshİnteraktif kabukları olarak kullanan insanlar /etc/profile(kendine özgü bash) umrumda değil
Basile Starynkevitch

2
Hayır @BasileStarynkevitch, bash özgü değildir hiç ! Tam tersine! Okumayan bazı mermiler olsa da (c-shell ailesi AFAIK), zsh onlardan biri değil. Bana inanmıyorsan, zsh man sayfasına bakın. Her durumda, etkileşimli mermiler ilgisizdir, çünkü çeşitli profiledosyalar zaten sadece giriş kabukları tarafından okunur. Bunlar etkileşimli olabilir veya olmayabilir.
Terdon

1
Bazen stringsbir programa karşı çalışmak bu kodlanmış değerleri bulmaya da yardımcı olabilir.
jrw32982, Monica

Yanıtlar:


47

Kaynak kodunda kodlanmış ( kodları mevcut Debian'a işaret ediyor cron- cronuygulamaların çeşitliliği göz önüne alındığında, birini seçmek zor, ancak diğer uygulamalar muhtemelen benzer):

#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif

#ifndef _PATH_DEFPATH_ROOT
# define _PATH_DEFPATH_ROOT "/usr/sbin:/usr/bin:/sbin:/bin"
#endif

cronbir yapılandırma dosyasındaki varsayılan yolları okumaz; Akıl yürütmenin, zaten PATH=herhangi bir cronjob'da kullanılan yolları belirlemeyi desteklediğini hayal ediyorum , bu nedenle başka bir yerde varsayılan bir şey belirtmeye gerek kalmadı. (Sabit kodlanmış varsayılan, başka hiçbir şey bir iş girişinde yol belirtmediyse kullanılır .)


Tanımlamanın varlığına rağmen, root'un crontab'ını Debian Stretch üzerinde kullanarak root'un crontab'ını düzenledikten sonra _PATH_DEFPATH_ROOT(cron echo $PATH > /testfilejob'unu kullanarak) onayladığımı , yani "/ usr / bin: / bin" değil . Bu, aynı zamanda bu cevaptaki (kaynak kullanılmayan) ikinci kaynak kod bağlantısı ile de doğrulanır . Artık bu tanımın bir hata olup olmadığı bana belli değil. crontab -e_PATH_DEFPATH_PATH_DEFPATH_ROOT _PATH_DEFPATH_ROOT
njahnke

8

Stephen Kitt'in cevabına ek olarak, PATHUbuntu'da cron için ayarlanan ve sabit kodlanmış varsayılanın (ya da crontab'larda ayarlanan) kullanılacağını cron göz ardı eden bir yapılandırma dosyası var . Dosya . Not PAM yapılandırması:PATHPATH/etc/environmentcron

$ cat /etc/pam.d/cron
...   
# Read environment variables from pam_env's default files, /etc/environment
# and /etc/security/pam_env.conf.
session       required   pam_env.so

# In addition, read system locale information
session       required   pam_env.so envfile=/etc/default/locale
...

Bu kolayca doğrulanabilir. Bir değişken ekleyin /etc/environment, cronjob olarak foo=barçalıştırın ve çıktıda env > /tmp/foogöründüğü şekilde izleyin foo=bar.


Ama neden? Varsayılan sistem çapında yol / etc / profile olarak ayarlanır, ancak diğer dizinleri içerir:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

Bu, Arch Linux'ta doğrudur, ancak Ubuntu'da, üs PATHkurulur /etc/environment. Dosyaları /etc/profile.dvarolan bir çakışmaya sokar PATHve içine ekleyebilirsiniz ~/.pam_environment. Ben Arch davranışları hakkında açılan bir hata .

Ne yazık ki, /etc/pam.d/cronden okumayı içermez ~/.pam_environment. Tuhaftır, /etc/pam.d/atd yaptığı bu dosyayı içerir:

$ cat /etc/pam.d/atd
#
# The PAM configuration file for the at daemon
#

@include common-auth
@include common-account
session    required   pam_loginuid.so
@include common-session-noninteractive
session    required   pam_limits.so
session    required   pam_env.so user_readenv=1

... ancak komutlar, atgörünüşe göre atişi yaratırken mevcut ortamı miras alır (örneğin, env -i /usr/bin/at ...işleri çok temiz bir çevre ile çalıştırıyor gibi).

Değişiklik Yapılması /etc/pam.d/cronolması user_readenv=1halinde herhangi bir sorun ve değişkenleri neden görünmektedir ~/.pam_environment(hariç gelmeye başladı cezası PATHelbette).


Bunların hepsi, cron için ortam değişkenleri belirlemek, dağınık bir iş gibi görünüyor. En iyi yer, iş şartnamesi kendisinde gözüküyor, eğer hangi kalıtsal ortam değişkenlerinin cronun yoksaymaya karar verebileceğini bilmiyorsanız (kaynağı okumadan).


İşlerle ilgili olarak at, bir atişi terk ederseniz, açıkça işin yaratıldığı sırada çevreye uyması için ortamı ayarladığını görürsünüz.
Stephen Kitt
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.