종료하기 전에 명령을 실행


52

컴퓨터가 종료되기 직전에 간단한 명령을 실행하고 싶습니다 (타이밍은 필수는 아닙니다).

시작을 위해 /etc/rc.local을 사용할 수 있습니다. 종료와 비슷한 것이 있습니까?

메뉴에서 통합 종료 버튼을 계속 사용하고 싶습니다. 즉, 터미널을 통해 종료 할 때마다 사용자 정의 스크립트를 사용하고 싶지 않습니다. 자동이어야합니다.

답변:


42

Linux Mint는 Ubuntu를 기반으로하므로 실행 수준 시스템이 동일하다고 생각합니다. 우분투에서는 다른 런레벨에 대한 스크립트가 /etc/rc[0-6].d디렉토리에 존재하는지에 따라 실행됩니다 . 실행 수준 0은 종료에 해당하고 6은 재부팅에 해당합니다.

일반적으로 스크립트 자체는에 저장되고 /etc/init.d필요한 실행 수준에 해당하는 디렉토리에 심볼릭 링크가 배치됩니다.

따라서 귀하의 경우 스크립트 /etc/init.d/를 작성하고 에 저장 한 다음 스크립트를 가리키는 각각 ( /etc/rc0.d/etc/rc6.d원하는 경우)에 심볼릭 링크를 만듭니다 .

각 런레벨 디렉토리의 스크립트는 우연한 순서 로 실행 되므로 런레벨 내의 순서가 중요한 경우 심볼릭 링크의 이름을 적절히 선택하십시오.


방금 init.d (kubuntu 정확한)의 뼈대 파일을 살펴보고 약간의 위협을 받았습니다. 종료 날짜를 / var / log 아래의 파일에 표시하는 몇 가지 명령을 추가하고 싶습니다. 그냥 그렇게 할 수 있습니까 아니면 골격 파일에서 다른 것들을 처리해야합니까?
Joe

2
@Joe-스크립트를 표준 서비스로 제어 할 수 있기를 원하지 않는 한 대부분의 작업이 필요하지 않습니다. 당신은 당신의 자신의 로그 파일에 간단한 반향으로 아무것도 깨지 않을 것이므로 그것을 시도하고보십시오.
ire_and_curses

1
다음 은 간단한 샘플 init.d 스크립트입니다. 또한 다음을 사용하여 심볼릭 링크를 만드는 것이 더 쉽고 강력합니다.sudo update-rc.d /etc/init.d/myservice defaults
RolfBly

/etc/init.d/spark_shutdown.sh를 작성하고 /etc/rc0.d & /etc/rc6.d에 링크를 만들었습니다. 이제이 스크립트가 우분투 aws ec2 인스턴스에서 실행되었는지 확인하는 방법
Ashish Karpe

10

우분투 변형과 민트가 시스템으로 옮겨 졌으므로 위의 기존 솔루션이 덜 만족 스럽습니다. 웹을 검색하여 systemd로 수행하는 방법을 찾고 다른 사람들의 지혜를 결합 하고 다음 자습서를 포함하는 blogspot.com.au 의 블로그 게시물로 문서화했습니다 .

systemd를 사용하면 아래 템플릿을 사용하여 스크립트를 호출하는 하나 또는 두 개의 파일을 만들고 몇 가지 명령을 실행합니다. 단순한.


GUI 버전

먼저 시작 및 / 또는 종료시 실행할 스크립트를 작성하십시오. .scopening_atstart 및 .scfullcopy_atend를 만들었습니다.

그런 다음 파일을 마우스 오른쪽 버튼으로 클릭하고 속성을 선택하고 권한에서 파일을 프로그램으로 실행 허용을 선택했는지 확인하여 파일이 실행 가능한지 확인하십시오.

내가 만든 두 파일은 램 디스크의 내용을 채우고 저장합니다. 또한 서비스가 작동하고 있음을 증명하기 위해 내 홈 디렉토리에 파일을 만듭니다. 그들은 다음과 같은 형태였습니다.

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

그런 다음 파일 관리자를 루트로 열고 /etc/systemd/system, startup.service 및 save-ramdisk.service 파일을 열어서 만들었습니다. 분명히 자신의 이름을 선택할 수 있으며 일반 이름에는 johns_start.service라는 시작 파일과 johns_shutdown.service라는 종료 파일이 포함될 수 있습니다. 기존 서비스 이름을 선택하지 마십시오.

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

동일한 서비스 파일을 사용하여 내 실행 스크립트의 전체 경로를 대체 할 수 있습니다.

마지막 으로 각각에 대해 systemctl enable your_files_name 명령을 실행하십시오 (그러나 접미사 서비스는 사용하지 않음). 첫 번째는systemctl enable startup

서비스를 시작하려면 컴퓨터를 한 번 재부팅하십시오. 시작 서비스는 systemd가 다중 사용자 대상에 진입 할 때마다 실행되고 다중 사용자 대상이 종료 될 때 중지 서비스가 실행됩니다. 활성화 조건이 다른 대체 서비스 파일에 대해서는 아래에서 설명합니다.


CLI (명령 줄) 버전

