我有一个备份脚本的问题,它应该调用一个bash启动/停止脚本,其中管理一个“守护进程”(通过GNU屏幕)。目前我的python备份脚本是通过cron调用的。在launch.sh
脚本中,可以确定给定的参数。如果给出“停止”脚本回声“停止...”并运行GNU屏幕命令来关闭会话。 “开始”也是如此。如果在Python中通过subprocess.call(...,Shell=True)
调用脚本,则会显示字符串,但屏幕会话保持不变。如果它直接在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
我的问题是什么?
答案 0 :(得分:2)
我相信你现在已经解决了这个问题,但是看看你的问题我敢打赌答案非常简单 - java找不到mcpc-plus-legacy-1.4.7-R1.1.jar
,失败了,随后屏幕终止。
在launch.sh中,屏幕将在与调用脚本相同的目录中执行。在这种情况下,你的python脚本在由cron运行时将拥有正在运行的用户主目录的活动目录(例如,root crontabs将在/root/
中运行,而{c}在/home/username/
中运行)。
简单解决方案仅适用于以下内容:
cd /home/minecraft/bspack2
作为launch.sh
脚本中的第二行,就在#!/bash/sh
之后。
将来,我建议在与屏幕交互时使用-L
参数。这会打开自动记录。默认情况下,在当前目录中,当屏幕终止时将生成文件“screenlog.0
”,在屏幕会话期间显示活动的日志历史记录。这将允许您轻松调试屏幕问题,并帮助鼓励在使用shell脚本时跟踪“当前目录”,以便简单地查找屏幕日志输出。