Python执行rsync复制文件后无法立即获取目标目录文件列表的解决请求
问题解决:rsync执行后立即获取目录文件列表
问题原因
用os.popen(query)调用rsync时,该方法是非阻塞的——代码会立刻执行后续的os.chdir和glob操作,但此时rsync可能还在后台传输文件,导致glob获取到空列表。拆分脚本手动执行时,rsync已完成传输,因此能正常获取文件。
解决方案
方案1:基于os.popen等待进程结束
os.popen返回的文件对象调用close()方法会等待子进程执行完毕,之后再进行后续操作:
import os import glob query = 'rsync -zavP server@10.10.0.160:/home/server/Catalog/ /home/user/sample' # 执行rsync并等待完成 pipe = os.popen(query) pipe.close() os.chdir('/home/user/sample') files = glob.glob('*.*') # 注意:原代码的*.*需加引号,否则会触发语法错误 print(files)
方案2:使用subprocess模块(推荐)
subprocess是Python官方推荐替代os.popen的模块,默认阻塞执行命令,功能更安全强大:
import subprocess import glob import os # 将命令拆分为列表形式,避免shell注入风险 query = ['rsync', '-zavP', 'server@10.10.0.160:/home/server/Catalog/', '/home/user/sample'] # 执行命令并等待完成,check=True会在命令执行失败时抛出异常 subprocess.run(query, check=True) os.chdir('/home/user/sample') files = glob.glob('*.*') print(files)
额外提示
- 若需要捕获rsync的输出内容,可给
subprocess.run()添加stdout=subprocess.PIPE和stderr=subprocess.PIPE参数。 - 原代码中
glob.glob(*.*)存在语法错误,必须将通配符用引号包裹,否则Python会将*.*视为变量解析。
内容的提问来源于stack exchange,提问作者glukoff
相关产品推荐
相关产品推荐

