Linux : 재부팅 후 한 번 실행되도록 예약 명령 (RunOnce에 해당)


26

Linux 상자에서 재부팅 한 후 명령이 실행되도록 예약하고 싶습니다. 이 작업을 수행하는 방법을 알고 있으므로 crontab 항목으로 재부팅때마다 명령이 일관되게 실행@reboot 되지만 명령을 한 번만 실행하고 싶습니다. 실행 된 후 실행할 명령 큐에서 제거해야합니다. 본질적으로 Windows 세계에서 RunOnce 와 동등한 Linux를 찾고 있습니다.

중요한 경우 :

$ uname -a
Linux devbox 2.6.27.19-5-default #1 SMP 2009-02-28 04:40:21 +0100 x86_64 x86_64 x86_64 GNU/Linux
$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
$ cat /etc/SuSE-release
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 0

이 작업을 수행하는 쉽고 스크립트 가능한 방법이 있습니까?


1
RunOnce는 재부팅 전에 구성을 완료하는 데 문제가 발생하여 Windows에서 발생하는 아티팩트입니다. 재부팅하기 전에 스크립트를 실행할 수없는 이유가 있습니까? 위의 솔루션은 RunOnce의 합리적인 복제 본인 것 같습니다.
BillThor

답변:


38

@rebootcrontab에 항목을 작성하여 라는 스크립트를 실행하십시오 /usr/local/bin/runonce.

/etc/local/runonce.d/ranusing 이라는 디렉토리 구조를 만듭니다 mkdir -p.

/usr/local/bin/runonce다음과 같이 스크립트 를 작성하십시오 .

