Python 脚本在首次启动时从 rc.local 运行不可靠

在 Ubuntu 10.04 中,有一个 Python 脚本可以随机生成并输出系统根目录、MySQL 用户密码和其他密码到文件中。该脚本在作为 root 用户登录后从命令行运行时效果很好,但在使用 /etc/rc.local 在首次启动时运行时,大约有 25% 的几率失败。系统根目录、MySQL root 和一些 MySQL 用户密码会正确设置,但其中一个会失败,控制台日志报告标准 MySQL 登录错误:“ERROR 1045 (28000): Access denied for user ‘root’ @ ‘localhost’ (using password: YES)”。

2、解决方案

在尝试从 init 作业运行 Python 脚本时,需要考虑一些环境变量或其他因素。

  • 在脚本中,使用 subprocess.Popen 函数来以异步方式执行子进程命令。这可能会导致在首次启动期间系统负载过高时发生竞争条件。

  • 为了解决这个问题,可以将 Popen 函数的调用改为使用 wait() 方法等待子进程完成,确保在进行下一个操作之前,上一个操作已经完成。

  • 脚本中还使用了 logh 变量来记录日志信息。但 logh 变量在脚本中声明为全局变量,但没有明确地对其进行初始化。应当在脚本的开头显式地初始化 logh 变量,以确保其能够正常工作。

修改后的脚本如下:

#!/usr/bin/env python

import random
import string
import crypt
import re
from subprocess import PIPE, Popen

def getsalt(chars=string.letters + string.digits):
    return random.choice(chars) + random.choice(chars)


def getpwd(chars=string.letters + string.digits, length=12):
    retval = ""
    for i in range(0, length):
        retval += random.choice(chars)
    return retval


def replace_pass(filename):
    handle = open(filename, 'r')
    hbuf = handle.read()
    handle.close()

    for placeholder, password in pdict.iteritems():
        hbuf = re.sub(placeholder, password, hbuf)

    try:
        handle = open(filename, 'w')
        handle.write(hbuf)
        handle.close()
    except:
        pass

files = ['/home/ubuntu/passwords', '/opt/data1/alfresco/extensions/extension/alfresco-global.properties', '/opt/data/etc/mysql/debian.cnf', '/home/ubuntu/duncil']
userpasswords = {'root': 'ROOTPASSWORD'}
mysqlpasswords = {'root': 'MYSQLPASSWORD', 'alfresco': 'alfrescoPASSWORD', 'debian-sys-maint': 'debian-sys-maintPASSWORD'}
otherpasswords = ['OTHERPASSWORD']
log = '/var/log/firstrun'

logh = open(log, "a")
logh.write("Starting...\n")

# Generate passwords
pdict = {}
for user, placeholder in userpasswords.iteritems():
    syspass = getpwd()
    process = Popen(['usermod', '--password', crypt.crypt(syspass, getsalt()), user])
    process.wait()
    logh.write(placeholder + ": User " + user + " --> " + syspass + "\n")
    pdict[placeholder] = syspass

# Whats the MySQL Root password placeholder?
mplace = mysqlpasswords['root']
for user, placeholder in mysqlpasswords.iteritems():
    mpass = getpwd()
    if ("root" in mysqlpasswords) and (mysqlpasswords['root'] in pdict):
        mrootpass = pdict[mysqlpasswords['root']]
    else:
        mrootpass = ""
    process = Popen(['mysql', '-uroot', "--password=" + mrootpass, "-e", "UPDATE user SET Password = PASSWORD('" + mpass + "') WHERE User = '" + user + "';FLUSH PRIVILEGES;", "mysql"])
    process.wait()
    logh.write(placeholder + ": MySQL " + user + " --> " + mpass + "\n")
    pdict[placeholder] = mpass

for placeholder in otherpasswords:
    opass = getpwd()
    logh.write(placeholder + ": " + opass + "\n")
    pdict[placeholder] = opass

# Update passwords
for file in files:
    logh.write("Replacing placeholders in " + file + "\n")
    replace_pass(file)

logh.write("Finished\n")
logh.close()

经过修改后,脚本在首次启动时更可靠,问题得到解决。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值