使用Python Paramiko向群晖NAS上传文件无报错但找不到文件
Paramiko上传群晖NAS文件无报错但找不到文件的原因与修正
核心问题根源
你现在代码运行不报错但找不到上传文件,本质是踩了两个最容易被忽略的路径上下文坑:
- SSH执行通道和SFTP通道的工作目录相互独立
Paramiko里exec_command开的是独立的shell会话,这个会话的当前工作目录、路径上下文,和后续open_sftp()开的SFTP通道的默认工作目录完全不共享。你在exec_command里执行mkdir创建的文件夹,是落在shell会话的默认路径下的,SFTP通道根本找不到这个目录,上传的文件也会落在SFTP自己的默认路径下,两者不在同一个位置。 - 相对路径+错误的用户名变量,完全偏离了群晖实际的文件存储位置
你用os.getenv("USERNAME")取的是自己Windows电脑的本地用户名,拿这个当远端目录名本身就不匹配群晖的文件结构。而且你用的utilisateur/test.txt是相对路径,不是绝对路径:SFTP解析相对路径时,是相对于自己默认的SFTP工作目录(一般是对应用户的系统家目录/var/services/homes/[你的SSH账号]/),这个路径下的内容在群晖File Station里默认是不展示的,你自然在自己能看到的存储目录里找不到文件。
群晖所有用户能在File Station看到的存储文件,实际都是挂载在/volume1/(或其他存储池编号的卷)路径下的,和系统家目录完全是两个位置。
可直接运行的修正代码
把所有路径逻辑改成绝对路径,全部通过SFTP通道完成目录创建和文件上传,避免跨通道的路径错位:
import paramiko # 替换为你的实际NAS信息 ip_address = "你的NAS实际IP" username = "你的NAS SSH登录账号" password = "你的NAS SSH账号密码" local_path = "d:/toto.txt" # 替换为你在群晖上实际要存放文件的绝对路径,比如/volume1/个人目录/测试文件夹 target_remote_dir = "/volume1/个人目录/测试文件夹" target_remote_file = f"{target_remote_dir}/test.txt" # 建立SSH连接 ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect(hostname=ip_address, username=username, password=password) print(f"SSH连接成功,目标IP:{ip_address}") # 开启SFTP通道 sftp = ssh_client.open_sftp() # 逐层创建目标目录(不存在时自动创建,避免报错) path_segments = target_remote_dir.strip("/").split("/") current_check_path = "" for segment in path_segments: current_check_path = f"{current_check_path}/{segment}" try: sftp.stat(current_check_path) except FileNotFoundError: sftp.mkdir(current_check_path) # 执行上传 sftp.put(local_path, target_remote_file) print(f"文件上传完成,实际存储路径:{target_remote_file}") # 关闭连接 sftp.close() ssh_client.close()
排查小提示
- 如果还是找不到文件,可以在SFTP连接建立后加一行打印
sftp.getcwd()和sftp.listdir(),就能直接看到SFTP默认的工作目录和里面的文件位置 - 确认你的SSH账号有目标存储目录的读写权限,群晖对权限不足的操作经常做静默拦截,不会抛出明确报错,表现就是操作成功但文件不见
内容的提问来源于stack exchange,提问作者user15672960
相关产品推荐
相关产品推荐