#!/bin/sh
for file in /etc/local/runonce.d/*
do
    if [ ! -f "$file" ]
    then
        continue
    fi
    "$file"
    mv "$file" "/etc/local/runonce.d/ran/$file.$(date +%Y%m%dT%H%M%S)"
    logger -t runonce -p local3.info "$file"
done

이제 디렉토리에서 다음에 다시 부팅 (한 번만) 실행하려는 모든 스크립트를 배치 /etc/local/runonce.d하고 chown하고 chmod +x적절하게. 일단 실행되면 ran하위 디렉토리 로 이동 하고 이름에 날짜와 시간이 추가 된 것을 볼 수 있습니다. 에 항목이있을 것 syslog입니다.


2
답변 주셔서 감사합니다. 이 솔루션은 훌륭합니다. 기술적으로 내 문제를 해결하지만이 작업을 수행하는 데 필요한 인프라 준비가 많이있는 것 같습니다. 휴대용이 아닙니다. 귀하의 솔루션이 이상적으로 Linux 배포판에 포함되어 있다고 생각합니다 (왜 그렇지 않은지 잘 모르겠습니다!). 귀하의 답변은 저의 궁극적 인 솔루션에 영감을 주며, 답변으로 게시했습니다. 다시 감사합니다!
Christopher Parker

0에서 7 사이의 다른 시설과 비교하여 local3을 선택한 이유는 무엇입니까?
Christopher Parker

3
@Christopher : 주사위 굴림은 항상 최선의 방법입니다. 그러나 진지하게, 예를 들어 그것은 중요하지 않으며 그것이 내 손가락이 내린 열쇠입니다. 게다가, 나는 8 면체 다이를 가지고 있지 않습니다.
추후 공지가있을 때까지 일시 중지되었습니다.

@Dennis : 감사합니다. 우연히도 local3은에 나타나는 로컬 시설입니다 man logger.
Christopher Parker

않는 $file변수는 전체 경로하거나 파일 이름을 포함?
Andrew Savinykh

21

Dennis Williamson의 답변에 대한 노력에 진심으로 감사드립니다 . 그러나 우아하고 간단하기 때문에이 질문에 대한 답변으로 받아들이고 싶었습니다.

  • 결국 설정하는 데 너무 많은 단계가 필요하다고 느꼈습니다.
  • 루트 액세스가 필요합니다.

그의 솔루션은 Linux 배포판의 기본 기능으로 훌륭하다고 생각합니다.

즉, Dennis의 솔루션과 거의 동일한 것을 달성하기 위해 자체 스크립트를 작성했습니다. 추가 설정 단계가 필요 없으며 루트 액세스가 필요하지 않습니다.

#!/bin/bash

if [[ $# -eq 0 ]]; then
    echo "Schedules a command to be run after the next reboot."
    echo "Usage: $(basename $0) <command>"
    echo "       $(basename $0) -p <path> <command>"
    echo "       $(basename $0) -r <command>"
else
    REMOVE=0
    COMMAND=${!#}
    SCRIPTPATH=$PATH

    while getopts ":r:p:" optionName; do
        case "$optionName" in
            r) REMOVE=1; COMMAND=$OPTARG;;
            p) SCRIPTPATH=$OPTARG;;
        esac
    done

    SCRIPT="${HOME}/.$(basename $0)_$(echo $COMMAND | sed 's/[^a-zA-Z0-9_]/_/g')"

    if [[ ! -f $SCRIPT ]]; then
        echo "PATH=$SCRIPTPATH" >> $SCRIPT
        echo "cd $(pwd)"        >> $SCRIPT
        echo "logger -t $(basename $0) -p local3.info \"COMMAND=$COMMAND ; USER=\$(whoami) ($(logname)) ; PWD=$(pwd) ; PATH=\$PATH\"" >> $SCRIPT
        echo "$COMMAND | logger -t $(basename $0) -p local3.info" >> $SCRIPT
        echo "$0 -r \"$(echo $COMMAND | sed 's/\"/\\\"/g')\""     >> $SCRIPT
        chmod +x $SCRIPT
    fi

    CRONTAB="${HOME}/.$(basename $0)_temp_crontab_$RANDOM"
    ENTRY="@reboot $SCRIPT"

    echo "$(crontab -l 2>/dev/null)" | grep -v "$ENTRY" | grep -v "^# DO NOT EDIT THIS FILE - edit the master and reinstall.$" | grep -v "^# ([^ ]* installed on [^)]*)$" | grep -v "^# (Cron version [^$]*\$[^$]*\$)$" > $CRONTAB

    if [[ $REMOVE -eq 0 ]]; then
        echo "$ENTRY" >> $CRONTAB
    fi

    crontab $CRONTAB
    rm $CRONTAB

    if [[ $REMOVE -ne 0 ]]; then
        rm $SCRIPT
    fi
fi

이 스크립트를 저장 (예 : runonce), chmod +x및 실행 :

$ runonce foo
$ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)"

오타가 발생하면 -r 플래그를 사용하여 runonce 큐에서 명령을 제거 할 수 있습니다.

$ runonce fop
$ runonce -r fop
$ runonce foo

sudo를 사용하면 예상대로 작동합니다. 다음에 재부팅 한 후 서버를 한 번만 시작하는 데 유용합니다.

myuser@myhost:/home/myuser$ sudo runonce foo
myuser@myhost:/home/myuser$ sudo crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/root/.runonce_temp_crontab_10478 installed on Wed Jun  9 16:56:00 2010)
# (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $)
@reboot /root/.runonce_foo
myuser@myhost:/home/myuser$ sudo cat /root/.runonce_foo
PATH=/usr/sbin:/bin:/usr/bin:/sbin
cd /home/myuser
foo
/home/myuser/bin/runonce -r "foo"

몇 가지 참고 사항 :

  • 이 스크립트는 호출 된 환경 (PATH, 작업 디렉토리, 사용자)을 복제합니다.
  • 기본적으로 다음 부팅 순서가 끝날 때까지 "지금 바로"실행되는 명령 실행을 기본적으로 연기하도록 설계되었습니다.

스크립트가 정말 편리해 보입니다. 한가지 주목할 점은 crontab에서 주석을 파괴적으로 제거한다는 것입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

@ 데니스 : 감사합니다. 나는 원래 거기에 추가적인 grep 호출을하지 않았지만 모든 의견이 쌓여있었습니다. 스크립트를 실행할 때마다 3 자동 생성 된 3 개의 주석처럼 보이는 주석 줄을 항상 제거하도록 스크립트를 변경한다고 생각합니다.
Christopher Parker

@ 데니스 : 완료. 패턴이 더 나을 수도 있지만 나에게 효과적입니다.
Christopher Parker

@Dennis : 실제로 crontab.c를 기반으로 내 패턴이 괜찮다고 생각합니다. ( opensource.apple.com/source/cron/cron-35/crontab/crontab.c 에서 "이 파일을 편집하지 마십시오"검색 )
Christopher Parker

5

예를 들어 /root/runonce.sh:

#!/bin/bash
#your command here
sed -i '/runonce.sh/d' /etc/rc.local

추가 /etc/rc.local:

/root/runonce.sh

이것은 순수한 천재입니다. /root/runonce.sh를 chmod + x하는 것을 잊지 마십시오. walinuxagent가 dpkg를 차단하기 때문에 중단되는 푸른 컴퓨터에서 apt-get 업그레이드에 적합
CarComp

이것은 너무 해키입니다 (처음에는 내가 생각해 낸 것이기도 함).
iBug

2

S99를 사용하여 /etc/rc5.d에 스크립트를 설정하고 실행 후 자체 스크립트를 삭제하십시오.


2

당신은이 작업을 수행 할 수 있습니다 at내가 알 수 있지만, 명령 할 수 있습니다 사용하지 않는 (I가 시험 RHEL 5에서 적어도) at @reboot또는 at reboot, 그러나 당신이 사용할 수있는 at now + 2 minutes다음과 shutdown -r now.

시스템을 실행하는 데 2 ​​분 이상 걸리지 않아도됩니다.

'runonce'명령이 표준 키트가되기를 원하지만 0 설정을 원하는 경우 유용 할 수 있습니다.


시스템 atd이 중지 될 때까지 시스템이 2 분 이상 걸리면 시스템 종료 중에 명령이 실행될 수 있습니다. atd명령을 무시한 atd now다음 다시 부팅 하기 전에 중지하여이를 피할 수 있습니다 .
mleu

2

이 답변 이 가장 우아 하다고 생각 합니다 .

/etc/init.d/script마지막 줄에 스크립트를 넣고 자동 삭제하십시오.rm $0

스크립트가 100 % 실패 방지가 아닌 한 치명적인 오류 루프를 피하기 위해 예외를 처리하는 것이 좋습니다.


2

내가 사용하는 chkconfig자동 스크립트를 한 번 부팅 후에 결코 다시 실행 내 시스템을 가지고. 시스템이 ckconfig (Fedora, RedHat, CentOs 등)를 사용하는 경우 작동합니다.

먼저 스크립트 :

#!/bin/bash
# chkconfig: 345 99 10
# description: This script is designed to run once and then never again.
#


##
# Beginning of your custom one-time commands
#

plymouth-set-default-theme charge -R
dracut -f

#
# End of your custom one-time commands
##


##
# This script will run once
# If you would like to run it again.  run 'chkconfig run-once on' then reboot.
#
chkconfig run-once off
chkconfig --del run-once
  1. 스크립트 이름을 run-once
  2. 스크립트를 /etc/init.d/
  3. 스크립트 활성화 chkconfig run-once on
  4. 재부팅

시스템 부팅시 스크립트는 한번만 실행되고 다시는 실행되지 않습니다.

즉, 원하지 않는 한 다시는 없습니다. 언제든지 chkconfig run-once on명령으로 스크립트를 다시 활성화 할 수 있습니다 .

이 솔루션은 시스템에 하나의 파일 만 저장하고 필요한 경우 run-once 명령을 다시 실행할 수 있기 때문에이 솔루션이 마음에 듭니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.