基于rpm-python-4.11.3-25模块的RPM查询Python脚本技术咨询
Hey there, let's break down your RPM query script and work through potential tweaks or issues you might be running into. First, a quick recap: your script uses the rpm-python library to find packages matching a glob pattern, print their version details, count included files, and attempt to show verification flags. Let's go over key improvements and fixes:
Key Observations & Fixes
1. Iterator Handling for Package Matches
In some versions of rpm-python, calling mi.pattern() after initializing mi = ts.dbMatch() can lead to inconsistent filtering results. A more reliable approach is to pass your glob pattern directly when creating the match set.
2. Correct Usage of fi.VFlags()
The VFlags() method of the FileInfo object requires a file index as an argument—it returns verification flags for a specific file in the package, not the entire set. Calling it without an argument will throw an error. We'll adjust this to loop through each file and display its flags.
3. Basic Error Handling
Your original script doesn't account for missing command-line arguments or no matching packages. Adding simple checks will make the script more robust and user-friendly.
Improved Script
Here's a revised version with these fixes and enhancements:
#!/usr/bin/env python import rpm import sys def main(): # Print the rpm-python library version print(f'Library version: {rpm.__version__}') # Check if a package pattern was provided if len(sys.argv) < 2: print("Error: Please provide a package name pattern (e.g., httpd*)") sys.exit(1) pkg_pattern = sys.argv[1] # Initialize transaction set and filter packages with the glob pattern ts = rpm.TransactionSet() mi = ts.dbMatch('name', rpm.RPMMIRE_GLOB, pkg_pattern) # Iterate through matching packages packages_found = False for h in mi: packages_found = True pkg_full_name = f"{h['name']}-{h['version']}-{h['release']}" print(f'##### {pkg_full_name} #####') # Get file list from the package header fi = h.fiFromHeader() file_list = [f[0] for f in fi] print(f"Number of files: {len(file_list)}") # Print human-readable verification flags for each file print("Verification flags per file:") for idx, file_path in enumerate(file_list): flags = fi.VFlags(idx) # Map bitmask values to readable labels (reference RPM docs for full list) flag_labels = [] if flags & rpm.RPMVERIFY_MD5: flag_labels.append('MD5_CHECK') if flags & rpm.RPMVERIFY_SIZE: flag_labels.append('SIZE_MISMATCH') if flags & rpm.RPMVERIFY_USER: flag_labels.append('USER_MISMATCH') if flags & rpm.RPMVERIFY_GROUP: flag_labels.append('GROUP_MISMATCH') if flags & rpm.RPMVERIFY_MTIME: flag_labels.append('MTIME_CHANGED') print(f" {file_path}: {', '.join(flag_labels) if flag_labels else 'No issues detected'}") if not packages_found: print(f"No packages matching pattern '{pkg_pattern}' were found on the system.") if __name__ == '__main__': main()
How to Run It
Use the same command as before:
python test.py httpd*
What Changed
- Error Handling: Provides clear messages if no argument is passed or no packages match the pattern.
- Reliable Filtering: Passes the glob pattern directly to
dbMatch()for consistent results across library versions. - Correct Flag Display: Loops through each file to fetch and translate verification flags from bitmasks to human-readable text.
- Cleaner Structure: Wrapped logic in a
main()function for better readability and maintainability.
If you ran into specific errors (like tracebacks) with your original script, share the full error output and we can dig deeper into those specifics!
内容的提问来源于stack exchange,提问作者HTF