이 설명에서는 / home / john이 아닌 홈 디렉토리에서 작업하고 필요에 따라 sudo를 사용하고 vim 또는 svim을 작성하는 편집기를 선택한다고 가정합니다.

첫 번째 줄로 시작 및 종료 쉘 스크립트를 작성#!/bin/sh 하고를 사용하여 실행 가능하게하십시오 chmod +x my_new_filename.

작성 위와 같이 두 개의 파일을, 또는이 예에서, 하나 개의 파일은 시작 및 종료 작업을 처리 할 수 있습니다. 필자는 홈 디렉토리에서 스크립트를 실행하지만 @don_crissti는 Stack Exchange 에서 몇 가지 대안을 보여줍니다 .

vim /etc/systemd/system/start_and_stop.service

파일 내용을 복사하십시오.

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

그런 다음 다음 명령으로 서비스활성화하십시오 .

systemctl enable start_and_stop

서비스가 활성화 된 후 시스템을 재부팅하십시오. 명령 systemctl is-enabled start_and_stopsystemctl is-active start_and_stop사용하여 새 서비스를 모니터링 할 수 있습니다.


종료 트리거 조건 변경

위의 파일은 모두 다중 사용자 환경의 열기 또는 닫기를 사용하여 스크립트 실행을 시작합니다. 아래 파일은 네 가지 잠재적 종료 프로세스의 시작을 사용하여 스크립트를 시작합니다. Before 라인 + WantedBy 라인에서 대상을 추가 또는 제거하면보다 세부적으로 구별 할 수 있습니다.

이 파일은 이 게시물 의 두 번째 답변에서 제안 되었지만 설치 섹션을 추가 할 때까지 실행할 수 없었습니다.

다시 스크립트를 편집하고을 /etc/systemd/service/사용하여 활성화하십시오 systemctl enable your_file_name. 대상을 변경하면 systemclt disable file_name명령을 사용한 다음 대상 디렉토리에 심볼릭 링크 된 명령을 다시 활성화했습니다. 재부팅하면 서비스가 작동합니다.

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target

7

rc.shutdownLinux 커널에는 종료 스크립트 를 사용해야 합니다. OpenBSD 매뉴얼 페이지 인용 :

reboot (8) 또는 halt (8) 명령을 사용하여 시스템을 종료하거나 init (8)에 신호를 보냈거나 키보드 요청 중단이 발행 될 때 (아키텍처가 지원하는 경우) rc ( 8)``종료 ''인수와 함께 호출됩니다.

따라서 rc.shutdown을 열고 실행하려는 쉘 명령을 추가하십시오.

업데이트 : Linux Mint는 다른 시작 / 종료 절차가있는 Ubuntu를 기반으로하므로 다음과 같은 절차가 있습니다.

실행하려는 쉘 스크립트를 작성하고의 관련 디렉토리에 복사하십시오 /etc/rc*.d/. *런레벨에 해당이되는 당신은 스크립트를 실행합니다.
우분투는 데비안 런레벨 넘버링을 따릅니다. 따라서 정지를 위해서는 런레벨 0, 재부팅을 위해서는 런레벨 6이 있습니다.


1

Debian Wheezy, Devuan 및 그 파생물 및 다른 시스템에서 사용되는 SysV 종속성 기반 초기화 시스템의 경우 다음과 같이 rc.shutdown아날로그 의 동작을 모방 할 수 있습니다 rc.local.

다음 스켈레톤에 명령을 추가하십시오 /etc/rc.shutdown.

#!/bin/sh -e
#
# rc.shutdown
#

# <add your commands here, before exit 0>

exit 0

스크립트를 저장하고로 파일을 실행 가능하게 만드십시오 chmod a+x /etc/rc.shutdown.

그런 /etc/init.d/rc.shutdown다음 다음 내용으로 시스템에 새 스크립트 를 추가 하십시오.

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.shutdown
# Required-Start:
# Required-Stop:
# X-Stop-After:      umountroot
# Default-Start:
# Default-Stop:      0 6
# Short-Description: Run /etc/rc.shutdown if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_stop() {
    if [ -x /etc/rc.shutdown ]; then
            [ "$VERBOSE" != no ] && log_begin_msg "Running local shutdown scripts (/etc/rc.shutdown)"
        /etc/rc.shutdown
        ES=$?
        [ "$VERBOSE" != no ] && log_end_msg $ES
        return $ES
    fi
}

case "$1" in
    start)
        # No-op
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop|status)
    do_stop
        exit 0
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

또한이 스크립트를 실행 가능하게 만드십시오.

/etc/rc[06].d에 심볼릭 링크를 만듭니다 :

cd /etc/rc0.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

cd /etc/rc6.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

사용 insserv심볼릭 링크를 수정하고 필요한 .depend.boot, .depend.start 및 .depend.stop 파일을 만들 수 :

insserv -v

위에서 언급 한 모든 명령에 root이거나 sudo를 사용해야합니다.


나는 오늘이 시간으로 약간의 시간을 낭비했으며 우분투 16에서 작동하도록 할 수 없었습니다. 아마 나 였지만 위의 해결책은 즉시 작동했습니다.
마이크 Q
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.