当前位置: 首页 > article >正文

后台运行 Python

后台运行 Python

如何运行

在后台运行 Python 程序的方式取决于操作系统以及具体需求(是否需要退出后继续运行、查看输出等)。以下是几种常用方法:

1. 使用 & (Linux/Unix/MacOS)

在命令末尾加上 &,可以让程序在后台运行。

示例:
python your_script.py &
  • 优点:简单快速。
  • 缺点:如果关闭终端,程序也会终止。

2. 使用 nohup (Linux/Unix/MacOS)

nohup 允许程序在终端关闭后继续运行。

示例:
nohup python your_script.py > output.log 2>&1 &
  • > \gt > output.log:将标准输出保存到 output.log 文件。
  • 2>&1:将标准错误输出重定向到标准输出。
查看运行状态:
jobs
停止任务:

找到对应的进程号(PID),然后用 kill 命令结束任务:

ps -ef | grep your_script.py
kill PID

3. 使用 screen 或 tmux (Linux/Unix/MacOS)

这两个工具允许创建虚拟终端,程序可以在其中运行,即使断开连接也不会中断。

使用 screen:
  1. 启动一个新的 screen 会话:
screen -S my_session
  1. 在会话中运行程序:
python your_script.py
  1. 按下 Ctrl+A,然后按 D 来退出到后台。
  2. 重新进入会话:
screen -r my_session
使用 tmux:

类似于 screen,更加现代化,命令类似。

4. 使用 Windows 的 start 命令

在 Windows 中,可以用 start 在后台运行 Python 程序。

示例:
start python your_script.py

5. 使用任务调度工具

(Linux/Unix/MacOS)

使用 cronsystemd 来安排脚本运行。

(Windows)

使用「任务计划程序」运行脚本。

6. 使用 Process Manager(如 Supervisor 或 PM2)

  • Supervisor:适合管理长期运行的 Python 脚本。
  • PM2:通常用于 Node.js,也支持 Python 程序。
示例 (PM2 安装后运行):
pm2 start your_script.py --interpreter=python3

7. 使用 Python 的多线程或守护进程

用 Python 自带的库运行守护程序,例如:

import threading

def your_function():
    while True:
        print("Running in the background...")
        time.sleep(10)

thread = threading.Thread(target=your_function, daemon=True)
thread.start()

总结

方法平台是否支持断开后继续运行备注
&Linux/MacOS简单但不能断开终端
nohupLinux/MacOS常用,适合简单脚本
screenLinux/MacOS虚拟终端,多任务管理
tmuxLinux/MacOS更现代的虚拟终端
startWindows适合 Windows 的简单运行
守护进程所有平台高级用法,需手动编写代码

根据需求选择合适的方案即可!

出现引入模块不存在怎么办?

在执行某个测试模块时出现提示,显示自定义模块data不存在,但是在PyCharm下运行正常。错误信息如下:

Traceback (most recent call last):
  File "XXX.py", line 2, in <module>
    from data import *
ModuleNotFoundError: No module named 'data'

大部分情况下,此类问题是由于包的路径没有设置正确所致。通过打印 PyCharm 和命令行下的 sys.path 路径信息对比,可以发现以下差异:
在当前目录下__init__添加

import sys
print("系统路径",sys.path)

解决方法

向执行代码中添加根目录路径,一般添加在头部

方法一:写死绝对路径
import sys
sys.path.append('xxx/xxx/xxx/')
方法二:使用os获取

os.path.dirname获取目录,此处就是获取目录的父目录。如果目录层级更多,就需要多加一层 os.path.dirname

import os,sys
project_root =  os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_root)
方法三:os获取+/…/

如果层级更多,则需要多加"…/" ,看起来比方法二更加简洁点

import os,sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../')
方法四,直接加到环境变量path中

输入以下命令

export PYTHONPATH=$PYTHONPATH:/xxx/

export 命令输入只临时生效,重新连接会失效,或者直接修改环境配置~/.bashrc等配置加上这句可以实现永久解决问题,如果这个不能实现,考虑自己手动去执行添加

方法五,subprocess.run 使用env变量

有些人是在subprocess去执行脚本,这个时候用上述的方法就不太能永久解决问题。我们可以使用subprocess的env参数去做,代码如下

def run_script(self, script_path, *args):
    # 运行 Python 脚本
    path_parts = script_path.split('/')
    export_commands = []
    for i in range(1, len(path_parts)):
        path_part = '/'.join(path_parts[:i])
        export_commands.append(f'{path_part}')
        env = os.environ.copy()
        env['PYTHONPATH'] = ':'.join(export_commands) + ':' + env.get('PYTHONPATH', '')
        # print(f"env{env}")
        script_dir = os.path.dirname(script_path)
        command = [f'{self.venv_path}/bin/python3', script_path] + list(args)
     return self.run_command(command,cwd=script_dir,env=env)
