crontab에 다음 명령을 추가하려고 합니다.
I=1; for X in $(/bin/ls -r /var/tmp/*); do [ $((I++)) -le 28 ] && echo "lower" || echo "higher"; done
이 명령은 명령줄(bash)에서 실행할 때 제대로 작동합니다. 하지만 crontab에 해당 줄을 추가하고 실행하면 cron이 다음과 같이 불평합니다.
/bin/sh: 1: arithmetic expression: expecting primary: "I++"
cron에서 다른 구문을 사용해야 합니까?
편집 1:나는 그것을 sh
다음으로 대체했습니다 bash
:/etc/crontab
SHELL=/bin/bash
재부팅했지만 cron
다음 cron 줄이 여전히 실행되지 않습니다.
(I=1; for X in $(/bin/ls -r /var/tmp/*); do [ $((I++)) -le 28 ] && echo "lower" || echo "higher"; done)
/bin/sh
오류는 다음 대신 에 여전히 해석되고 있음을 보여줍니다 /bin/bash
.
/bin/sh: 1: arithmetic expression: expecting primary: "I++"
답변1
내 기억이 정확하다면 Cron의 기본값은 /bin/sh
.check /etc/crontab/
행 입니다 SHELL=
. /bin/sh
( ) 로 설정되었을 가능성이 높습니다 dash
. 나는 당신 이 이것을 SHELL=/bin/bash
당신의 사용자 crontab 파일(에 의해 편집됨 crontab -e
)에서 설정할 수 있다고 믿습니다. 아니면 스크립트를 작성할 수도 있습니다.
답변2
예, 구문을 사용해야 합니다 sh
. Portable Standard sh
Syntax 에 대한 사양을 찾을 수 있습니다.거기.
이 경우 를 원 [ "$((i+=1))" -le 29 ]
하거나 표준 산술 연산자의 전체 세트를 아직 지원하지 않는 sh
이전 버전을 기반으로 하는 경우 를 사용하십시오 .ash
[ "$i" -le 28 ] ...; i=$(($i + 1))
경고: /var/tmp
cron에서 누구나 쓰기 가능한 디렉토리를 다루는 것은 웜 캔을 여는 것만큼 안전합니다.
파일 이름과 해당 유형은 신뢰할 수 없고 매우 지저분한 것으로 취급해야 합니다.
특히 당신의 $(/bin/ls -r /var/tmp/*)
것은 파일 이름에 어떤 문자가 포함될 수 있는지에 대해 많은 가정을 하고 그 중 어느 것도 디렉토리나 디렉토리에 대한 심볼릭 링크가 아니라고 가정하기 때문에 가짜입니다.
답변3
완전히 이식 가능하게 하려면 $() 구문을 다음으로 바꿀 수 있습니다.
I=1; for X in `/bin/ls -r /var/tmp/*`; do [ $I -le 28 ] && echo "lower" || echo "higher"; I=`expr $I + 1`; done
그러나 cron 작업과 전역적으로 쓰기 가능한 디렉토리에는 주의하세요.