python subprocess.run() 不等待 sh 脚本完成

python subprocess.run() 不等待 sh 脚本完成

我正在尝试从 python 执行以下命令子进程.运行()

tmux send-keys -t sessionp:4 "source /home/user/script.sh

为了在 tmux 会话中运行 bash shell 脚本。

cmd = 'tmux send-keys -t sessionp:4 "source /home/user/script.sh'
p = subprocess.run(cmd, shell=True, check=True)

Python 不会等到 script.sh 执行结束,并且由于脚本的下一个 python 部分需要由 script.sh 生成的文件,因此崩溃。

我怎样才能让子进程等到 script.sh 执行结束?

答案1

subprocess.run() 没有这些信息。事实上,甚至 tmux 也没有这些信息。

你不是在告诉 tmux 运行命令然后等待;而是在告诉它模拟一些按键。它甚至不知道这些按键实际上对应于一个脚本,更不用说知道该脚本何时完成。

这是运行脚本的一个糟糕的方法,但是如果你必须使用它,那么您的选择是有限的:

  • 您可以轮询(定期检查)该文件是否已出现。

    while not os.path.exists(...):
        time.sleep(1)
    
  • 您可以使用通知(Linux)或队列(FreeBSD)查看目录;内核会在文件出现时告诉您。

  • 您可以创建一个命名管道并尝试从中读取。这将等待另一个程序(例如您的脚本)实际在其中写入内容。(这当然需要在脚本末尾或“source”命令后添加“echo”命令。)

  • 您可以使用其他形式的 IPC(例如,使用信号而不是管道)来执行上述操作。

  • 你甚至可以使用 tmux 本身来发送信号:

    1. 运行此命令后,运行并等待tmux wait -L myscript

    2. 编辑您的脚本或“源”命令以tmux wait -U myscript在完成后运行。

答案2

我遇到了这个问题,因为我的subprocess.call语句会启动多个线程并继续运行,而不是像我预期的那样等待 unix 程序完成

我发现,如果不使用,shell=true我就会得到我期望的行为。我将命令作为列表传递,并使用每个参数构建列表:

我的原始代码:

unix_command = r'/usr/local/bin/program ' + \
               '--arg1 arg1value --arg2 arg2value \
               --arg3' + arg3value
subprocess.call(unix_command, Shell=TRUE)

修改后的代码:

unix_command = []
unix_command.append('/usr/local/bin/program')
unix_command.append('--arg1')
unix_command.append('arg1value')
unix_command.append('--arg2')
unix_command.append('arg2value')
unix_command.append('--arg3')
unix_command.append(arg3value)
subprocess.call(unix_command)

调用shell=TRUE参数意味着生成一个新的 shell 子进程,并且使用该 shell 的 PID 而不是命令程序 PID。

相关内容