이것은 나에게 약간 혼란 스럽습니다.
다음 cronjob을 단독으로 시도할 때:
* * * * * /bin/bash -c "readlink /proc/$$/exe >> /root/printenv"
* * * * * /bin/bash -c "readlink /proc/$PPID/exe >> /root/printenv"
* * * * * /bin/bash -c "readlink /proc/self/exe >> /root/printenv"
* * * * * /bin/bash -c "ps -h -o comm -p $$ >> /root/printenv"
* * * * * /bin/bash -c "echo $SHELL" >> /root/printenv
나는 각각 다음과 같은 결과를 얻습니다.
/bin/dash
/usr/sbin/cron
/bin/readlink
sh
/bin/sh
이렇게 cron에서 호출하면 /bin/bash
어떤 상황에서도 신고 할 수 없는 것 같습니다.
직접 cronjob에서 " "가 해석되고 있음 * * * * * /bin/bash -c "command"
을 어떻게 증명할 수 있습니까 ?command
/bin/bash
나중에 참고할 답변:
큰따옴표를 작은따옴표로 변경하면 올바른 쉘이 반환됩니다.
* * * * * /bin/bash -c 'readlink /proc/$$/exe >> /root/printenv'
로 돌아가:
/bin/bash
아래 답변에 기여한 모든 분들께 감사드립니다.
답변1
이 경우 내 기본 셸은 bash
이며 방금 테스트를 실행했습니다.
sh -c 'echo $0'
결과:sh
sh -c "echo $0"
결과:-bash
bash -c 'echo $0'
결과:bash
bash -c "echo $0"
결과:-bash
'
작은따옴표 뒤에 -c
스위치를 사용해야 하는 것 같습니다.
답변2
모든 명령의 문제점은 잘못된 따옴표를 사용하고 있다는 것입니다. crontab의 각 명령은 쉘에서 처리되는 쉘 코드 조각입니다. crontab 명령 처리 쉘은 SHELL
crontab 파일의 변수 설정을 통해 정의되며 기본값은 /bin/sh
.
/bin/sh
(또는 호환 가능한 쉘)이 스크립트를 실행할 때 /bin/bash -c "readlink /proc/$$/exe >> /root/printenv"
명령줄을 구문 분석한 후 단계 중 하나는 변수 또는 명령 대체를 수행하는 것입니다. 여기에는 변수 대체가 있습니다. 즉, $$
큰따옴표로 묶인 문자열 내부입니다. so를 $$
프로세스의 프로세스 ID로 바꿉니다 /bin/sh
. 프로세스 ID가 1234라고 가정합니다. cron에 의해 호출된 셸은 /bin/bash
인수 -c
와 readlink /proc/1234/exe >> /root/printenv
. 출력은 이것이 /bin/sh
에 대한 심볼릭 링크임을 나타냅니다 /bin/bash
.
큰따옴표 대신 작은따옴표를 사용하는 경우 cron에 의해 호출된 셸은 변수 대체를 수행하지 않고 대신 /bin/bash
인수를 사용 -c
하고 명령을 실행합니다 readlink /proc/$$/exe >> /root/printenv
. 그런 다음 Bash는 명령을 구문 분석하고 $$
이를 자체 프로세스 ID로 대체한 다음 readlink
인수를 사용하여 실행합니다 1234
.
셸에 따라 이 명령의 출력은 셸 바이너리일 수도 있고 아닐 수도 있습니다 /bin/readlink
. 그 이유는 bash(및 기타 여러 셸)에 최적화가 있기 때문입니다. 외부 명령을 사용하면 하위 프로세스에서 명령을 실행하지 않고 대신 셸의 프로세스 이미지를 바꿉니다. (Unix에서의 프로그램 실행은 항상 다음을 통해 수행됩니다.프로세스 이미지를 다른 이미지로 교체;프로그램대개 자신을 복사직전이지만 의무사항은 아닙니다. ) bash는 실행이 readlink
마지막으로 수행해야 하는 작업임을 감지하므로 readlink
동일한 프로세스에서 1234를 실행하므로 readlink /proc/1234/exe
보고서가 /bin/readlink
. 명령을 실행하면 Bash가 이 최적화를 수행합니다.
bash -c 'readlink /proc/$$/exe`
그러나 리디렉션이 있는 경우에는 그렇지 않습니다. 일부 쉘(예: 대시)은 이 최적화를 수행하지 않습니다. ksh와 같은 일부 쉘은 더 똑똑하고 최적화 ksh -c 'readlink /proc/$$/exe >>/root/printenv
하지만 최적화하지는 않습니다 ksh -c 'readlink /proc/$$/exe; true
. (연습: 왜 그것을 최적화하는 것이 불가능합니까?)