Why crontab is deleted when running on 'crontab' or 'crontab -' command with ctrl+D ?
Environment
- Red Hat Enterprise Linux
Issue
crontab
또는crontab -
을 실행한 후 stdin 모드에서 Ctrl+D를 입력하면 기존 crontab이 대체되는 현상.
[test@localhost ~]$ crontab -l
* * * * * echo test
[test@localhost ~]$ crontab
* * * * * /bin/test <----- Type rule and ctrl + D
[test@localhost ~]$ crontab -l
* * * * * /bin/test
[test@localhost ~]$ crontab - <----- Type nothing and ctrl + D
[test@localhost ~]$ crontab -l
[test@localhost ~]$ # // empty
Resolution
- 이는 예상된 동작입니다.
- 수정을 위해서는
crontab -e
사용이 권장됩니다.
Root Cause
- crontab 과 crontab - 는 같은 동작입니다.
- 두 항목 모두 표준 입력(stdin)으로 전달되는 소스 코드에서 자세히 확인할 수 있습니다.
136 int main(int argc, char *argv[]) {
137 int exitstatus;
138 char n[] = "-"; /*set the n string to - so we have a valid string to use */
139 char *nargv[] = { argv[0], n, NULL };
157 /*should we desire to make changes to behavior later. */
158 if (argv[1] == NULL) { /* change behavior to allow crontab to take stdin with no '-' */
159 argv = nargv;
160 }
161 parse_args(argc, argv); /* sets many globals, opens a file */
\_____
\
216 static void parse_args(int argc, char *argv[]) {
351 if (Option == opt_replace) {
352 if (!strcmp(Filename, "-"))
353 NewCrontab = stdin;
Diagnostic Steps
- 만약 crontab에서 "NULL" 또는 "-"로 시작한 뒤 유효한 규칙 없이 Ctrl+D로 종료하면 모든 데이터가 삭제됩니다.
- 또는, 새 규칙을 추가하고 Ctrl+D를 누르면 crontab이 교체됩니다.
$ strace -e write crontab -
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7959, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
write(3, "/var/spool/cron/#tmp.vm1.XXXXWDo"..., 55/var/spool/cron/#tmp.vm1.XXXXWDovV2: Permission denied
) = 55
+++ exited with 1 +++
$ strace -e write crontab
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7970, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
write(3, "/var/spool/cron/#tmp.vm1.XXXXycA"..., 55/var/spool/cron/#tmp.vm1.XXXXycAFIg: Permission denied
) = 55
+++ exited with 1 +++
- 한편, crontab -e 명령은 파일을 연 상태에서 vi 편집기를 사용하게 됩니다.
"/tmp/crontab.hgpHxL"
$ egrep "open|write|rename" a2.out|grep crontab
open("/tmp/crontab.RH8rIt", O_RDWR|O_CREAT|O_EXCL, 0600) = 5
write(2, "crontab: installing new crontab\n", 32) = 32
open("/tmp/crontab.RH8rIt", O_RDWR) = 4
write(2, "crontab: edits left in /tmp/cron"..., 43) = 43
crontab -e
는 임시로/tmp
에 저장한 후 이를/var/spool/cron
으로 이동하지만, 표준 입력(stdin)을 사용하는 경우에는 임시 파일이 바로/var/spool/cron
에 생성됩니다.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments