【问题标题】:Execute command with delay using subprocess使用子进程延迟执行命令
【发布时间】:2023-05-28 09:38:02
【问题描述】:

我正在尝试使用子进程从 python 脚本执行此命令:sleep 10 && sudo /etc/init.d/tractor-blade restart &

我希望 Python 脚本完成(返回代码 0)。然后,10 秒后,我希望命令被执行。

这就是我所拥有的:

import sys, subprocess
command = ['sleep', '10', '&&', 'sudo', '/etc/init.d/tractor-blade', 'restart' '&']
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

# Catch stdout
sys.stdout.flush()
for line in iter(p.stdout.readline, b''):
    print(">>> " + line.rstrip())

但这就是发生的事情:

>>> sleep: invalid time interval `&&'
>>> sleep: invalid time interval `sudo'
>>> sleep: invalid time interval `/etc/init.d/tractor-blade'
>>> sleep: invalid time interval `restart'
>>> sleep: invalid time interval `&'
>>> Try `sleep --help' for more information.

我猜我的格式有误?

我需要在命令执行之前完成 python 脚本,这就是为什么我试图为命令添加延迟。我的 sudoers 允许使用 NOPASSWD 执行这个“拖拉机刀片”,因此不需要密码。

【问题讨论】:

标签: python


【解决方案1】:

这是因为 subprocess 可以在两种模式下工作:fork() 作为参数传递的元组指定的进程,或者使用 shell 执行字符串。区别在于shell 参数。所以你可能想要做的是:

command = "sleep 10 && sudo /etc/init.d/tractor-blade restart"
p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)

或:

time.sleep(10)
command = ['sudo', '/etc/init.d/tractor-blade', 'restart' '&']
subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

来自documentation

shell 参数(默认为 False)指定是否使用 shell 作为程序来执行。如果 shell 为 True,建议将 args 作为字符串而不是序列传递。

【讨论】:

    【解决方案2】:

    API 的工作方式是,command 中的第一个元素是subprocess.Popen 将调用的程序。该列表的其余部分被解析,然后作为参数输入该程序。默认情况下,它们不会被解析为 shell 命令。

    【讨论】: