시스템 서비스를 제어하기 위해 화면을 사용하는 방법은 무엇입니까?

시스템 서비스를 제어하기 위해 화면을 사용하는 방법은 무엇입니까?

내 Minecraft 서버를 실행하기 위해 시스템 서비스를 설정했습니다. 이제 서버가 충돌할 때 시작 스크립트를 반복하는 데 필요합니다. 이것은 지금까지 내 코드입니다.

#!/bin/bash

while true; do
    cd /home/mcserver/Spigot
    echo Starting Spigot...
    echo 600 > ./restart-info
    java -jar spigot.jar
    echo Server has stopped or crashed, starting again in 5 minutes...
    sleep 300
done

spigot.jar실제로 를 사용하여 출력을 볼 수 있지만 systemctl status spigot를 사용하여 서버 콘솔을 제어하고 싶습니다 screen.

내가 이것을 하려고 할 때:

screen -S "Spigot" java -jar spigot.jar

오류가 발생합니다 Must be connected to a terminal. 이 명령은 스크립트가 아닌 터미널에서만 작동하며 screen -r.

이 화면 오류를 "우회"할 수 있는 방법이 있습니까? script /dev/null화면 명령 앞에 배치해 보았습니다 . -d 및 -m과 함께 screen을 사용하고 싶지 않습니다. 왜냐하면 이 명령은 백그라운드에서 실행되고 스크립트는 내 서버를 계속 다시 시작하기 때문입니다.

답변1

나는 당신이 그것을 우연히 발견했다고 의심합니다이 블로그 게시물SSH 또는 Putty 세션을 닫을 때 screenMinecraft 서버가 중지되는 문제를 해결하는 데 사용됩니다. $ java -jar spigot.jar이 방법은 필수는 아니지만 Minecraft 서버를 실행하는 방법에 대한 표준 답변이 된 것 같습니다.

systemd는 이 문제에 대한 완전히 다른(그리고 더 나은) 솔루션입니다 screen. 스크립트에서 수행하는 모든 작업에 systemd 서비스 옵션을 사용할 수 있습니다.


일반 Minecraft 서버를 실행하려면 /etc/systemd/system/minecraft.service다음 콘텐츠로 서버를 만드세요.

[Unit]
Description=Minecraft Server

[Service]
Type=simple
WorkingDirectory=/home/minecraft
ExecStart=java -Xmx1024M -Xms1024M -jar /home/minecraft/server.jar nogui
User=minecraft
Restart=on-failure

[Install]
WantedBy=multi-user.target

시작 시 자동으로 시작되도록 설정합니다 systemctl enable minecraft.

당신은 그것을 제어하는 ​​​​방법을 묻고 있습니다 :

$ sudo systemctl start minecraft   # Starts the service if it wasn't running
$ sudo systemctl stop minecraft    # Stops the service
$ sudo systemctl restart minecraft # Restarts the service
$ sudo systemctl status minecraft  # Find out how the service is doing
$ sudo journalctl -u minecraft -f  # Monitor the logs

콘솔에 명령을 보내는 방법을 제외한 모든 작업을 수행합니다. 이를 위해 서버가 수신할 파일을 설정하고 다음 systemd 장치를 생성하여 해당 파일에 명령을 작성할 수 있습니다.

/etc/systemd/system/minecraft.socket:

[Unit]
PartOf=minecraft.service

[Socket]
ListenFIFO=%t/minecraft.stdin

그리고 /etc/systemd/system/minecraft.service:

[Unit]
Description=Minecraft Server

[Service]
Type=simple
WorkingDirectory=/home/minecraft
ExecStart=java -Xmx1024M -Xms1024M -jar /home/minecraft/server.jar nogui
User=minecraft
Restart=on-failure
Sockets=minecraft.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

이제 이 파일에 내용을 반영하여 콘솔 명령을 보낼 수 있습니다.

echo "help" > /run/minecraft.stdin
echo "/stop" > /run/minecraft.stdin

또한 멋진 점은 사용자 정의 명령 시퀀스와 cat전체 파일을 콘솔에 넣을 수 있다는 것입니다. 예를 들어 플레이를 하면보편적 건강 보장, 새로운 세계를 시작하고 사람들이 로그인하도록 한 다음 cat uhc.commands > /run/minecraft.stdin게임 규칙을 설정하고 플레이어를 분산시키고 활동을 시작할 수 있습니다.

답변2

-d 및 -m과 함께 screen을 사용하고 싶지 않습니다. 왜냐하면 이 명령은 백그라운드에서 실행되고 스크립트는 내 서버를 계속 다시 시작하기 때문입니다.

그래서 사용-D대신 -d(대문자 주의!)

-D -m 또한 "분리" 모드에서 화면을 시작하지만 새 프로세스를 분기하지는 않습니다. 세션이 종료되면 명령이 종료됩니다.

screen새로운 프로세스가 생성되지 않으므로 실행 java중에는 차단되고 서버가 중지되면 종료됩니다.

보너스로, 추가하면 -S spigot이 화면에 연결하여 모든 터미널의 출력을 모니터링할 수 있습니다(심지어 명령도 보낼 수 있습니다!).

그리고... 어쨌든 systemd 서비스를 사용하고 있는데(그리고 실제로 그래야 하므로) 스크립트에서 이 재시작 루프를 수행하는 이유는 무엇입니까? Restart=always다음 을 사용하여 systemd에서 이 문제를 처리하도록 하세요.RestartSec=5min

답변3

해결책을 찾았지만 사용할 수 없습니다 systemctl status spigot.

#!/bin/bash

while true; do
    cd /home/mcserver/Spigot
    echo Starting Spigot...
    screen -d -m -S Spigot java -jar spigot.jar
    SCREEN_NAME="Spigot"
    while screen -list | grep -q $SCREEN_NAME
    do
        sleep 1
    done
    echo Server has stopped, starting again in 5 minutes...
    sleep 300
done

스크립트는 screen 세션이 종료될 때까지 기다립니다. 이제 를 사용하여 출력을 보거나 콘솔과 상호 작용할 수 있습니다 screen -r. 또는 여러 화면 세션을 실행하는 경우에는 추가를 사용할 수 있습니다 screen -D -R "Spigot".

관련 정보