You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python服务执行rsync提示‘rsync: not found’问题排查求助

问题描述

我开发了一个Python应用,运行正常;将其制作为服务后整体运行也正常,但执行文件同步至远程服务器的rsync命令时出现异常:以个人用户身份运行时rsync可正常执行,通过服务运行时却失败。

程序中使用os.system调用rsync命令,代码如下:

import os
..
...
os.system("rsync --remove-source-files -p -e 'ssh -i ~/.ssh/id_rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa' -avq --chmod=a+rwx /source remoteuser@serviceip:/destination/")

查看journalctl日志发现错误:

python3[361897]: sh: 1: rsync: not found

我的服务配置如下:

[Unit]
Description=Job Server Service
After=network.target

[Service]
WorkingDirectory=/home/myuser/project
Environment="PATH=/home/myuser/project/projectenv/bin"
ExecStart=/home/myuser/project/projectenv/bin/python3 /home/myuser/project/job_server.py
User=myuser
Group=myuser
Environment=PYTHONUNBUFFERED=1


[Install]
WantedBy=multi-user.target

起初我以为是~/.ssh/id_rsa密钥文件无法被服务访问,但错误提示找不到rsync,怀疑是否与Python虚拟环境有关?进入虚拟环境(执行source projectenv/bin/activate)后我可正常执行rsync,恳请指点排查方向。


解决方案与排查方向

1. 核心问题:服务的PATH环境变量缺失系统路径

你的服务配置里Environment="PATH=/home/myuser/project/projectenv/bin"完全覆盖了系统默认PATH,只保留了虚拟环境的bin目录。而rsync通常位于系统全局路径(比如/usr/bin/rsync),不在虚拟环境目录内,所以服务进程无法找到它。

你在虚拟环境里能执行rsync,是因为激活虚拟环境时,脚本只是把虚拟环境的bin目录追加到原有PATH的前面,系统默认PATH并未丢失,因此仍能定位到rsync。

两种修复方式:

  • 修改服务PATH配置:将系统默认路径追加进去,比如:
    Environment="PATH=/home/myuser/project/projectenv/bin:/usr/bin:/bin"
    
  • 使用rsync绝对路径调用:先在终端执行which rsync获取其绝对路径(例如/usr/bin/rsync),然后在代码中直接使用该路径:
    os.system("/usr/bin/rsync --remove-source-files -p -e 'ssh -i ~/.ssh/id_rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa' -avq --chmod=a+rwx /source remoteuser@serviceip:/destination/")
    

2. 额外验证要点

  • SSH密钥权限与路径:当前错误是找不到rsync,但后续可能遇到密钥访问问题。服务运行时~指向/home/myuser,若密钥确实在~/.ssh/id_rsa,需确保文件权限为600(SSH会拒绝权限过宽的密钥);也可直接替换为绝对路径/home/myuser/.ssh/id_rsa避免路径解析问题。
  • 虚拟环境的rsync来源:在虚拟环境中执行which rsync,若输出是系统路径(如/usr/bin/rsync),说明虚拟环境未单独安装rsync,仍依赖系统版本,进一步验证PATH覆盖是核心问题。

3. 更可靠的命令调用方式(可选)

建议用subprocess模块替代os.system,能更精准地捕获输出和错误信息,便于调试:

import subprocess
try:
    result = subprocess.run(
        [
            "/usr/bin/rsync",
            "--remove-source-files",
            "-p",
            "-e", "ssh -i /home/myuser/.ssh/id_rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa",
            "-avq",
            "--chmod=a+rwx",
            "/source",
            "remoteuser@serviceip:/destination/"
        ],
        check=True,
        capture_output=True,
        text=True
    )
    # 成功执行后的逻辑
except subprocess.CalledProcessError as e:
    # 打印错误详情用于调试
    print(f"Rsync执行失败: {e.stderr}")

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:37:30