如何在操作系统中锁定文件阻止其他应用写入?解决fcntl.flock无效问题
Hey there, let's break down why your current fcntl.flock() approach isn't stopping programs like text editors, and walk through real solutions to enforce write protection.
Why flock() Isn't Working for You
The fcntl.flock() function implements cooperative locking. That means the lock only works if other programs explicitly check for the lock using flock() too. Most common tools (like text editors, terminal utilities) don't bother checking these locks—they just open and write to the file directly, completely ignoring your lock.
Solution 1: Mandatory Record Locking (Linux-Only)
Linux supports mandatory file locking, which forces the kernel to block any write attempts from other programs, regardless of whether they check for locks. Here's how to set it up:
Prerequisites
- Your filesystem must be mounted with the
mandoption. You can remount it with root privileges:
(Note: This requires root access, and not all filesystems support mandatory locking—ext2/3/4 work, tmpfs may not.)sudo mount -o remount,mand /path/to/your/filesystem - Set the
setgidbit on your target file and remove group execute permissions:chmod g+s,g-x somefile.txt
Python Implementation
#!/usr/bin/env python3 import time import fcntl import struct # Define the flock structure (works for x86_64 systems) class flock_struct: def __init__(self): self.l_type = 0 self.l_whence = 0 self.l_start = 0 self.l_len = 0 self.l_pid = 0 file_path = './somefile.txt' with open(file_path, 'r+') as f: # Create a write lock for the entire file lock = flock_struct() lock.l_type = fcntl.F_WRLCK # Mark as write lock lock.l_whence = 0 # Start locking from file beginning lock.l_start = 0 lock.l_len = 0 # Lock the entire file try: fcntl.fcntl(f, fcntl.F_SETLK, struct.pack('hhllh', lock.l_type, lock.l_whence, lock.l_start, lock.l_len, lock.l_pid)) print("File is mandatorily locked—no other app can write to it now.") time.sleep(20) finally: # Release the lock lock.l_type = fcntl.F_UNLCK fcntl.fcntl(f, fcntl.F_SETLK, struct.pack('hhllh', lock.l_type, lock.l_whence, lock.l_start, lock.l_len, lock.l_pid))
This will block any write attempts from other programs until your lock is released. If your app crashes, the kernel will automatically release the lock.
Solution 2: Temporary File Permission Modification (Cross-Platform, but Risky)
If you can't modify filesystem mount options, you can temporarily remove write permissions from the file, then restore them when you're done.
Python Implementation
#!/usr/bin/env python3 import time import os import stat file_path = './somefile.txt' # Save the original file permissions original_stat = os.stat(file_path) original_perms = original_stat.st_mode try: # Remove write permissions for all users os.chmod(file_path, original_perms & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)) with open(file_path, 'r') as f: print("Write permissions revoked—other apps can't modify the file.") time.sleep(20) finally: # Restore original permissions (works unless the app is force-killed with kill -9) os.chmod(file_path, original_perms)
⚠️ Important Caveat: If your app is force-killed (e.g., kill -9), the finally block won't execute, and the file will remain read-only. You'll need to manually restore permissions in that case.
Solution 3: Exclusive File Creation (Only for New Files)
If you're creating the file from scratch, you can use the O_EXCL | O_CREAT flag when opening it to ensure you're the only one who can access it initially. However, this only prevents other apps from creating the same file—it doesn't block writes once the file exists, so it's only useful for new files.
Final Notes
flock()is great for coordinating access between your own processes, but useless against apps that don't check for cooperative locks.- For true system-wide write protection, mandatory locking (Solution 1) is the most reliable option on Linux.
- If you don't have root access, Solution 2 is a workable alternative, just be mindful of the permission recovery risk.
内容的提问来源于stack exchange,提问作者BPS

