0

我有一个备份脚本的问题,它应该调用一个 bash 启动/停止脚本,其中管理一个“守护程序”(通过 GNU 屏幕)。目前我的 python 备份脚本是通过 cron 调用的。在launch.sh脚本中有给定参数的确定。如果给出“stop”,脚本会回显“Stopping...”并运行 GNU screen 命令来关闭会话。“开始”也是如此。如果通过subprocess.call(...,Shell=True)Python 调用脚本,则会显示字符串,但屏幕会话保持不变。如果在 bash 中直接调用它,一切正常。

#!/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()

和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

我这里有什么问题?

4

1 回答 1

2

我敢肯定,现在你已经解决了这个问题,但是通过你的问题,我敢打赌答案非常简单——javamcpc-plus-legacy-1.4.7-R1.1.jar找不到,它失败了,随后屏幕终止。

在 launch.sh 中,screen 将在与调用脚本相同的目录中执行。在这种情况下,当由 cron 运行时,您的 python 脚本将具有正在运行的用户主目录的活动目录(/root/例如,root crontabs 将在 中运行,而用户 crontab 在 中/home/username/)。

简单的解决方案就是以下:

cd /home/minecraft/bspack2

launch.sh作为脚本中的第二行,就在#!/bash/sh.

将来,我建议在与屏幕交互时利用该-L参数。这将打开自动记录。默认情况下,screenlog.0当屏幕终止时,在当前目录中会生成一个文件“ ”,向您显示屏幕会话期间的活动日志历史记录。这将允许您轻松调试屏幕问题,并有助于鼓励在使用 shell 脚本时跟踪“当前目录”,从而使查找屏幕日志输出变得简单。

于 2014-02-26T19:41:42.863 回答