def run_command(self, command, shell=False,cwd=None,env=None) -> Tuple[int, str]:
    # 执行命令
    result = subprocess.run(command, shell=shell, capture_output=True, text=True,cwd=cwd,env=env)
    print(f"returncode:{result.returncode}")
    return result.returncode

通过script_path地址变量解析,添加所有的路径到环境变量中,然后给subprocess.run做继承,subprocess.run如果不继承的,每开一个会话,都是新的变量环境。

总结:
可能还有其他方法,但大体上找不到module的问题,大部分是路径变量问题,按照这个思路去解决就可以解决大部分类似问题。

如果输出文件中没有内容怎么办?

如果使用以下命令运行 Python 脚本时:

nohup python your_script.py > output.log 2>&1 &

而输出文件 output.log 中没有 print 语句的内容,可能是由于以下原因:

1. 输出被缓冲(最常见原因)

在 Python 中,标准输出(sys.stdout)默认是行缓冲全缓冲模式,尤其是当输出被重定向到文件时。这意味着 print 的内容可能会积累在缓冲区中,直到程序结束或缓冲区满时才会写入到文件。

解决方法:

在脚本中强制关闭缓冲,使用以下任意方法:

  1. 在 print 中加 flush=True:
    修改所有 print 调用,强制刷新输出缓冲区。
print("This is a test message", flush=True)
  1. 运行脚本时禁用缓冲:
    在运行命令中添加 -u 参数,这会使 Python 以无缓冲模式运行:
nohup python -u your_script.py > output.log 2>&1 &
  1. 手动刷新缓冲:
    使用 sys.stdout.flush() 在每次输出后刷新缓冲。
import sys
print("This is a test message")
sys.stdout.flush()

2. print 输出到了 stderr

有时,print 输出意外地被写入了 stderr,而不是 stdout,可能由于代码中修改了标准输出流。

解决方法:

确保你的命令正确重定向了 stderrstdout,如:

nohup python your_script.py > output.log 2>&1 &

其中 2>&1 将标准错误重定向到标准输出。

3. print 被捕获或重定向

如果脚本内部重定向了 sys.stdout,例如将输出流写到了其他地方,则 print 不会写入到默认输出。

解决方法:

检查代码中是否有类似以下操作:

import sys
sys.stdout = open("another_log.txt", "w")
  • 如果有,请注释掉或修改它。

4. 输出文件路径问题

确认 output.log 的路径是否正确,或者脚本是否有权限写入该路径。

检查方法:
  1. 确认文件是否创建:
ls -l output.log
  1. 检查写入权限:
touch output.log

5. 脚本没有运行成功

如果脚本未成功启动,可能导致没有输出。

检查方法:
  1. 确认脚本是否运行:
ps -ef | grep your_script.py
  1. 查看 nohup.out 文件:
    如果没有指定 > output.log,默认输出到 nohup.out 文件,检查其中是否有相关信息。

总结

最可能的原因是 缓冲问题,可以通过以下方式解决:

nohup python -u your_script.py > output.log 2>&1 &

或者在脚本中修改 print

print("Hello, World!", flush=True)

http://www.kler.cn/a/470057.html

相关文章:

  • Java 日期时间格式化标准
  • 如何轻松反转C# List<T>中的元素顺序
  • Arduino IDE刷微控制器并下载对应固件的原由
  • excel如何将小数转换为百分比
  • c#版本、.net版本、visual studio版本之间的对应关系
  • Flutter Web 选取并上传图片
  • JVM实战—MAT的使用和JVM优化总结
  • pip error: microsoft visual c++ 14.0 or greater is required
  • 文档解析工具:如何将PDF文档转换为Markdown格式?
  • 【FlutterDart】 listView.builder例子二(14 /100)
  • 练习(继承)
  • 25考研|重邮软件工程复试攻略!
  • 数据结构-单链表及其应用
  • 2025课题推荐:低空飞行器在复杂环境中的导航与避障系统
  • 资源分享:gpts、kaggle、paperswithcode
  • excel快速计算周数的方法
  • vue3中ref动态定义
  • 使用Llama 3.1创建合成数据集以调优你的大型语言模型
  • LeetCode代码随想录(二)——977.有序数组平方、209长度最小子数组、59螺旋矩阵2
  • Unity3D仿星露谷物语开发15之创建道具晃动效果
  • Vue——使用html2pdf插件,下载pdf文档到本地
  • VAxios
  • 深入了解 Nginx:进程、代理及用途解析
  • 苍穹外卖-day07(Spring Cache 购物车业务逻辑)
  • Flink 实时数据处理中的问题与解决方案
  • 【简博士统计学习方法】3. 统计学习方法的三要素