프로그래밍 방식으로(Ssh를 통해) crontab에 일부 콘텐츠 추가

프로그래밍 방식으로(Ssh를 통해) crontab에 일부 콘텐츠 추가

배포 스크립트가 있습니다. 사용자에게 무언가를 추가해야 합니다 crontab (로그를 정리하는 스크립트를 트리거함).트리플 엑스일) 그러나 이 작업은 초기 배포 중에 또는 업데이트가 필요한 경우에만 수행할 수 있습니다.

(나는 달리 xxx.py deploy env거나 xxx.py update env.)

그래서 나는 이렇게 해야 합니다:

내 cronJob이 이미 존재하는지 확인하세요.
내 cronJob이 아직 존재하지 않으면 제출하세요. 명령 매개변수 중 하나가 다른 경우
내 cronJob을 업데이트하세요.

crontab 파일을 사용 crontab -e하거나 "수동으로" 편집 하지 않고 crontab항목을 추가/확인/제거(다운로드, 다시 작성, 다시 업로드) 하는 방법을 모르겠습니다 .

추신: 이것은 사용자별 cronjob입니다. "webadmin"이 이 작업을 수행하지만 sudo이 작업에 사용되어서는 안 됩니다.

답변1

지금까지 내 최고의 아이디어

먼저 콘텐츠가 있어야 하는 내용과 일치하는지 확인하고, 그렇지 않은 경우 업데이트하세요.

if [[ $(crontab -l | egrep -v "^(#|$)" | grep -q 'some_command'; echo $?) == 1 ]]
then
    set -f
    echo $(crontab -l ; echo '* 1 * * * some_command') | crontab -
    set +f
fi

그러나 이는 크론 작업을 중심으로 별도의 스크립트를 작성해야 할 정도로 복잡해집니다.

다른 아이디어

stdin을 통해 crontab에 문자열을 보낼 수 있습니다(이렇게 하면 이전 crontab 항목이 지워집니다).

echo "* 1 * * * some_command" | crontab -

SSH를 통해서도 제대로 작동합니다.

echo "* 1 * * * some_command" | ssh user@host "crontab -"

파일에 추가하려면 다음을 사용할 수 있습니다.

# on the machine itself
echo "$(echo '* 1 * * * some_command' ; crontab -l 2>&1)" | crontab -
# via ssh
echo "$(echo '* 1 * * * some_command' ; ssh user@host crontab -l 2>&1)" | ssh user@host "crontab -"

답변2

기록을 위해 루트만 여기에서 파일에 쓸 수 있지만 항목은 모든 사용자로 실행되도록 구성할 수 있습니다( 런타임에 /etc/cron.d/있을 필요 없음 ). 이 예에서는 매주 일요일 자정에 사용자로 실행될 sudo작업을 정의합니다 .my_webadmin/usr/local/bin/tidy_logfileswebadmin

echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' >/etc/cron.d/my_webadmin

중요한 부분은 my_webadmin모든 설치 패키지가 여기에 파일을 쓸 수 있고 충돌을 피하고 싶기 때문에 사용자에게 고유해야 한다는 것입니다(실행할 때 반드시 고유할 필요는 없음). 이 고유성 제약 조건을 사용하면 my_webadmin"귀하의 것"이고 다른 사람의 항목이 포함되지 않는다는 것을 알고 간단한 재정의를 통해 업데이트 할 수 있습니다 .

또한 이 접근 방식을 사용하면 cron 항목을 삭제하는 것이 쉬워집니다.

rm -f /etc/cron.d/my_webadmin

귀하의 질문 범위를 벗어나는 것일 수도 있지만 루트 계정에 대한 원격 액세스(또는 를 통해 sudo)가 있는 경우 원격으로 구성할 수도 있습니다.

echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' > ~/webadmin.cron
scp -p ~/webadmin.cron root@remote_host:/etc/cron.d/my_webadmin

또는,

echo '0 0 * * 0 webadmin /usr/local/bin/tidy_logfiles' |
    ssh -q root@remote_host 'cat >/etc/cron.d/my_webadmin'

구성을 삭제하고,

ssh -nq root@remote_host rm -f /etc/cron.d/my_webadmin

scp(암호 기반 로그인을 방지하기 위해 루트 계정이 제한되어 있기 때문에 / 명령에 루트 암호를 제공할 수 없는 경우가 많습니다 ssh. 대신 공개/개인 키 인증서를 설정해야 합니다. 또한 로컬 계정(무엇과 관계없이) 즉) 원격 서버에 대한 전체 루트 액세스 권한을 갖습니다. )

답변3

이 목적을 위해서는 직접 수행하는 것보다 Ansible*을 사용하는 것이 좋습니다. 또는 Puppet 또는 Chef — 그러나 Ansible은 이와 같은 제로 인프라 배포 스크립트에 적합합니다.

이는 이러한 문제를 해결하기 위해 설계된 모듈이 이미 있고 구성 관리 도구가 이미멱등성기본 설계 목표로서 실수로(또는 의도적으로) 다시 실행하더라도 필요할 때만 변경하십시오.

특히 앤서블의예약된 작업 모듈사용자의 crontab을 수정할 수 있습니다. 보너스로 나중에 시스템 crontab을 사용하도록 조정하려는 경우 재작성보다는 매우 간단한 조정만 하면 됩니다.


*면책 조항: 저는 Red Hat에서 일하고 있으며 Ansible은 Red Hat이 후원하는 프로젝트입니다.

답변4

이 적응은 무엇입니까?@phillip-zyan-k-lee-stockmann그의 "아직 최고의 아이디어"를 기반으로 제공된 코드입니다.

그의 (훌륭하고 유용한 조각)에 대한 나의 변경 사항은 기본적으로 다음과 같습니다.

  • 정규식은 명령 이름뿐만 아니라 시간 문자열을 포함한 전체 항목에 대해서도 작동합니다. 이렇게 하면 동일한 이름의 명령이 있거나 다른 항목에 이름이 겹치는 경우에도 명령 추가를 지원할 수 있습니다. (여전히 동일한 일정에 동일한 명령을 두 번 추가하지 않습니다.)
  • 약간의 로깅
  • 여러 가지 이유로 시간별로 이름을 변경했습니다. crontab 구문을 기반으로 쉽게 조정할 수 있습니다.

이것이 내가 말하는 코드입니다 crontab-add-hourly.sh.

#!/bin/bash

# PURPOSE:
# To allow simple, programmatic addition of commands/entries into the crontab (if not already present)

cmd=$1
entry="0 * * * * $cmd"
printf "we want to add this entry:\n$entry\n\n" 
escapedEntry=$(printf '%s\n' "$entry" | sed 's:[][\/.^$*]:\\&:g') #from: https://unix.stackexchange.com/a/129063/320236
printf "but first we'll see if it's already in there using this regex pattern:\n$escapedEntry\n\n"

if [[ $(crontab -l | egrep -v '^(#|$)' | grep -q "$escapedEntry"; echo $?) == 1 ]] # from: https://unix.stackexchange.com/a/297377/320236
then
    printf "all clear; pattern was not already present; adding command to crontab hourly:\n$cmd\n\n"
    (crontab -l ; printf "$entry\n\n") | crontab -
else
    printf "pattern already present; no action taken\n\n"
fi

사용법 및 출력 예:

$ ./crontab-add-hourly.sh my-script.bash

we want to add this entry:
0 * * * * my-script.bash

but first we'll see if it's already in there using this regex pattern:
0 \* \* \* \* my-script\.bash

all clear; pattern was not already present; adding command to crontab hourly:
my-script.bash

관련 정보