首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python - [Subprocess Popen Communicate]在执行时挂起

Python - [Subprocess Popen Communicate]在执行时挂起
EN

Stack Overflow用户
提问于 2021-11-16 14:35:34
回答 1查看 227关注 0票数 0

我正在尝试运行一个简单的命令,该命令在执行我的自动化测试之前启动一个端口转发,但它每次都挂起。

最终目标是在会话结束时设置端口转发,获取PID并终止端口转发。

我在macOS上使用Python 3.9.7,并试图在PyCharm IDE中执行此操作。

以下是代码片段:

代码语言:javascript
复制
def setup_port_forward():

     # command
     command = 'kubectl port-forward api_service 8080:80 -n service_name'

     # shell
     shell_script = subprocess.Popen(command,
                                shell=True,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                start_new_session=True)

     # extract
     try:
         stdout, stderr = shell_script.communicate(timeout=15)
         pid = int(stdout.decode().strip().split(' ')[-1])
     except subprocess.TimeoutExpired:
         shell_script.kill()

     yield

     # kill session
     os.kill(pid, signal.SIGTERM)

我不想假装知道它是做什么的,也不知道它是如何工作的,因为我还在学习python。

下面是我看过的一些帖子:

Python Script execute commands in Terminal

python subprocess.Popen hanging

Python Script execute commands in Terminal

Python hangs when executing a shell script that runs a process as a daemon

https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate

许多线程都说在shell脚本中使用subprocess.PIPE可能会导致问题,但是在另一个线程上,关于如何获取PID,这就是所使用的方法。

我试过使用不同的方法,就像在不同的帖子中建议的那样:

代码语言:javascript
复制
command = 'kubectl port-forward api_service 8080:80 -n service_name'

# 1
os.system(command)

# 2
subprocess.Popen(command).communicate

# 3
subprocess.run(command)

# 4
subprocess.call(command)

# 5
commands.getstatusoutput(command)

和他们所有的人一起,他们被吊死了。运行这是终端,它工作得很好。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-16 14:51:33

这里的主要问题是communicate。您只需要Popen进程,然后让它运行,直到您kill它。

如果可以的话,您肯定希望避免使用shell=True;另请参阅Actual meaning of

我也不认为stdoutstderr重定向有用。如果你只是想安静地运行它,可能只需要重定向到subprocess.DEVNULL或从它重定向。

在这里创建一个单独的会话似乎是有问题的;我可能也会放弃这一点。

对于在什么情况下首选哪种subprocess方法,Running Bash commands in Python有一些指导。当您想要等待进程完成时,TLDR是subprocess.run;当您不想等待进程完成时,则是subprocess.Popen (但是要了解您在管理对象方面的职责)。

代码语言:javascript
复制
def setup_port_forward():
    proc = subprocess.Popen(
        ['kubectl', 'port-forward', 'api_service', '8080:80', '-n',  'service_name'],
        stdin=subprocess.DEVNULL,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        start_new_session=True)
    yield
    # When done
    proc.kill()

将此函数用作生成器的设计也有点奇怪;我可能建议您将其转换为context manager

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69991074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档