【问题标题】:How can I Executing Shell Commands with Python for restore database postgres?如何使用 Python 执行 Shell 命令以恢复数据库 postgres?
【发布时间】:2021-05-03 06:26:27
【问题描述】:

我在 Linux 上恢复我的数据库模板,如下所示: Linux 终端:

su postgres
psql
create database test3;
\q
pg_restore -v -d test3 /opt/empty-db_template.backup
exit
systemctl restart postgresql-11.service

完成了!但是当我在 python 中执行 Shell 命令时,如图卡在psqlstep 中,我该如何解决?

Get stuck in psql step

import os
os.system('ls')
os.system('su postgres')
os.system('psql')

os.system('create database test3;')
os.system('\q')


os.system('pg_restore -v -d test3 /opt/empty-db_template.backup')
os.system('exit')
os.system('systemctl restart postgresql-11.service')

【问题讨论】:

  • 你弄错了 os.system。它不会将您的字符串作为击键传递,而是将参数作为命令行执行。因此,例如, os.system('\q') 没有任何意义。您应该将所有操作作为一个命令行。所以你将有三个 os.system 调用(一个用于“ls”,第二个用于运行 psql,第三个用于重新启动 postgresql)

标签: python linux shell


【解决方案1】:

su postgres 切换到另一个用户并打开一个子shell,其中执行以下命令。换句话说,您以用户postgres 的身份执行命令(直到exit)。

使用os.system() 离开外壳,su 会立即打开。以下命令再次以您的标准用户身份执行。

为避免这种情况,您必须将所有命令直接传递给su

su postgres -c psql

我认为create database test3 行不是shell 命令,而是输入到交互式psql 命令中的行。然后你必须弄清楚如何以非交互方式做到这一点,例如通过拨打psql -c 'create database test3' 或类似电话。有关详细信息,请参阅 psql 的手册页。

如此有效,您将使用类似的行

os.system('su postgres -c "psql -c \'create database test3\'"')

引用可能是个问题。尝试一下,如果没有成功,请打开另一个问题,提供有关您已经尝试过的更具体的信息。

【讨论】:

  • 谢谢帮助我,我创建数据库:os.system('su postgres -c "psql -c \'create database test3\'"') 并恢复我的模板:os.system('su postgres -c "pg_restore -v -d test3 /opt/empty-db_template.backup" ') 并完成。不需要os.system('\q') 和os.system('exit')
  • 是的,\q 会退出 postgres 的交互模式,exit 会离开 shell。如果您使用新方法,显然两者都不是必需的。使用-c 到su 会在执行命令后终止shell(因此不需要exit)并使用-c 调用psql 也会执行一个命令然后终止(因此不需要\q)。跨度>
【解决方案2】:

你在这里做的事情是行不通的。 su 创建一个新的外壳。它将等待来自控制台的更多输入。在退出su shell 之前,您将没有机会输入psql 命令。您要么需要以postgres 用户身份运行此命令,要么重复使用su 命令,或者只需创建一个shell 脚本并运行该shell 脚本。

os.system( 'su postgres createdb test3' )
os.system( 'su postgres pg_restore ... ' )
os.systen( 'systemctl restart postgresql-11.service' )

【讨论】:

  • 此外,您可能希望将 os.system() 替换为 subprocess.run() 或其旧版本之一(特别是 subprocess.check_call()。您可以使用 @987654330 来使用单个子进程@,尽管您仍然需要弄清楚如何正确编写这些命令的脚本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 2011-02-13
相关资源
最近更新 更多