如何 运行 一个后台进程并且*不*等待?
How to run a background process and do *not* wait?
我的目标很简单:启动 rsync,不要等待。
Python Debian 上的 2.7.9
示例代码:
rsync_cmd = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}@{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1)
rsync_cmd2 = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}@{1}:'{2}' {3} &".format(remote_user, remote_server, file1, file1)
rsync_path = "/usr/bin/rsync"
rsync_args = shlex.split("-a -e 'ssh -i /home/mysuser/.ssh/id_rsa' {0}@{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1))
#subprocess.call(rsync_cmd, shell=True) # This isn't supposed to work but I tried it
#subprocess.Popen(rsync_cmd, shell=True) # This is supposed to be the solution but not for me
#subprocess.Popen(rsync_cmd2, shell=True) # Adding my own shell "&" to background it, still fails
#subprocess.Popen(rsync_cmd, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True) # This doesn't work
#subprocess.Popen(shlex.split(rsync_cmd)) # This doesn't work
#os.execv(rsync_path, rsync_args) # This doesn't work
#os.spawnv(os.P_NOWAIT, rsync_path, rsync_args) # This doesn't work
#os.system(rsync_cmd2) # This doesn't work
print "DONE"
(我注释掉执行命令只是因为我实际上将所有试验保留在我的代码中,这样我就知道我做了什么和没做什么。显然,我会 运行 右行未注释的脚本。)
这是怎么回事...我可以在服务器上观看传输,传输完成后,我会在屏幕上打印 "DONE"。
我希望在发出 rsync
命令并开始传输后立即打印 "DONE"。
看起来很简单。我遵循了其他帖子中概述的详细信息,例如 this one and this 一个,但有些东西阻止它为我工作。
提前致谢。
(我已经尝试了我在 StackExchange 中找到的所有内容,但我不觉得这是重复的,因为我仍然无法让它工作。我的设置有些不对,需要帮助。)
这里是 Python REPL 的验证示例:
>>> import subprocess
>>> import sys
>>> p = subprocess.Popen([sys.executable, '-c', 'import time; time.sleep(100)'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT); print('finished')
finished
如何通过另一个终端验证 window:
$ ps aux | grep python
输出:
user 32820 0.0 0.0 2447684 3972 s003 S+ 10:11PM 0:00.01 /Users/user/venv/bin/python -c import time; time.sleep(100)
Popen()
启动一个子进程——它不等待它退出。如果要等待子进程,则必须显式调用 .wait()
方法。从这个意义上说,所有子进程都是后台进程。
另一方面,子进程可能会从父进程继承各种properties/resources,例如打开的文件描述符、进程组、它的控制终端、一些信号配置等——这可能会导致阻止祖先进程退出,例如, 或者子进程可能会在 Ctrl-C 上过早死亡(SIGINT 信号发送到前台进程组)或者如果终端会话关闭(SIGHUP)。
要完全解除子进程的关联,您应该将其设为 daemon. Sometimes something in between could be enough e.g., it is enough to 。
我在使用 qnx 设备时遇到了类似的问题,我想要一个独立于主进程运行甚至在主进程终止后运行的 sub-process。
这是我发现实际有效的解决方案 'creationflags=subprocess.DETACHED_PROCESS':
import subprocess
import time
pid = subprocess.Popen(["python", "path_to_script\turn_ecu_on.py"], creationflags=subprocess.DETACHED_PROCESS)
time.sleep(15)
print("Done")
Link 到文档:https://docs.python.org/3/library/subprocess.html#subprocess.Popen
在 Ubuntu 中,即使 python 应用程序退出,以下命令仍然有效。
url = "https://www.youtube.com/watch?v=t3kcqTE6x4A"
cmd = f"mpv '{url}' && zenity --info --text 'you have watched {url}' &"
os.system(cmd)
我的目标很简单:启动 rsync,不要等待。
Python Debian 上的 2.7.9
示例代码:
rsync_cmd = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}@{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1)
rsync_cmd2 = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}@{1}:'{2}' {3} &".format(remote_user, remote_server, file1, file1)
rsync_path = "/usr/bin/rsync"
rsync_args = shlex.split("-a -e 'ssh -i /home/mysuser/.ssh/id_rsa' {0}@{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1))
#subprocess.call(rsync_cmd, shell=True) # This isn't supposed to work but I tried it
#subprocess.Popen(rsync_cmd, shell=True) # This is supposed to be the solution but not for me
#subprocess.Popen(rsync_cmd2, shell=True) # Adding my own shell "&" to background it, still fails
#subprocess.Popen(rsync_cmd, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True) # This doesn't work
#subprocess.Popen(shlex.split(rsync_cmd)) # This doesn't work
#os.execv(rsync_path, rsync_args) # This doesn't work
#os.spawnv(os.P_NOWAIT, rsync_path, rsync_args) # This doesn't work
#os.system(rsync_cmd2) # This doesn't work
print "DONE"
(我注释掉执行命令只是因为我实际上将所有试验保留在我的代码中,这样我就知道我做了什么和没做什么。显然,我会 运行 右行未注释的脚本。)
这是怎么回事...我可以在服务器上观看传输,传输完成后,我会在屏幕上打印 "DONE"。
我希望在发出 rsync
命令并开始传输后立即打印 "DONE"。
看起来很简单。我遵循了其他帖子中概述的详细信息,例如 this one and this 一个,但有些东西阻止它为我工作。
提前致谢。
(我已经尝试了我在 StackExchange 中找到的所有内容,但我不觉得这是重复的,因为我仍然无法让它工作。我的设置有些不对,需要帮助。)
这里是 Python REPL 的验证示例:
>>> import subprocess
>>> import sys
>>> p = subprocess.Popen([sys.executable, '-c', 'import time; time.sleep(100)'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT); print('finished')
finished
如何通过另一个终端验证 window:
$ ps aux | grep python
输出:
user 32820 0.0 0.0 2447684 3972 s003 S+ 10:11PM 0:00.01 /Users/user/venv/bin/python -c import time; time.sleep(100)
Popen()
启动一个子进程——它不等待它退出。如果要等待子进程,则必须显式调用 .wait()
方法。从这个意义上说,所有子进程都是后台进程。
另一方面,子进程可能会从父进程继承各种properties/resources,例如打开的文件描述符、进程组、它的控制终端、一些信号配置等——这可能会导致阻止祖先进程退出,例如,
要完全解除子进程的关联,您应该将其设为 daemon. Sometimes something in between could be enough e.g., it is enough to
我在使用 qnx 设备时遇到了类似的问题,我想要一个独立于主进程运行甚至在主进程终止后运行的 sub-process。 这是我发现实际有效的解决方案 'creationflags=subprocess.DETACHED_PROCESS':
import subprocess
import time
pid = subprocess.Popen(["python", "path_to_script\turn_ecu_on.py"], creationflags=subprocess.DETACHED_PROCESS)
time.sleep(15)
print("Done")
Link 到文档:https://docs.python.org/3/library/subprocess.html#subprocess.Popen
在 Ubuntu 中,即使 python 应用程序退出,以下命令仍然有效。
url = "https://www.youtube.com/watch?v=t3kcqTE6x4A"
cmd = f"mpv '{url}' && zenity --info --text 'you have watched {url}' &"
os.system(cmd)