如何在Armbian启动时以source方式激活Python虚拟环境?
解决Python虚拟环境激活脚本的问题
我来帮你拆解下问题:你现在的脚本如果直接执行(./script.sh),会在子shell里运行,source激活虚拟环境后,子shell执行完python就退出了,所以当前终端的shell不会保留虚拟环境;而如果是作为init.d服务的话,可能你误解了source的作用——其实在init.d脚本里source是有效的,只是你的脚本没有处理后台运行的问题。
下面分两种场景给你解决方案:
场景1:在交互式终端运行脚本后,保持虚拟环境激活
如果你是想在打开的终端里运行脚本,执行完应用后依然留在激活的虚拟环境中,那你需要修改脚本,在执行完python后启动一个新的shell,同时用source(或.)来运行脚本:
修改后的脚本内容:
#!/bin/bash echo "Activating application's virtual environment..." source /mpoint/bin/activate echo "Running main app.." python /mpoint/mpoint.py # 执行完应用后,启动当前用户的默认shell,保持虚拟环境激活状态 exec $SHELL
然后在终端里用以下命令运行:
source /path/to/your/script.sh # 或者用短点写法 . /path/to/your/script.sh
这样执行完mpoint.py后,你会自动进入一个已经激活虚拟环境的shell,不会直接退出。
场景2:作为开机自启服务运行(init.d方式)
如果你是想把这个应用设置成开机自动启动的服务,那原来的脚本问题在于python是前台运行,会导致init.d服务无法正常完成启动流程,而且没有提供停止/重启的管理功能。
你可以把脚本改成标准的init.d服务脚本,具体如下:
#!/bin/bash ### BEGIN INIT INFO # Provides: mpoint # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start mpoint app in Python virtual environment ### END INIT INFO # 配置参数 PID_FILE="/var/run/mpoint.pid" APP_SCRIPT="/mpoint/mpoint.py" VENV_ACTIVATE="/mpoint/bin/activate" LOG_FILE="/var/log/mpoint.log" case "$1" in start) echo "Starting mpoint application..." # 激活虚拟环境 source "$VENV_ACTIVATE" # 后台运行应用,把输出写入日志,记录PID python "$APP_SCRIPT" >> "$LOG_FILE" 2>&1 & echo $! > "$PID_FILE" echo "mpoint started successfully (PID: $(cat $PID_FILE))" ;; stop) if [ -f "$PID_FILE" ]; then local PID=$(cat "$PID_FILE") echo "Stopping mpoint (PID: $PID)..." kill "$PID" # 等待进程结束 sleep 2 if ! ps -p "$PID" > /dev/null 2>&1; then rm "$PID_FILE" echo "mpoint stopped successfully" else echo "Failed to stop mpoint, force killing..." kill -9 "$PID" rm "$PID_FILE" fi else echo "mpoint is not running (no PID file found)" fi ;; restart) echo "Restarting mpoint..." $0 stop sleep 3 $0 start ;; status) if [ -f "$PID_FILE" ]; then local PID=$(cat "$PID_FILE") if ps -p "$PID" > /dev/null 2>&1; then echo "mpoint is running (PID: $PID)" else echo "mpoint PID file exists but process is not running" fi else echo "mpoint is not running" fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0
然后执行以下步骤完成配置:
- 给脚本添加可执行权限:
chmod +x /etc/init.d/mpoint - 创建日志文件并设置权限:
touch /var/log/mpoint.log chown your_username:your_username /var/log/mpoint.log - 配置开机自启:
update-rc.d mpoint defaults
这样配置后,你可以用service mpoint start/stop/restart/status来管理服务,而且脚本里的source会在服务的启动进程中生效,应用会在虚拟环境里运行。
内容的提问来源于stack exchange,提问作者Marek Ant




