在Python中os.access()失效时,如何检测文件是否为可执行文件?
解决Python脚本识别Linux下可执行文件的问题
原代码的核心问题
你的代码有两个关键错误:
- 路径拼接错误:手动拼接
parent_dir + libs + "/"容易在parent_dir末尾无斜杠时生成无效路径,而且os.walk遍历得到的file是文件名,不是完整路径,os.access(file, os.X_OK)会检查当前工作目录下的文件,而非目标文件夹中的文件。 - 权限判断局限:
os.X_OK仅检查文件权限位的执行权限,但你遇到的文件是「格式为可执行但权限位无X」的情况,这种单纯靠权限位判断会漏识别。
修正后的解决方案
下面的代码会同时处理路径问题,并结合权限位检查和文件格式识别来找到所有可执行文件:
基础版本(兼容Python3.6+)
import os parent_dir = "/你的父文件夹路径" for lib_name in os.listdir(parent_dir): lib_path = os.path.join(parent_dir, lib_name) # 跳过非目录项 if not os.path.isdir(lib_path): continue for root, _, files in os.walk(lib_path): for file_name in files: full_path = os.path.join(root, file_name) # 先检查权限位的执行权限 if os.access(full_path, os.X_OK): print(full_path) continue # 检查是否为Linux可执行ELF格式(即使权限无X) try: with open(full_path, 'rb') as f: # ELF文件的魔数是\x7fELF if f.read(4) == b'\x7fELF': print(full_path) except (PermissionError, IsADirectoryError): # 跳过无权限读取的文件或误判的目录 continue
进阶版本(区分可执行文件与共享库)
如果需要排除共享库(.so文件),只保留真正的可执行程序,可以通过解析ELF文件头的类型实现:
import os import struct def is_standalone_executable(file_path): """判断文件是否为独立可执行ELF(排除共享库)""" try: with open(file_path, 'rb') as f: header = f.read(20) if len(header) < 20 or header[:4] != b'\x7fELF': return False # 区分32位/64位ELF ei_class = header[4] if ei_class == 1: # 32位ELF e_type = struct.unpack('<H', header[16:18])[0] elif ei_class == 2: # 64位ELF e_type = struct.unpack('<H', header[18:20])[0] else: return False # ET_EXEC表示独立可执行文件,ET_DYN是共享库 return e_type == 2 except Exception: return False parent_dir = "/你的父文件夹路径" for lib_name in os.listdir(parent_dir): lib_path = os.path.join(parent_dir, lib_name) if not os.path.isdir(lib_path): continue for root, _, files in os.walk(lib_path): for file_name in files: full_path = os.path.join(root, file_name) if os.access(full_path, os.X_OK) or is_standalone_executable(full_path): print(full_path)
关键说明
- 使用
os.path.join拼接路径,避免手动拼接的兼容性问题。 - 通过读取文件魔数识别ELF格式,解决「权限无X但格式为可执行」的场景。
- 进阶版的函数可以精准区分独立可执行程序和共享库,根据你的需求选择即可。
内容的提问来源于stack exchange,提问作者Hashem HZ
相关产品推荐
相关产品推荐

