如何用Python递归移除目录及所有子目录、文件的写入权限?
chmod -R a-w) Got it, you want to replicate the Bash command chmod -R a-w $path in Python—removing write permissions for all users (owner, group, others) across a directory and every file/subdirectory inside it. Since Python's built-in os.chmod doesn't have a recursive=True parameter, we need to handle the directory traversal ourselves. Here are two clean ways to do this:
Method 1: Using os.walk (classic approach)
This uses the standard os module to walk through every file and directory, adjusting permissions one by one:
import os def remove_recursive_write_permissions(path): # Traverse the directory tree top-down for root, dirs, files in os.walk(path): # Update permissions for subdirectories first for dir_name in dirs: dir_path = os.path.join(root, dir_name) # Get the current permission mode current_mode = os.stat(dir_path).st_mode # Remove write permissions for all users (a-w = ~0o222 in octal) new_mode = current_mode & ~0o222 os.chmod(dir_path, new_mode) # Then update permissions for files for file_name in files: file_path = os.path.join(root, file_name) current_mode = os.stat(file_path).st_mode new_mode = current_mode & ~0o222 os.chmod(file_path, new_mode) # Example usage remove_recursive_write_permissions("/your/target/directory")
How it works:
os.walk(path)iterates through every directory and file under the target path.os.stat(item).st_modegets the current permission bits of the file/directory.- The bitwise operation
& ~0o222clears the write bits for all users:0o222is octal for owner write (200), group write (020), others write (002)~0o222flips those bits to 1s, and ANDing with the current mode turns off those write permissions.
Method 2: Using pathlib (modern Python 3.4+)
If you prefer a more object-oriented approach, pathlib makes this cleaner:
from pathlib import Path def remove_recursive_write_permissions(path): target_dir = Path(path) # Recursively match all files and subdirectories (excludes the root itself) for item in target_dir.rglob("*"): current_mode = item.stat().st_mode item.chmod(current_mode & ~0o222) # Don't forget to update the root directory's permissions too! root_mode = target_dir.stat().st_mode target_dir.chmod(root_mode & ~0o222) # Example usage remove_recursive_write_permissions("/your/target/directory")
Note:
rglob("*") matches every item inside the target directory, but not the directory itself—hence the separate step to update the root's permissions.
Adding Error Handling
If you're dealing with a directory where you might not have full permissions, add try-except blocks to avoid crashes:
from pathlib import Path import traceback def remove_recursive_write_permissions(path): target_dir = Path(path) for item in target_dir.rglob("*"): try: current_mode = item.stat().st_mode item.chmod(current_mode & ~0o222) except PermissionError: print(f"Skip {item}: Insufficient permissions to modify") except Exception as e: print(f"Unexpected error processing {item}: {str(e)}") traceback.print_exc() # Handle root directory try: root_mode = target_dir.stat().st_mode target_dir.chmod(root_mode & ~0o222) except PermissionError: print(f"Skip root directory {target_dir}: Insufficient permissions") except Exception as e: print(f"Unexpected error processing root {target_dir}: {str(e)}") traceback.print_exc()
Customizing Permissions
If you don't want to remove write permissions for all users, adjust the octal value:
- Remove only others' write permissions:
~0o002 - Remove group and others' write permissions:
~0o022 - Remove only owner's write permissions:
~0o200
内容的提问来源于stack exchange,提问作者wotanii

