我正在尝试从 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 本身来发送信号:
运行此命令后,运行并等待
tmux wait -L myscript
;编辑您的脚本或“源”命令以
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。