使用ADB mv命令重命名Android文件时提示“非目录”错误求助
ADB批量重命名文件报错
mv: ... not directory的解决思路 问题背景
在Windows系统通过ADB命令重命名Android设备文件时,频繁触发以下错误:
mv: '/storage/emulated/0/Download/xrn/folder/new_name.xml' not directory
执行的ADB命令格式为:
adb shell mv /path/to/old /path/to/new
因需求限制无法在设备端用Python或应用完成批量重命名,编写了如下Python脚本遍历目录重命名,但仍会触发上述错误:
import subprocess def list_files_and_dirs(path): # Run the adb command to list files and directories result = subprocess.run(['adb', 'shell', 'ls', '-l', path], capture_output=True, text=True) # Initialize the result dictionary ret = {'files': [], 'dirs': []} # Check if the command was successful if result.returncode == 0: # Split the output into lines lines = result.stdout.splitlines() for line in lines: # Skip empty lines if not line.rstrip(): continue print(line) # Split the line into parts (you may need to alter this line according to your adb shell ls output format) try : name = line.split(':')[1][3:].replace('\\', '') except : name = '' if name != '' : # The first part indicates the type (d for directory, - for file) entry_type = line[0] # The last part is the name of the file or directory if entry_type == 'd': ret['dirs'].append(name) elif entry_type == '-': ret['files'].append(name) else: print(f"Error: {result.stderr.strip()}") return ret def new_name(n) : return b.b64encode(n. encode('utf-8')). decode('cp1250'). replace('+', '-'). replace('/', '_'). replace('=', '') + '.bn' def rename_file(old_name, new_name): # Construct the adb command to rename the file command = ['adb', 'shell', 'mv', old_name, new_name] # Run the command result = subprocess.run(command, capture_output=True, text=True) print(command) # Check if the command was successful if result.returncode == 0: print(f"Successfully renamed '{old_name}' to '{new_name}'") else: print(f"Error: {result.stderr.strip()}") def walk (p, l = 0) : array = list_files_and_dirs(p)# + '/*') for i in array['dirs'] : walk(p + '/' + i, l + 1) for i in array['files'] : print(p, '/', array) name = new_name(i) if '.bn' not in i : #print(i, name) rename_file('%s/%s' % (p, i), '%s/%s' % (p, name)) root = '/storage/emulated/0/Download/xrn' walk(root)
核心原因与解决思路
1. 文件名解析逻辑依赖不稳定的ls -l输出
当前list_files_and_dirs函数通过line.split(':')[1][3:]提取文件名,这种方式完全依赖ls -l的输出格式,一旦文件名包含冒号、空格或特殊字符,就会提取失败,生成错误路径导致mv报错。
**解决:**改用ls -1(数字1)获取纯文件名列表,再通过stat命令判断文件类型:
def list_files_and_dirs(path): result = subprocess.run(['adb', 'shell', 'ls', '-1', path], capture_output=True, text=True) ret = {'files': [], 'dirs': []} if result.returncode == 0: lines = result.stdout.splitlines() for line in lines: line = line.strip() if not line: continue # 用stat判断文件/目录类型 stat_result = subprocess.run( ['adb', 'shell', 'stat', '-c', '%F', f'{path}/{line}'], capture_output=True, text=True ) if stat_result.returncode == 0: type_str = stat_result.stdout.strip() if type_str == 'directory': ret['dirs'].append(line) elif type_str == 'regular file': ret['files'].append(line) else: print(f"Error: {result.stderr.strip()}") return ret
2. 新文件名与目录重名导致mv行为异常
当生成的新文件名恰好和当前目录下的子目录同名时,mv会尝试将文件移入该目录,而非重命名,从而触发报错。
**解决:**重命名前先检查目标路径是否存在,若存在则生成唯一文件名:
import os def check_path_exists(path): # 用test命令判断路径是否存在 result = subprocess.run( ['adb', 'shell', 'test', '-e', path], capture_output=True, text=True ) return result.returncode == 0 def rename_file(old_name, new_name): # 检查目标路径是否存在,存在则添加数字后缀 if check_path_exists(new_name): base, ext = os.path.splitext(new_name) counter = 1 while check_path_exists(f"{base}_{counter}{ext}"): counter += 1 new_name = f"{base}_{counter}{ext}" command = ['adb', 'shell', 'mv', old_name, new_name] result = subprocess.run(command, capture_output=True, text=True) print(command) if result.returncode == 0: print(f"Successfully renamed '{old_name}' to '{new_name}'") else: print(f"Error: {result.stderr.strip()}")
3. 脚本的其他潜在问题修复
new_name函数中b.b64encode缺少base64模块导入,需补充import base64,并将b.b64encode改为base64.b64encode。- 手动拼接路径易出现重复斜杠(如
//),改用os.path.join规范路径拼接:# 遍历目录时的路径拼接 walk(os.path.join(p, i), l + 1) # 重命名时的路径拼接 rename_file(os.path.join(p, i), os.path.join(p, name)) - 删除
walk函数中无用的print(p, '/', array)代码,避免干扰输出。
内容的提问来源于stack exchange,提问作者mxl
相关产品推荐
相关产品推荐

