• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Linux Running Server And Restarting

Thaian Citizen

Hexenjäger
Joined
Apr 5, 2013
Messages
144
Solutions
4
Reaction score
17
Location
germany
Hello,

It's the first time that I'm trying to get a server to run from outside my own machine.

Now I've got the following problem:

When I close putty or it aborts the connection the server crashes. What's the way to start the server and keep it running?

Then I want something like an auto restart system. Let's say I want the server to restart daily at 6 am - how am I going to let it automatically shut down and restart? I'm not just talking about the server.exe itself, I am talking about I want to reboot that full machine after the game-server shut down, then turn it on again after my dedicated has rebooted. I could only find info to keep it restarting after crashes, but that's not exactly what I am looking for..

And is there a way to log what happened in case my server crashes and I'm not there?

I am using OTHire, Debian 7 Weezy.

Thank you!

Sincerely Yours,
Your secret admirer from Thais
 
As a start you can create a bash script in /etc/init.d that starts your tfs (just make the bash script executable "chmod +x script.sh" and make it start your server "sh /path/to/server/serverstartfile.sh").
This will start your server at system boot :)
 
As a start you can create a bash script in /etc/init.d that starts your tfs (just make the bash script executable and make it start your server "sh /path/to/server/serverstartfile.sh").
This will start your server at system boot :)

i can confirmed this :oops: worked for my ot
 
Thank you,

So this is the way I see it as a complete script in pseudo code:
(Before I would create code in the otserv source to make the console accept a /shutdown)
Code:
some_global_variable.STATE = not running
some_global_variable.checkTime = 60 secs

export otdatabase from phpmyadmin
store it in a folder /backups/current.date/

if (state = not.running ) { 
start application
STATE = running
}

Loop(checkTime) {
  if (server.time == XXX ) {
    go to application send command /shutdown
    state=shutdown
    1 if (application.not running) then state = not running  reboot system
    2 if (application.running) then wait some go back to 1
  }

  if (application.notrunning && state != shutdown) {
    log /logs/date/servercrash text file
    send email to [email protected]
  }
}

This would really do the job I think, can I make a bash file do all of this?
I guess I'll have to take a look at bash script documentation to find the right functions.

I might need help with: (can't find it easily)
1. Accesing the otserv application to send the console a /shutdown line
2. What do I do to create a log that describes the servercrash
should I just write in a textfile on what day and time the server has crashed and then send an email notification to myself
then figure out on myself how it crashed or is there a way to get a more precise information on the crash without hard coding log outputs into my servers sources?

Thank you, even for reading all of this. I know it's a lot, but I also want to really understand what I am doing or what I am going to do.
 
Hello,

It's the first time that I'm trying to get a server to run from outside my own machine.

Now I've got the following problem:

When I close putty or it aborts the connection the server crashes. What's the way to start the server and keep it running?

Then I want something like an auto restart system. Let's say I want the server to restart daily at 6 am - how am I going to let it automatically shut down and restart? I'm not just talking about the server.exe itself, I am talking about I want to reboot that full machine after the game-server shut down, then turn it on again after my dedicated has rebooted. I could only find info to keep it restarting after crashes, but that's not exactly what I am looking for..

And is there a way to log what happened in case my server crashes and I'm not there?

I am using OTHire, Debian 7 Weezy.

Thank you!

Sincerely Yours,
Your secret admirer from Thais
You can use the command "screen" and run your tfs normally, here are some basics:
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/

To log the output you can run tfs followed by "2>&1 | tee output.txt".

To get the backup/restart server when crashing/sending email I would use perl, but you can use any other language you think its good for you.
 
I have come up with following solution for my requirements.
Please look over it before I test it, I fear making some lesser damage testing this stuff.
This script is to be put in /etc/init.d.
Code:
chmod +x ServerRebooter.sh

# NOT_RUNNING, RUNNING, SHUTDOWN, CRASHED
STATE="NOT_RUNNING"

# Server restart time, defined by default by a range of 5 minutes
RESTART_RANGE_MIN="050000"
RESTART_RANGE_MAX="050500"

# Time to check after shutdown call, 15 minutes as default
CHECKTIME=15


CreateBackupDB ()
{
    local curYear="`date +%Y`"
    local curMonth="`date +%B`"
    local curDate="`date +%m-%d-%Y`"
    local curTime="`date +%H:%M:%S`"

    local filename=db-backup_"$curDate"_at_"$curTime"
    local dir=/root/backups/database/"$curYear"/"$curMonth"

    # check if directory exists, if not create it
    if [ ! -d "$dir" ];
    then
        mkdir $dir
    fi
 
    # export the database sql file to backup directory
    mysqldump -u username -ppassword database_name > $dir/$filename.sql
}

RunServer ()
{ 
    local curYear="`date +%Y`"
    local curMonth="`date +%B`"
    local curDate="`date +%m-%d-%Y`"

    local filename=output_"$curDate"
    local dir=/root/logs/"$curYear"/"$curMonth"
 
    # run server application and print output to a textfile sorted by year,month,date
    sh /root/otserver/server.sh 2>&1 | tee $dir/$filename.txt
}

CheckIfIsRunning ()
{
    if [ pgrep "server" > /dev/null ];
    then
        return 0
    else
        return 1
    fi
}

SendShutdown ()
{
    local processId=`pidof "server"`
    echo "/shutdown" > /proc/$processId/fd/0
     
    RebootServer
}

RebootServer ()
{
    local startTime=`date +%s`
    local currentTime=$startTime
    local waitTime=`expr $CHECKTIME * 60`

    while [ `expr $currentTime - $startTime` -le $waitTime ];
    do
        local currentTime=`date +%s`
    done
 
    CreateBackupDB
 
    sudo reboot
}

NotifyMe ()
{
    local curDate="`date +%m-%d-%Y`"
    local curTime="`date +%H:%M:%S`"
    echo "curDate - Server crashed @$curTime" | mail -s "Server Crash" [email protected]
}

if [ $STATE = "NOT_RUNNING" ];
then
    if [ CheckIfIsRunning ];
    then
        # set state right if its running but state is not set to running
        STATE="RUNNING"
    else
        # if not running then run server and set state
        RunServer
        STATE="RUNNING"
    fi
fi

if [ $STATE = "RUNNING" ];
then
    while [ CheckIfIsRunning ];
    do
        local currentTime="`date +%H+%M+%S`"
        if [ $currentTime > $RESTART_RANGE_MIN && $currentTime < $RESTART_RANGE_MAX ];
        then
            STATE="SHUTDOWN"
            break
        fi
    done
fi

if [ $STATE = "SHUTDOWN" ];
then
    SendShutdown
else
    STATE="CRASHED"
fi

if [ $STATE = "CRASHED" ];
then
    NotifyMe
fi


EDIT: I tried to run this script, put it in /etc/init.d/ then restarted my server, it didnt execute the file by itself and when I try to start it from putty it says permission denied
 
Last edited:
I have come up with following solution for my requirements.
Please look over it before I test it, I fear making some lesser damage testing this stuff.
This script is to be put in /etc/init.d.
Code:
chmod +x ServerRebooter.sh

# NOT_RUNNING, RUNNING, SHUTDOWN, CRASHED
STATE="NOT_RUNNING"

# Server restart time, defined by default by a range of 5 minutes
RESTART_RANGE_MIN="050000"
RESTART_RANGE_MAX="050500"

# Time to check after shutdown call, 15 minutes as default
CHECKTIME=15


CreateBackupDB ()
{
    local curYear="`date +%Y`"
    local curMonth="`date +%B`"
    local curDate="`date +%m-%d-%Y`"
    local curTime="`date +%H:%M:%S`"

    local filename=db-backup_"$curDate"_at_"$curTime"
    local dir=/root/backups/database/"$curYear"/"$curMonth"

    # check if directory exists, if not create it
    if [ ! -d "$dir" ];
    then
        mkdir $dir
    fi

    # export the database sql file to backup directory
    mysqldump -u username -ppassword database_name > $dir/$filename.sql
}

RunServer ()
{
    local curYear="`date +%Y`"
    local curMonth="`date +%B`"
    local curDate="`date +%m-%d-%Y`"

    local filename=output_"$curDate"
    local dir=/root/logs/"$curYear"/"$curMonth"

    # run server application and print output to a textfile sorted by year,month,date
    sh /root/otserver/server.sh 2>&1 | tee $dir/$filename.txt
}

CheckIfIsRunning ()
{
    if [ pgrep "server" > /dev/null ];
    then
        return 0
    else
        return 1
    fi
}

SendShutdown ()
{
    local processId=`pidof "server"`
    echo "/shutdown" > /proc/$processId/fd/0
    
    RebootServer
}

RebootServer ()
{
    local startTime=`date +%s`
    local currentTime=$startTime
    local waitTime=`expr $CHECKTIME * 60`

    while [ `expr $currentTime - $startTime` -le $waitTime ];
    do
        local currentTime=`date +%s`
    done

    CreateBackupDB

    sudo reboot
}

NotifyMe ()
{
    local curDate="`date +%m-%d-%Y`"
    local curTime="`date +%H:%M:%S`"
    echo "curDate - Server crashed @$curTime" | mail -s "Server Crash" [email protected]
}

if [ $STATE = "NOT_RUNNING" ];
then
    if [ CheckIfIsRunning ];
    then
        # set state right if its running but state is not set to running
        STATE="RUNNING"
    else
        # if not running then run server and set state
        RunServer
        STATE="RUNNING"
    fi
fi

if [ $STATE = "RUNNING" ];
then
    while [ CheckIfIsRunning ];
    do
        local currentTime="`date +%H+%M+%S`"
        if [ $currentTime > $RESTART_RANGE_MIN && $currentTime < $RESTART_RANGE_MAX ];
        then
            STATE="SHUTDOWN"
            break
        fi
    done
fi

if [ $STATE = "SHUTDOWN" ];
then
    SendShutdown
else
    STATE="CRASHED"
fi

if [ $STATE = "CRASHED" ];
then
    NotifyMe
fi


EDIT: I tried to run this script, put it in /etc/init.d/ then restarted my server, it didnt execute the file by itself and when I try to start it from putty it says permission denied
You can use sleep to wait for reboot and you should add sleep to CheckIfIsRunning loop as well.
 
I get everything to work now using screen and such...

But theres one problem, the server won't even start no more
Suddenly it looks for config.lua in /root/.otserv/ and then says that it can't find it
Thats so strange, that didnt happen before, the folder the server is in is: /root/server/

And yea too much for me today I watch some tv and sleep
 
I get everything to work now using screen and such...

But theres one problem, the server won't even start no more
Suddenly it looks for config.lua in /root/.otserv/ and then says that it can't find it
Thats so strange, that didnt happen before, the folder the server is in is: /root/server/

And yea too much for me today I watch some tv and sleep
Now that is very weird. Just for the permission part: Have you run chmod +x on the file?
 
I get everything to work now using screen and such...

But theres one problem, the server won't even start no more
Suddenly it looks for config.lua in /root/.otserv/ and then says that it can't find it
Thats so strange, that didnt happen before, the folder the server is in is: /root/server/

And yea too much for me today I watch some tv and sleep
Now that is very weird. Just for the permission part: Have you run chmod +x on the file?
Its because your working dir have to be the TFS. And your code wont work because "sh tfs" will lock your script until the server is closed, so it wont execute anything.

Here is a working code in perl, but there is still one problem that I couldn't solve, when you start the tfs using screen the tee simply doesn't work.
Code:
#!/usr/bin/perl
use Time::Piece;

my $otdir = "/root/forgottenserver/";
my $runtfs = "server.sh";
my $dbbackdir = "/root/backups/database/";
my $logsdir = "/root/logs/";
my $CHECKRUNNING = 60; #Check if tfs running in seconds
my $DELAYSHUTDOWN = 10*60; #Delay reboot in seconds

my $dateformat = "%H:%M:%S";
my $backdateformat = "db-backup_%m-%d-%Y_at_%H:%M:%S.sql";
my $outputdateformat = "output_%m-%d-%Y_at_%H:%M:%S.txt";
my $RESTART_RANGE_MIN = "05:00:00";
my $RESTART_RANGE_MAX = "05:05:00";
my $STATE = "NOT_RUNNING";
my $curyear = localtime->strftime("%Y");
my $curmonth = localtime->strftime("%B");
my $curtime = localtime->strftime("%H:%M:%S");
$RESTART_RANGE_MIN = Time::Piece->strptime($RESTART_RANGE_MIN, $dateformat);
$RESTART_RANGE_MAX = Time::Piece->strptime($RESTART_RANGE_MAX, $dateformat);
$curtime = Time::Piece->strptime($curtime, $dateformat);

sub CreateBackupDB {
my $filename = localtime->strftime($backdateformat);
my $dir = $dbbackdir . $curyear . "/" . $curmonth;
if(! -d $dir) {
` mkdir -p $dir`;
}
`mysqldump -u root -ppassword dbname > $dir/$filename`;
}

sub RunServer {
my $filename = localtime->strftime($outputdateformat);
my $dir = $logsdir . $curyear . "/" . $curmonth;
if(! -d $dir) {
`mkdir -p $dir`;
}
chdir $otdir;
`screen -d -m -S server $otdir/$runtfs $dir/$filename`;
}

sub CheckIfIsRunning {
my $command = `screen -S server -X select .`;
if(${^CHILD_ERROR_NATIVE} == 0) {
return 1;
} else {
return 0;
}
}

sub RebootServer {
CreateBackupDB();
sleep $DELAYSHUTDOWN;
sudo reboot;
}

sub SendShutdown {
my $pid = `pidof $runtfs`;
$pid =~ s/\D//g;
`echo "/shutdown" > /proc/$pid/fd/0;`;
RebootServer();
}

sub NotifyMe {
my $curT = localtime->strftime("%m-%d-%Y %H:%M:%S");
`echo "Server crashed @$curT" | mail -s "Server Crash" [email protected]`;
}

if ($STATE eq "NOT_RUNNING") {
if(CheckIfIsRunning()) {
$STATE = "RUNNING";
print("Server is already running.\n");
} else {
RunServer();
print("Server started.\n");
$STATE = "RUNNING";
}
}

if ($STATE eq "RUNNING") {
while(CheckIfIsRunning()) {
if($curtime > $RESTART_RANGE_MIN && $curtime < $RESTART_RANGE_MAX) {
$STATE = "SHUTDOWN";
print("Server restarting.\n");
last;
}
sleep $CHECKRUNNING;
}
}

if ($STATE eq "SHUTDOWN") {
SendShutdown();
} else {
print("Server crashed\n");
$STATE = "CRASHED";
}

if ($STATE eq "CRASHED") {
NotifyMe();
}

This will run the screen with the server so closing the script wont stop the server, but wont backup/reboot/notify;.

To stop the server you have to do "screen -r -S server" and press CTRL+C or just kill the tfs process.

Edit: Okay, found a solution for the tee problem, instead of sending the command here:
Code:
`screen -d -m -S server $otdir/$runtfs 2>&1 | tee $dir/$filename`;

You have to create a .sh to run the server and execute tee so the .sh, already edited the code, thats how server.sh looks like (its inside the same dir as the tfs):
Code:
./tfs 2>&1 | tee $1;
 
Last edited:
Ok I got it now, I must start it from within the working directory.

So best would be to have 2 screens:
One running my script to have it doing all the stuff like backup/reboot/notify
And one screen that is running the server

But now I got following problem, how can I check if the server in the screen is still running
I mean I can check if the screen is there, but lets say the server crashed, the screen would be still there but the server not running

And to send commands to the console i should just let my script attach the server's screen and then echo /shutdown for example?
 
Ok I got it now, I must start it from within the working directory.

So best would be to have 2 screens:
One running my script to have it doing all the stuff like backup/reboot/notify
And one screen that is running the server

But now I got following problem, how can I check if the server in the screen is still running
I mean I can check if the screen is there, but lets say the server crashed, the screen would be still there but the server not running

And to send commands to the console i should just let my script attach the server's screen and then echo /shutdown for example?
To view running processes you could use the htop command :)
 
