【问题标题】:running shell command in python在python中运行shell命令
【发布时间】:2023-07-09 00:14:01
【问题描述】:

我有这个用于运行 shell 脚本的简单代码,它有时可以工作,有时不能。如果不工作,控制台日志是:

请编辑 vars 脚本以反映您的配置,然后 使用“source ./vars”获取它。接下来,从新的 PKI 开始 配置并删除任何以前的证书和密钥,运行 “./clean-all”。最后,你可以运行这个工具(pkitool)来构建 证书/密钥。

这对我来说很奇怪,因为当我在控制台中运行命令时,它们会正常工作

def cmds(*args):

    cd1 = "cd /etc/openvpn/easy-rsa && source ./vars"
    cd2 = "cd /etc/openvpn/easy-rsa && ./clean-all"
    cd3  = "cd /etc/openvpn/easy-rsa && printf '\n\n\n\n\n\n\n\n\n' | ./build-ca"

    runcd1 = subprocess.Popen(cd1, shell=True)
    runcd2 = subprocess.Popen(cd2 , shell=True)
    runcd3 = subprocess.Popen(cd3 , shell=True)

    return (runcd1, runcd2, runcd3)  

我是这样改变的:

def pass3Cmds(*args):
    commands = "cd /etc/openvpn/easy-rsa && source ./vars && ./clean-all &&   printf '\n\n\n\n\n\n\n\n\n' | ./build-ca"
    runCommands = subprocess.Popen(commands, shell=True, stdout=PIPE)
    return (runCommands)

但控制台写下:

来源:未找到

【问题讨论】:

  • 您不需要子进程来更改目录,您还可以将 cwd 传递给子进程 cwd=path,如果一个依赖于另一个是完整的,那么您可能还会像 Popen 那样遇到更多问题不要等待
  • 在每个Popen-实例化之后添加runcd.communicate()。否则你无法保证在调用下一个命令之前之前的命令已经完成。
  • addind .communicate() 在第一行和第二行没有改变之后...

标签: python shell openvpn


【解决方案1】:

您需要将三个命令合二为一。

“source ./vars”只影响运行它的 shell。当您使用三个单独的 Popen 命令时,您将获得三个单独的 shell。

在一个 Popen 中运行所有命令,它们之间带有 &&s。

这“有时”工作的原因是你有时在你已经获取了 vars 脚本的 shell 中运行 python。

【讨论】:

  • 谢谢,Borealid,似乎它应该可以工作,但仍然不行(我已经编辑过,请参见上文)
  • @AndriyKravchenko 你的pass3Cmds 函数应该可以工作,假设你的shell 是bash。您可以删除 cd 并使用 Popencwd 参数,如另一条评论中所建议的那样,但除此之外,我可以看到这段代码没有任何问题。