0

I have a problem with a backup script which is supposed to call a bash starting/stopping script, in which a "daemon" (via GNU screen) is managed. For the moment my python backup script is called via cron. Within the launch.sh script there is a determination of the given parameter. If "stop" is given the script echos "Stopping..." and runs the GNU screen command to shut down the session. The same goes for "start". If the script is called via subprocess.call(...,Shell=True) in Python the string is shown but the screen session remains untouched. If it gets called directly in bash everything works fine.

#!/usr/bin/env python
'''
Created on 27.07.2013
BackUp Script v0.2
@author: Nerade
'''
import time
import os
from datetime import date
from subprocess import check_output
import subprocess



script_dir = '/home/minecraft/automated_backup'

#folders = ['/home/minecraft/staff']
folders = ['/home/minecraft/bspack2','/home/minecraft/staff']

# log = 0
backup_date = date.today()
backup_dir = '/home/minecraft/automated_backup/' + backup_date.isoformat()

def main():
    global log
    init_log()
    init_dirs()
    for folder in folders:
        token = folder.split("/")
        stopCmd = folder + '/launch.sh stop'
        log.write("Stopping server %s...\n" % (token[3]))
        subprocess.call(stopCmd,shell=True)
        #print stopCmd
        while screen_present(token[3]):
            time.sleep(0.5)
        log.write("Server %s successfully stopped!\n" % (token[3]))
        specificPath = backup_dir + '/' + token[3]
        os.makedirs(specificPath)
        os.system("cp /home/minecraft/%s/server.log %s/server.log" % (token[3],specificPath))
        backup(folder,specificPath + '/' + backup_date.isoformat() + '.tar.gz')
    dumpDatabase(backup_dir)
    for folder in folders:
        token = folder.split("/")
        startCmd = folder + '/launch.sh start'
        log.write("Starting server %s...\n" % (token[3]))
        subprocess.call(startCmd,shell=True)
        time.sleep(1)
        log.write(screen_present(token[3]))
        #print startCmd
def dumpDatabase(target):
    global log

    log.write("Dumping Database...\n")
    cmd = "mysqldump -uroot -p<password> -A --quick --result-file=%s/%s.sql" % (backup_dir,backup_date.isoformat())
    os.system(cmd)
    #print cmd

def backup(source,target):
    global log

    log.write("Starting backup of folder %s to %s\n" % (source,target))
    cmd = 'tar cfvz %s --exclude-from=%s/backup.conf %s' % (target,source,source)
    os.system(cmd)
    #print cmd


def screen_present(name):
        var = check_output(["screen -ls; true"],shell=True)
        if "."+name+"\t(" in var:
                return True
        else:
                return False

def init_log():
    global log
    log = open("%s/backup.log" % script_dir,'a')

    log.write(
    "Starting script at %s\n" % time.strftime("%m/%d/%Y %H:%M:%S")
    )
def init_dirs():
    global backup_dir,log
    log.write("Checking and creating directories...\n")
    if not os.path.isdir(backup_dir):
        os.makedirs(backup_dir)

if __name__ == '__main__':
    main()

And the launch.sh:

#!/bin/sh
if [ $# -eq 0 ] || [ "$1" = "start" ]; then
echo "Starting Server bspack2"
screen -S bspack2 -m -d java -Xmx5G -Xms4G -jar mcpc-plus-legacy-1.4.7-R1.1.jar nogui
fi
if [ "$1" = "stop" ]; then
screen -S bspack2 -X stuff 'stop\015'
echo "Stopping Server bspack2"
fi

What's my problem here?

Nerade
  • 61
  • 1
  • 3

1 Answers1

2

I'm sure by now you've solved this problem, but looking through your question I'd bet the answer is remarkably simple -- mcpc-plus-legacy-1.4.7-R1.1.jar isn't found by java, which fails, and subsequently screen terminates.

In launch.sh, screen will execute in the same directory as the calling script. In this case, your python script, when run by cron, will have an active directory of the running user's home directory (so root crontabs will run in /root/, for instance, and a user crontab in /home/username/).

Simple solution is just to the following:

cd /home/minecraft/bspack2

as the second line in your launch.sh script, just after #!/bash/sh.

In the future, I'd recommend when interacting with screen to leverage the -L parameter. This turns on autologging. By default, in the current directory a file "screenlog.0" will be generated when screen terminates, showing you a log history of activity during the screen session. This will allow you to debug screen problems with ease, and help encourage keeping track of "current directory" while working with shell scripts, to make finding the screen log output simple.

ProgrammerDan
  • 871
  • 7
  • 17