This is Gentoo's testing wiki. It is a non-operational environment and its textual content is outdated.
Please visit our production wiki at https://wiki.gentoo.org
Handbook:PPC64/Working/Initscripts/ko
실행 레벨
시스템 부팅
시스템을 부팅하면 수많은 텍스트가 떠다닙니다. 더 자세히 들여다보면 여러분이 다시 부팅할 때마다 이 텍스트가 같은 내용이 항상 나오는 것을 보실 수 있습니다. 이 동작의 순서를 부트 시퀀스라고 하며, (더 혹은 덜) 정적으로 정의합니다.
먼저 부트로더는 CPU한테 커널을 실행하라고 알린 다음에 부트로더 설정에 지정되어 있는 커널 이미지를 메모리에 불러옵니다. 커널을 불러와서 실행한 후 모든 커널 관련 구조를 초기화하고 init 과정을 시작합니다.
이 프로세스는 (/etc/fstab에 지정한) 모든 파일 시스템을 마운트 했는지 사용할 준비가 되었는지를 확인합니다. 그 다음 시스템을 성공적으로 부팅하기 위해 필요한 서비스를 시작하려고 /etc/init.d의 수 많은 스크립트를 실행합니다.
마지막으로 모든 스크립트를 실행하고 나면, init 에서 터미널(대부분의 경우 Alt+F1, Alt+F2 키로 숨겨놓은 가상 콘솔입니다)을 활성화하고 agetty라고 하는 특별한 프로세스를 터미널에 붙입니다. 이 과정에서 로그인을 실행하여 터미널로 로그온을 할 수 있는지 확인합니다.
Initscripts
여기서 init는 /etc/init.d/에 있는 스크립트를 임의대로 실행하는 것이 아닙니다. 게다가 /etc/init.d/에 있는 모든 스크립트를 실행하는 것도 아니며 실행하라고 지시한 스크립트만 실행합니다. 이는 /etc/runlevels/를 확인하여 어떤 스크립트를 실행할 지 결정합니다.
먼저 init는 /etc/init.d/에서 /etc/runlevels/boot에 심볼릭 링크한 모든 스크립트를 실행합니다. 보통 철자순으로 스크립트를 실행하겠지만 어떤 스크립트의 경우 이들 스크립트를 실행하기 전에 다른 스크립트를 먼저 실행해야 한다고 시스템에 알려주는 의존성 정보를 가지고 있습니다.
/etc/runlevels/boot가 참조하는 스크립트를 실행하고 나면 init는 /etc/runlevels/default에 심볼릭 링크한 스크립트의 실행을 계속합니다. 다시 한 번 말씀드리지만, 어떤 스크립트를 먼저 실행할 지는 유효한 시작 순서를 제공하도록 순서를 바꾸는 의존성 정보를 가지고 있지 않는 한 철자순서를 사용하여 결정합니다. 후자는 왜 젠투리눅스 설치 과정에서 rc-update add sshd default의 default
를 사용하는 지에 대한 답입니다.
init 동작 방식
물론 init 에서 모든 사항을 자체적으로 결정하지 못합니다. 어떤 동작을 취해야 할지 지시하는 설정 파일이 필요합니다. 이 설정 파일은 /etc/inittab입니다.
우리가 적은대로 부팅 순서를 기억한다면, 여러분이 기억하기로는 init에서 처음 하는 동작은 모든 파일 시스템의 마운트입니다. /etc/inittab의 다음 줄에 설정했습니다:
si::sysinit:/sbin/openrc sysinit
This line tells init that it must run /sbin/openrc sysinit to initialize the system. The /sbin/openrc script takes care of the initialization, so one might say that init doesn't do much - it delegates the task of initializing the system to another process.
두번째로, init은 /etc/runlevels/boot에 심볼릭 링크를 걸어둔 모든 스크립트를 실행합니다. 이는 다음의 줄에서 설정했습니다:
rc::bootwait:/sbin/openrc boot
Again the openrc script performs the necessary tasks. Note that the option given to openrc (boot) is the same as the subdirectory of /etc/runlevels/ that is used.
이제 init 는 어떤 실행 레벨을 실행할 지 설정 파일을 확인합니다. /etc/inittab에서 다음 줄을 읽어 들들이고 실행할 실행 레벨을 결정합니다.
id:3:initdefault:
이 경우 (대부분의 젠투 사용자들이 사용할 경우), 실행레벨 id는 3입니다. 이 정보를 사용하여 init 은 실행레벨 3을 시작하기 위해 무엇을 실행해야 하는지 확인합니다:
l0:0:wait:/sbin/openrc shutdown l1:S1:wait:/sbin/openrc single l2:2:wait:/sbin/openrc nonetwork l3:3:wait:/sbin/openrc default l4:4:wait:/sbin/openrc default l5:5:wait:/sbin/openrc default l6:6:wait:/sbin/openrc reboot
The line that defines level 3, again, uses the openrc script to start the services (now with argument default
). Again note that the argument of openrc is the same as the subdirectory from /etc/runlevels/.
When openrc has finished, init decides what virtual consoles it should activate and what commands need to be run at each console:
c1:12345:respawn:/sbin/agetty 38400 tty1 linux c2:12345:respawn:/sbin/agetty 38400 tty2 linux c3:12345:respawn:/sbin/agetty 38400 tty3 linux c4:12345:respawn:/sbin/agetty 38400 tty4 linux c5:12345:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linux
존재하는 실행 레벨
이전 절에서, init에서 어떤 실행 레벨을 활성화 할지 결정하는 숫자 방식을 활용함을 보았습니다. 실행 레벨은 시스템이 실행중인 상태를 나타내며, 실행 레벨에 진입하거나 벗어날때 실행해야 할 여러가지 스크립트(실행 레벨 스크립트 또는 초기화 스크립트)를 가지고 있습니다.
젠투에서는 세가지의 내부 런레벨과 네가지의 사용자 정의 런레벨 즉, 일곱가지 런레벨을 정의했습니다. 내부 런레벨은 sysinit, shutdown, reboot가 있고 이들 이름이 함축하는 일을 정확하게 수행합니다. 시스템을 초기화하고 시스템을 종료하며 시스템을 다시 시작합니다.
사용자 런레벨은 /etc/runlevels의 하위 디렉터리 boot, default, nonetwork, single과 연결됩니다. boot 런레벨은 모든 기타 런레벨에서 사용하려는, 전체 시스템에서 필요한 서비스를 시작합니다. 나머지 세가지 런레벨은 어떤 서비스를 시작하느냐에 따라 차이가 있습니다. default는 항상 실행할 때 사용하고, nonetwork는 네트워크 연결이 필요하지 않을 때 사용하며, single은 시스템을 복구해야 할때 사용합니다.
초기화 스크립트(initscript) 다루기
The scripts that the openrc process starts are called init scripts. Each script in /etc/init.d/ can be executed with the arguments start
, stop
, restart
, zap
, status
, ineed
, iuse
, iwant
, needsme
, usesme
, or wantsme
.
서비스(와 관련 서비스들)를 시작, 중지, 다시 시작하려면 start
, stop
, restart
를 사용해야 합니다:
root #
/etc/init.d/postfix start
주어진 서비스에서 필요한 요건은 중지된 상태나 재시작한 상태입니다. 다른 관련 서비스 (서비스를 사용하지만 필요하지 않은) 는 건드리지 않은 상태로 남아있습니다.
서비스를 중단하고 싶지만 다른 관련 서비스는 그대로 둔다면 --nodeps
매개 변수를 stop
명령과 함께 사용할 수 있습니다.
root #
/etc/init.d/postfix --nodeps stop
서비스의 상태(시작함, 중단함, 멈춤, 등)가 어떤지 보려면 status
인자를 사용하십시오:
root #
/etc/init.d/postfix status
상태 정보에서 서비스가 동작중이라고 알리고 있지만, 실제로 동작중이 아님을 알고 있을 경우 zap
인자를 사용하여 상태 정보를 "중지됨"으로 되돌릴 수 있습니다:
root #
/etc/init.d/postfix zap
또한 관련 서비스가 무엇인지 알아보려면 iuse
나 ineed
를 사용할 수 있습니다. ineed
를 사용하면 서비스가 올바른 기능을 다하는데 실제로 필요한 서비스를 볼 수 있습니다. 반면에 iuse
를 사용하면 서비스에서 사용할 수 있지만 올바른 동작을 하는데 필요하지는 않은 서비스를 보여줍니다.
root #
/etc/init.d/postfix ineed
이와 비슷하게 어떤 서비스를 필요로 하는지(needsme
) 어떤 서비스를 사용할 수 있는지(usesme
) 확인할 수 있습니다:
root #
/etc/init.d/postfix needsme
실행 레벨 업데이트
rc-update
젠투의 init 시스템은 의존 트리를 사용하여 어떤 서비스를 먼저 시작해야 할지 결정 합니다. 사용자 여러분들이 이 지루한 작업을 하지 않도록 실행 레벨과 초기화 스크립트 관리를 쉽게 하는 도구를 만들었습니다.
rc-update를 사용하면 초기화 스크립트를 실행 레벨에 추가하고 제거할 수 있습니다. rc-update 도구는 그 다음 의존 트리를 다시 만들기 위해 depscan.sh를 자동으로 요청합니다.
서비스 추가/삭제
이전 설치과정에서 "default" 실행 레벨에 초기화 스크립트를 추가했습니다. 그 때 여러분은 "default"가 왜 있는지 눈치채지 못하셨겠지만 이제는 알아차리셨을겁니다. rc-update 스크립트는 add
, del
, show
동작 중 하나를 두번째 매개 변수로 필요로 합니다.
초기화 스크립트를 추가하거나 제거하려면 rc-update 스크립트에 add
나 del
매개 변수를 추가하고, 초기화 스크립트 이름과 실행 레벨을 제시하시면 됩니다. 예를 들자면 다음과 같습니다.
root #
rc-update del postfix default
rc-update -v show 명령은 사용할 수 있는 실행할 초기화 스크립트와 실행 레벨의 목록을 보여줍니다.
root #
rc-update -v show
(-v
를 뺀) rc-update show를 실행하여 활성화 한 초기화 스크립트와 실행 레벨만을 보실 수 있습니다.
서비스 설정
왜 추가 설정이 필요한가
초기화 스크립트는 조금 복잡할 수 있습니다. 때문에 오류에 취약하게 만들 수가 있어 사용자가 초기화 스크립트를 올바르게 수정하는게 만족스럽진 않습니다. 그러나 서비스를 설정할 수 있는 방법에 있어서는 중요합니다. 예를 들어 여러분이 서비스 자체에 더 많은 옵션을 주고 싶어할 수도 있습니다.
두번째 이유로는 초기화 스크립트의 외부 설정을 보유하려면, 바꾼 설정을 되돌릴 수 없다는 두려움을 없애고 초기화 스크립트를 업데이트할 수 있어야 하기 때문입니다.
conf.d 디렉터리
젠투에서는 서비스를 설정하는 쉬운 방법을 제공합니다: 모든 초기화 스크립트는 /etc/conf.d의 파일로 설정할 수 있습니다. 예를 들어 apache2 초기화 스크립트(/etc/init.d/apache2)는 Apache 2 서버를 시작할 때 주고 싶은 옵션을 넣을 수 있는 /etc/conf.d/apache2 설정 파일을 지니고 있습니다.
APACHE2_OPTS="-D PHP5"
이런 설정 파일에는 서비스 설정을 쉽게 하는 (/etc/portage.make.conf 같은)변수만 들어있습니다. 변수에 대한 더 자세한 정보도(주석을 통해) 제공해줄 수 있습니다.
initscript 작성
Is it necessary?
아닙니다. 초기화 스크립트 작성은 보통 젠투가 모든 제공하는 서비스에 대해 준비된 초기화 스크립트를 제공하는 만큼 필요하지 않습니다. 그러나 포티지를 사용하지 않는 서비스를 설치할 때가 있는데, 초기화 스크립트의 거의 대부분을 만들 필요가 있습니다.
젠투용으로 확실하게 작성한 것이 아니라면 서비스에서 제공하는 init 스크립트를 사용하지 마십시오. 젠투의 초기화 스크립트는 다른 배포판에서 사용하는 초기화 스크립트와 호환되지 않습니다! 다른 배포판이 OpenRC를 사용하지 않는 한!
배치
초기화 스크립트의 기본 배치는 아래와 같습니다.
#!/sbin/openrc-run depend() { # (Dependency information) } start() { # (Commands necessary to start the service) } stop() { # (Commands necessary to stop the service) }
#!/sbin/openrc-run command=/usr/bin/foo command_args="${foo_args} --bar" pidfile=/var/run/foo.pid name="FooBar Daemon" description="FooBar is a daemon that drinks" extra_started_commands="drink" description_drink="Opens mouth and reflexively swallows" depend() { # (Dependency information) } start_pre() { # (Commands necessary to prepare to start the service) # Ensure that our dirs are correct checkpath --directory --owner foo:foo --mode 0775 \ /var/run/foo /var/cache/foo } stop_post() { # (Commands necessary to clean up after the service) # Clean any spills rm -rf /var/cache/foo/* } drink() { ebegin "Starting to drink" ${command} --drink beer eend $? "Failed to drink any beer :(" }
어떤 초기화 스크립트든지 start()
함수의 정의가 필요합니다. 다른 모든 부분은 부가적인 요소입니다.
의존성
초기화 스크립트의 준비와 순차진행에 영향을 주는 요소가 무엇인지 지정할 수 있는 의존성 유사 방식에는 use
와 need
가 있습니다. 순서에 관계된 메서드에는 before
과 after
가 있습니다. 후자의 두가지 키워드는 그 자체로 의존성을 지니지 않습니다 어떤 스크립트가 시작하도록 계획하지 않았을 때(또는 시작에 실패했을 때) 원 초기화 스크립트의 동작이 실패하지 않도록 합니다.
use
설정은 선택한 스크립트의 기능을 이 스크립트가 사용하지만 직접적인 의존성을 지니지 않도록 init 시스템에 알려줍니다. 좋은 본보기로use logger
나use dns
를 들 수 있습니다. 이 서비스가 존재한다면 사용하기 좋은 상태로 두겠지만 로거나 DNS 서버가 없다 하더라도 서비스는 여전히 동작할 것입니다. 서비스가 존재한다면 use에 있는 스크립트보다 먼저 서비스를 시작합니다.need
설정은 강한 의존성입니다. 이는 need(필요)한 스크립트일 경우 명시한 스크립트를 성공적으로 실행하기 전에 시작하지 않음을 의미합니다. 또한 언급한 다른 스크립트를 다시 시작하면 마찬가지로 해당 스크립트도 다시 시작합니다.before
를 사용하면, 선택한 요소가 init 레벨의 일부일 경우 선택한 요소를 실행하기 전에 주어진 스크립트를 실행합니다. 그래서before alsasound
를 정의한 xdm 초기화 스크립트는 alsasound 스크립트를 실행하기 전에 시작하겠지만, alsasound가 동일한 init 레벨에서 실행하도록 계획했을 경우에만 해당합니다. alsasound를 시작하도록 계획하지 않았다면, 일부 설정은 효력이 없으며, 스크립트 자신이 가장 적당하다고 여기는 시점에 xdm을 실행합니다.- 이와 마찬가지로
after
를 사용하면, 선택한 요소가 init 레벨의 일부일 경우 선택한 요소를 실행한 다음에 주어진 스크립트를 실행합니다. 아니면 설정이 효력이 없으며, 적당하다고 여기는 시점에 init 시스템이 스크립트를 실행합니다.
need
가 스크립트를 시작하든 아니든 영향을 주는 진성 의존성 설정이라는 점을 분명히 이해해야합니다. 다른 모든 요소는 명령 스크립트를 실행(할 수 있거나 해야)할 수 있을때 init 시스템에 대해 분명히 가리킬 뿐입니다.
이제 젠투에서 사용하는 초기화 스크립트를 살펴보고, 초기화 스크립트가 아닌 의존성 요소를 살펴보십시오. 이"것"을 가상요소라고 부릅니다.
"가상 의존성"은 서비스에서 제공하는 의존성이지만 서비스에서 단독으로 제공하지 않는 의존성입니다. 초기화 스크립트는 시스템 로거에 의존할 수 있습니다만 시스템 로거는 여러가지가 있습니다(metalogd, syslog-ng, sysklogd, ...). 스크립트에서 이들 각자의 단일 모듈(모든 시스템 로거를 설치하고 실행중인지 시스템에서 신경쓰지 않음)을 필요로하지 않기 때문에, 이런 모든 서비스에서 가상 의존성을 제공함을 확인합니다.
Postfix 서비스의 의존성 정보를 살펴보겠습니다:
depend() { need net use logger dns provide mta }
보시는 바와 같이 Postfix서비스에는 다음과 같은 내용이 있습니다:
- (가상)net 의존 요소가 필요합니다 (/etc/init.d/net.eth0 같은 요소로 제공)
- (가상)logger 의존 요소를 사용합니다 (/etc/init.d/syslog-ng 같은 요소로 제공)
- (가상)dns 의존 요소를 사용합니다 (/etc/init.d/named 같은 요소로 제공)
- (가상)mta 의존 요소를 제공합니다 (모든 메일 서버의 공통요소)
순서 처리
이전 장에서 설명한 바와 같이 스크립트를 시작(하고 중지)하는 순서를 어떻게 할지 init 시스템에 알려줄 수 있습니다. 이 순서는 use와 need 의존 설정을 통해 다룰 뿐만 아니라 before와 after로도 순서 설정을 다루기도 합니다. 역시 앞의 설명과 마찬가지로 초기화 스크립트 중 하나의 예제로서 portmap 서비스를 살펴보겠습니다.
depend() { need net before inetd before xinetd }
비록 별로 도움이 되는 이야기는 아니지만, 동일한 실행 레벨의 모든 서비스를 포함하려면 "*" 글롭을 사용할 수 있습니다.
depend() { before * }
서비스가 반드시 로컬 디스크에 기록을 해야 한다면 localmount가 필요합니다. pidfile 같은 것을 /var/run에 두었다면 bootmisc 다음에 실행해야합니다:
depend() { need localmount after bootmisc }
표준 함수
depend()
함수 다음, start()
함수 정의가 필요합니다. 이 함수에는 서비스를 시작하는데 필요한 모든 명령어를 담고 있습니다. 사용자에게 무슨 일이 일어나고 있는지를 알리려면 ebegin과 eend함수를 사용하는 것이 좋습니다.
start() { if [ "${RC_CMD}" = "restart" ]; then # Do something in case a restart requires more than stop, start fi ebegin "Starting my_service" start-stop-daemon --start --exec /path/to/my_service \ --pidfile /path/to/my_pidfile eend $? }
--exec
와 --pidfile
는 start와 stop 함수에서 사용합니다. 서비스에서 pidfile을 만들지 못할 경우, 제대로 동작하는지 테스트 하는 겸에 되도록이면
--make-pidfile
를 사용합니다. 그렇지 않으면 pidfile를 사용하지 않습니다. 또한 start-stop-daemon의 옵션으로 --quiet
를 추가할 수 있지만 서비스에서 너무 많은 메시지를 뿌려대지 않은 이상 추천하는 방법은 아닙니다. --quiet
를 사용하면 서비스 시작에 실패했을 때 디버깅 내용을 못볼 수도 있습니다.
Another notable setting used in the above example is to check the contents of the RC_CMD variable. Unlike the previous init script system, the newer OpenRC system does not support script-specific restart functionality. Instead, the script needs to check the contents of the RC_CMD variable to see if a function (be it
start()
or stop()
) is called as part of a restart or not.
참고
--exec
가 실제로 서비스를 실행하는 쉘 스크립트를 실행하고 나가는 것이 아니라 서비스를 호출하는지 확인하십시오. -- 어떤 초기화 스크립트를 실행할지 고려합니다.
start()
함수에 대한 더 많은 예제를 보시려면 /etc/init.d 디렉터리에 있는 초기화 스크립트의 소스 코드를 살펴보십시오.
정의할 수 있(지만 반드시 정의할 필요는 없)는 또 다른 함수로는 stop()
이 있습니다. init 시스템은 여러분이 start-stop-daemon을 사용한다면 자체적으로 내용을 채울 정도로 충분히 똑똑합니다.
stop() {
ebegin "Stopping my_service"
start-stop-daemon --stop --exec /path/to/my_service \
--pidfile /path/to/my_pidfile
eend $?
}
서비스에서 (bash, python, perl과 같은) 다른 스크립트를 실행하고 나중에 이 스크립트의 이름을 (foo.py를 foo로) 바꾼다면 start-stop-daemon에 --name
을 추가해야합니다. 여러분의 스크립트를 지정할 때 바꿀 이름으로 반드시 지정해야 합니다. 이 경우 서비스에서는 foo로 이름을 바꾸는 foo.py를 시작합니다.
start() {
ebegin "Starting my_script"
start-stop-daemon --start --exec /path/to/my_script \
--pidfile /path/to/my_pidfile --name foo
eend $?
}
참고할 내용이 더 많이 필요할 경우를 대비하여 start-stop-daemon은 최고의 맨 페이지를 보유하고 있습니다:
user $
man start-stop-daemon
젠투의 초기화 스크립트 문법은 POSIX 쉘을 기반으로 하기 때문에 자유롭게 초기화 스크립트에 sh-호환 문법 스크립트를 사용할 수 있습니다. init 시스템에서 젠투가 처리할 변경 사항과는 상관 없이 스크립트의 기능이 남아있는지 확인하는, init 스크립트 외적인 배시 맞춤형 구성체처럼 다른 요소도 유지합니다.
개별 옵션 추가
앞서 우리가 언급했던 옵션보다 더 많은 옵션을 초기화 스크립트에서 지원하도록 하려면 extra_commands 변수에 옵션을 추가하고, 옵션 이름과 동일한 함수를 만들어야 합니다. 실례로 restartdelay
라고 하는 옵션을 지원하게 해보겠습니다:
- extra_commands - Command is available with the service in any state
- extra_started_commands - Command is available when the service is started
- extra_stopped_commands - Command is available when the service is stopped
extra_commands="restartdelay"
restartdelay() {
stop
sleep 3 # Wait 3 seconds before starting again
start
}
중요
restart()
함수는 openrc에서 중복 우선적용할 수 없습니다!
서비스 설정 변수
/etc/conf.d의 설정 파일을 지원하려 어떤 내용도 구현할 필요가 없습니다. 초기화 스크립트를 실행하면 다음 파일을 자동으로 참조합니다(예: 사용할 수 있는 변수):
- /etc/conf.d/YOUR_INIT_SCRIPT
- /etc/conf.d/basic
- /etc/rc.conf
또한 초기화 스크립트에 (net과 같은)가상 의존성을 제공하면, (/etc/conf.d/net과 같은) 의존성의 관련 파일도 참조합니다.
실행 레벨 동작 바꾸기
Who might benefit
많은 랩톱 사용자들은 이런 상황을 알고 있습니다. 밖에서 (사용할 수 있는 네트워크가 없을 때) net.eth0를 시작하고 싶지 않은데 집에서는 net.eth0를 시작해야 할 때가 있습니다. 젠투에서는 여러분이 실행할 실행 레벨 동작을 바꿀 수 있습니다.
다른 초기화 스크립트를 할당하여 부팅할 수 있는 두번째 "default" 실행 레벨을 만들 수 있습니다. 사용자는 부팅 시간에 활용할 기본 실행 레벨이 어떤 레벨인지 선택할 수 있습니다.
소프트 레벨 사용
제일 먼저, 두번째 "default" 실행 레벨에 대한 실행 레벨 디렉터리를 만드십시오. 다음 예제에서 "offline" 실행 레벨을 만들겠습니다.
root #
mkdir /etc/runlevels/offline
새로이 만든 실행 레벨에 필요한 초기화 스크립트를 추가하십시오. 현재 기본 실행 레벨에 net.eth0를 제외한 정확한 복사본을 보유하려면:
root #
cd /etc/runlevels/default
root #
for service in *; do rc-update add $service offline; done
root #
rc-update del net.eth0 offline
root #
rc-update show offline
(Partial sample Output)
acpid | offline
domainname | offline
local | offline
net.eth0 |
net.eth0을 offline 런레벨에서 제거했지만서도, udev가 감지한 장치를 시작하고 핫 플러그라는 기능의 적당한 서비스를 실행하려 들지도 모릅니다. 기본적으로 젠투는 핫 플러그를 활성화하지않습니다:
핫 플러그 기능을 활성화하지만 선택한 스크립트 모음에 한정하려면, /etc/rc.conf의 rc_hotplug 변수를 사용하십시오:
rc_hotplug="net.wlan !net.*"
참고
장치 초기화 서비스에 대한 더 많은 내용은 /etc/rc.conf의 주석을 살펴보십시오.
부트로더 설정을 편집하여 오프라인 실행 레벨에 대한 새 항목을 추가하십시오. 해당 항목에서 부팅 매개변수로 softlevel=offline
를 추가하십시오.
부트 레벨 사용
bootlevel을 사용하는 것은 softlevel과 완전히 유사합니다. 두번째 "default" 런레벨 대신에 두번째 "boot" 런레벨을 정의하는 점만 다릅니다.