【发布时间】:2012-09-02 17:31:23
【问题描述】:
我正在尝试编写 Python 脚本的一部分,该脚本会在 Linux 下为小型 Web 管理界面更改根 MySQL 密码。我已经按照 MySQL 官方文档更改了 root 密码,并提出了这个 shell 脚本,效果很好:
shopt -s xpg_echo
# stopping running MySQL server
invoke-rc.d mysql stop
# creating init file in a mysqld readable location
cat > /var/lib/mysql/mysql-init <<END
UPDATE mysql.user SET Password=PASSWORD('x123') WHERE User='root';
FLUSH PRIVILEGES;
END
# running mysqld_safe with init-file in the background
mysqld_safe --init-file=/var/lib/mysql/mysql-init &
sleep 5
# stopping mysql
invoke-rc.d mysql stop
# deleting the init file
rm /var/lib/mysql/mysql-init
# starting mysql
invoke-rc.d mysql start
有一个部分,我必须启动 mysqld_safe 并让它运行几秒钟,然后用 invoke-rc.d 很好地停止它。在 shell 脚本中,我可以使用 & 和 sleep 5 来解决它。
我的问题是我不知道如何在 Python 脚本中执行此操作不使用 shell=True。我可以使用 Popen 和 shlex.split(cmd) 完成所有其他部分,但是 & 似乎既没有通过 shlex.split(cmd) 也没有通过 shell=False。
这只是命令行中& 的一个简单问题,还是我真的需要 shell=True 来解决这个问题?如果没有,我需要使用线程吗?
【问题讨论】:
-
&由 shell 解释,因此您必须使用具有该语法的 shell。但是,您可以在 Python 中复制该功能,方法是使用系统调用fork、exec*和setsid。 -
好的,我得到了外壳部分。但是不能把 Popen 放在一个线程中吗?
-
是的,您也可以使用线程。这取决于您所说的“背景”到底是什么意思。要生成一个完全分离的子进程,您需要使用这些系统调用(以及其他),但对于一个短暂的进程,线程应该没问题。
-
我想要做的只是等待大约 5 秒,而进程初始化,然后调用
invoke-rc.d mysql stop停止它。背景只是一个想法,在 bash 脚本中运行良好。 -
顺便说一句,仔细看,你怎么知道mysql_safe进程完成了?你怎么知道它成功退出了?既然你的脚本在睡眠时阻塞,为什么你不能等待它呢?
标签: python multithreading shell process subprocess