cron의 PATH는 어디에 설정되어 있습니까?


34

Cron은 crontab이 있고 대신 자체 경로를 가진 사용자의 경로를 사용하지 않습니다. PATH=/foo/barcrontab의 시작 부분 에 추가하여 쉽게 변경할 수 있으며 고전적인 해결 방법은 항상 cron이 실행하는 명령에 절대 경로를 사용하는 것이지만 cron의 기본 PATH는 어디에 정의되어 있습니까?

내 아치 시스템 (cronie 1.5.1-1)에서 다음 내용으로 crontab을 만들고 동일한 결과로 Ubuntu 16.04.3 LTS 상자에서도 테스트했습니다.

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

인쇄 :

$ cat fff
/usr/bin:/bin

그런데 왜? 기본 시스템 전체 경로는에 설정되어 /etc/profile있지만 다른 디렉토리가 포함되어 있습니다.

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

의 관련 아무것도 없다 /etc/environment또는 /etc/profile.d나는 아마도 크론 읽을 수 있습니다 생각, 다른 파일은 :

$ 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

의 파일 중 어느 것도 관련이 /etc/skel없으며, 당연히, 어떤 /etc/cron*파일 에도 설정되어 있지 않습니다 .

$ 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

그렇다면 사용자 crontab에 대한 cron의 기본 PATH는 어디에 설정되어 있습니까? cron자체 하드 코딩되어 있습니까? 이것에 대한 일종의 구성 파일을 읽지 않습니까?


3
에 대한 이유가 없다 cron보고하는 /etc/profile특정 쉘에 대해, 또는주의. 하지 않는 이유 더 나은 질문은 cron읽기 PATH에서 login.defs(리눅스) 또는 login.conf(* BSD에). 나는 그것이 궁극적으로 구현 세부 사항이라고 가정합니다.
사토 카츠라

@ SatōKatsura는 필자 가 자체 /etc/profile와 동일한 구문 ( var=value)을 사용하기 때문에 언급 했으므로 내 지식으로는 매우 널리 퍼져 있습니다. 나를 놀라게 한 것은 어디에서나 설정할 수 없어서 하드 코딩 된 것처럼 보입니다. 실제로 스티븐이 아래에서 설명했듯이. cron/etc/profile
terdon

zsh대화 형 쉘로 사용 하는 사람들 은 신경 쓰지 않습니다 /etc/profile(특정 bash)
Basile Starynkevitch

2
@BasileStarynkevitch 아니오, 전혀 배쉬 한정되지 않습니다 ! 꽤 대조적 인 것! 읽지 않은 일부 쉘 (c-shell 패밀리 AFAIK)이 있지만 zsh는 그 중 하나가 아닙니다. 나를 믿지 않으면 zsh 맨 페이지를 참조하십시오. profile어쨌든 다양한 파일은 로그인 쉘에서만 읽으 므로 대화식 쉘은 관련이 없습니다 . 이들은 대화식이거나 대화식이 아닐 수 있습니다.
terdon

1
때로는 strings프로그램에 대해 실행 하면 이러한 하드 코딩 된 값을 찾는 데 도움이 될 수 있습니다.
jrw32982는

답변:


47

소스 코드 에 하드 코딩되어 있습니다 (링크는 현재 데비안을 가리 킵니다 cron. 다양한 cron구현을 고려할 때 하나를 선택하기는 어렵지만 다른 구현은 비슷할 것입니다).

#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

cron구성 파일에서 기본 경로를 읽지 않습니다. PATH=cronjob에서 이미 사용중인 경로 지정을 지원한다는 이유가 있기 때문에 다른 곳에서 기본값을 지정할 필요가 없습니다. ( 작업 항목에 경로를 지정하지 않은 경우 하드 코딩 된 기본값이 사용 됩니다 .)


_PATH_DEFPATH_ROOT정의 의 존재에도 불구하고 Debian Stretch에서 echo $PATH > /testfile루트의 crontab을 편집 한 후 crontab -e루트의 crontab에서도 _PATH_DEFPATH``/ usr / bin : / bin "이 아닌``/ usr / bin : / bin"을 사용한다는 것을 확인했습니다 _PATH_DEFPATH_ROOT . 이것은 또한이 답변의 두 번째 소스 코드 링크 (확인 _PATH_DEFPATH_ROOT되지 않은)로 확인됩니다. 이 고아 정의가 버그인지 확실하지 않습니다.
njahnke

8

Stephen Kitt의 대답에 덧붙여 PATH우분투에서 cron으로 설정하는 구성 파일이 있으며 하드 코딩 된 기본값 (또는 crontabs 자체에서 설정) 을 사용하는 것을 cron 무시 합니다 . 파일은 입니다. 참고 PAM 구성 :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
...

이것은 쉽게 확인할 수 있습니다. 에 변수 추가 /etc/environment말하자면, foo=bar실행 env > /tmp/foocronjob에와 시계 등으로 foo=bar출력의 쇼를 위로.


그런데 왜? 기본 시스템 전체 경로는 / etc / profile에 설정되어 있지만 다른 디렉토리가 포함되어 있습니다.

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

아치 리눅스에서는 사실이지만 우분투에서는베이스 PATH가로 설정되어 /etc/environment있습니다. /etc/profile.d기존 파일에 고정 된 파일을 PATH추가 할 수 있습니다 ~/.pam_environment. 나는이 아치의 행동에 대해 제기 버그 .

불행히도에서 /etc/pam.d/cron읽은 내용은 포함되지 않습니다 ~/.pam_environment. 이상하게, /etc/pam.d/atd 않습니다 그 파일을 포함한다 :

$ 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

...하지만 명령을 통해 실행 at하면 분명히 at작업을 만들 때 사용 가능한 환경이 상속됩니다 (예 env -i /usr/bin/at ...: 매우 깨끗한 환경에서 작업을 실행하는 것 같습니다).

개정 /etc/pam.d/cron하도록하는 것은 user_readenv=1에서 아무런 문제, 변수의 원인이없는 것 같다 ~/.pam_environment(제외 게재 시작 벌금을 PATH물론,).


cron에 대한 환경 변수를 설정하는 것은 지저분한 일처럼 보입니다. cron이 어떤 상속 된 환경 변수를 알지 못하기 때문에 (소스를 읽지 않고) 무시할 수있는 최선의 장소는 작업 스펙 자체에있는 것 같습니다.


at작업과 관련하여 작업을 덤프하면 at작업을 만들 때 환경과 일치하도록 환경을 명시 적으로 설정하는 것을 볼 수 있습니다.
Stephen Kitt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.