【问题标题】:Using subprocess.popen with multiple stdin to configure system : Python 2.7使用带有多个标准输入的 subprocess.popen 来配置系统:Python 2.7
【发布时间】:2013-07-27 22:39:57
【问题描述】:

我的目标是使用安装我的存储库和包的 python 脚本配置我的新 AWS 实例,然后使用子进程来配置(在本例中)postgres。从 yaml 或 json 文件中读取值。到目前为止,我已经成功安装了该环境的所有软件包和存储库。我被困的地方是一个 python 脚本,它将在 postgres 中创建一个用户,然后创建一个数据库。

import subprocess
# out is to show output, com is the stdin value(s) to pass
def run(command, out=False, com=False, ):

  process = subprocess.Popen(
    command,
    close_fds=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT
  )

  if out:
    out = iter(process.stdout.readline, b'')
    for line in out:
      print(line)

  if com:
    process.stdin.write(com)
    # http://stackoverflow.com/questions/16091112/python-pipe-to-popen-stdin
    # process.communicate(com) doesn't fit, i need multiple stdin

run(['ls', '-l'], True) # works 
run(['sudo', 'su', '-', 'postgres']) # works 

run(['createuser'], False, 'testuser') 
# broken, also after i get this working, this should be a list of stdin values    
# this results in infinite lines:
# Shall the new role be a superuser? (y/n)
# I do have a workaround, run(['createuser', '-d', '-r', '-s', '-w', 'username'], False)
# Confirmed workaround created user successfully

【问题讨论】:

    标签: python subprocess stdin popen


    【解决方案1】:

    我已经很久没有使用过 Postgres,但我猜你想 su 到 postgres,然后运行一个需要 postgres 权限的命令。

    但是你的 run(['sudo', 'su', '-', 'postgres']) 可能只是打开一个 shell 并等待; run(['createuser'], False, 'testuser') 可能永远不会运行。

    相反,我认为您应该将这两个命令结合起来。请参阅 su 的“-c”选项。

    另外,更安全一点的是,您可以在 sudo 中授予源用户 postgres 权限,以摆脱等式并使您的代码更简单。

    【讨论】:

    • 它运行了。查看以下的无限输出:新角色应该是超级用户吗? (是/否)
    • 所以解决这个问题的最好方法是不要使用需要多个标准输入的子进程运行命令。我觉得这在 Python 3 中有效。
    猜你喜欢
    • 2011-11-30
    • 2021-03-05
    • 2019-09-03
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多