Ok I got it now, I must start it from within the working directory.

So best would be to have 2 screens:
One running my script to have it doing all the stuff like backup/reboot/notify
And one screen that is running the server

But now I got following problem, how can I check if the server in the screen is still running
I mean I can check if the screen is there, but lets say the server crashed, the screen would be still there but the server not running

And to send commands to the console i should just let my script attach the server's screen and then echo /shutdown for example?
When you start the screen as i did,the screen should close when it's finished. However you can still check if the server is running.
 
So I just check if the screen is still there? if the server crashed the screen is gone aswell?
Because the way I see it the screen holds the otserver application if the otserver crashes, the screen would still be there just empty now?
 
So I just check if the screen is still there? if the server crashed the screen is gone aswell?
Yes, unless the tfs doesn't stop running when it crashes. But you can also check for the tfs using something like:

Code:
#!/usr/bin/perl
my $running = `pgrep -f tfs`;
$running =~ s/\D//g;

if ($running) {
    print("Process is running, PID:$running\n");
} else {
    print("Process is not running\n");
}

If you're using bash i don't know should be something like that.
 
The script seems to work just not that one part..
When I type screen -d -S server -m ./server into putty command line then it works
if i start a bash script that includes above screen creation command, it wont execute ???
Everything else in my script seems to be ok, the script just wont start a screen

This really gets me tired, already been working on other fixes all day long
 
Back
Top