You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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

然后执行以下步骤完成配置:

  1. 给脚本添加可执行权限:
    chmod +x /etc/init.d/mpoint
    
  2. 创建日志文件并设置权限:
    touch /var/log/mpoint.log
    chown your_username:your_username /var/log/mpoint.log
    
  3. 配置开机自启:
    update-rc.d mpoint defaults
    

这样配置后,你可以用service mpoint start/stop/restart/status来管理服务,而且脚本里的source会在服务的启动进程中生效,应用会在虚拟环境里运行。

内容的提问来源于stack exchange,提问作者Marek Ant

火山引擎 最新活动