我在 Ubuntu Server 中有一个文件夹,来自不同客户端计算机(也是 Ubuntu)的用户可以编辑文件(通过 FileZilla,但任何其他方式都可以)。但是,当一个用户正在编辑一个文件时,该文件应该锁定这样其他人就无法同时编辑它。这应该是预期的行为(而且确实如此,别处)。如何在 Ubuntu Server 14.04 中实现此操作?这看起来是一项简单甚至显而易见的任务,但我就是找不到它。Google 只给我“如何解锁被别人锁定的文件”。
编辑
根据 Lmwangi 的建议,我尝试创建一个 bash 脚本来自动执行该任务。首先,我使用 NFS 在客户端计算机上挂载服务器文件夹的映像。然后,我在服务器文件夹上创建了以下脚本:
flock -nx "$1" xdg-open "$1"
仍然无法测试它。
答案1
应该锁定 ...预期的行为...
您对 Linux 上的文件锁定语义的理解是错误的。从给出的参考链接来看,您的假设是基于 Windows 文件语义的。它们不适用于大多数基于 unix 的系统。
我找不到非常权威的来源,但是维基百科却很容易测试。
https://en.wikipedia.org/wiki/File_locking#In_Unix-like_systems
类 Unix 操作系统(包括 Linux 和 Apple 的 OS X)通常不会自动锁定打开的文件或正在运行的程序。
(维基百科关于运行程序的说法实际上是错误的,所以我对其进行了编辑!)
在 Linux 上,其正常操作是允许多个写入器和读取器同时对同一个文件进行操作。
唯一不成立的情况是当文件本身是当前已加载的可执行对象并且您请求写访问权限时。
文件锁定是非强制选项,通过或完成fcntl
,所有使用该文件的应用程序必须支持并使用相同的锁定方法才能工作。flock
lockf
另一种常用方法是创建一个新文件,该文件是旧文件的副本,作为临时命名的文件,然后重命名旧文件。这种方法可行,因为所有重命名在 posix 兼容文件系统上都是原子的——人们将看到旧文件或新文件,但不会同时看到两者。
如果您想实现多个作者编辑同一个文件,您可能需要采用类似的方法,git
以便用户可以将更改推送到更改存储库。
或者,只需使用具有锁定功能的 Windows 系统,您就会明白此功能是否对您至关重要。
答案2
取决于访问文件的模式。例如,
- 脚本/代码正在访问共享资源:通过 NFS 共享挂载,然后使用独占 flock(man flock 有示例)作为脚本的包装器。如果您正在编写 C/python/perl/... 程序,您的环境应该允许您访问 flock 系统调用。
- 用户正在访问文件:这可能有点棘手。如果用户正在访问相同的文件并相互干扰,则由他们使用的程序来检测多用户访问。例如,vim 将通过 .swp 系统在单个文件级别检测打开的文件。如果您可以编写程序启动器脚本,也许用 flock 包装它会有所帮助?
羊群帮助:
❯ flock -h
Usage:
flock [-sxun][-w #] fd#
flock [-sxon][-w #] file [-c] command...
flock [-sxon][-w #] directory [-c] command...
Options:
-s --shared Get a shared lock
-x --exclusive Get an exclusive lock
-u --unlock Remove a lock
-n --nonblock Fail rather than wait
-w --timeout Wait for a limited amount of time
-o --close Close file descriptor before running command
-c --command Run a single command string through the shell
-h --help Display this text
-V --version Display version
例子。
第一个子 shell 获取 20 秒的锁,然后被推送到后台。如果获取了锁,任何其他进程(第二个进程)都会立即失败。
❯ (flock -nx /tmp/a sleep 20 && echo nice..)& flock -nx /tmp/a sleep 20 || echo failed to lock ⏎
[1] 2546
failed to lock
❯ jobs
[1] + running ( flock -nx /tmp/a sleep 20 && echo nice..; )
❯ nice..
[1] + 2546 done ( flock -nx /tmp/a sleep 20 && echo nice..; )
---编辑
# Flock using a lock file based on the md5 of the content. I'm being lazy here. I should md5 the filename...
❯ open_something() { md5="$( md5sum "$1" | awk '{print $1}'; )"; flock -nx "/tmp/lock_${md5}" vim "$1" || echo "Oops. Go Already in use."; };
# So now let's vim a file and background it immediately.
❯ open_something /tmp/a;
[1] + 9185 suspended open_something /tmp/a
❯ jobs;
[1] + suspended (signal) open_something /tmp/a
# Let's see whether flock created a lock file based on the md5 of the file and who's using it...
❯ ls /tmp;
vagrant VMwareDnD vmware-root a lock_d41d8cd98f00b204e9800998ecf8427e vgauthsvclog.txt.0
❯ fuser '/tmp/lock_d41d8cd98f00b204e9800998ecf8427e';
/tmp/lock_d41d8cd98f00b204e9800998ecf8427e: 9175 9176
# Another user/process tries to open the file
❯ open_something /tmp/a;
Oops. Already in use.
# Let's kill the original vim process and another process can now acquire the lock.
❯ fg;
[1] + 9185 continued open_something /tmp/a
vagrant@ubuntu-trusty ~ ❯❯❯ open_something /tmp/a;
答案3
FTP(filezilla)不支持锁定。也许如果你设置了 NFS 或 SaMBa,然后使用普通文件编辑器锁定就可以了。
答案4
简单来说,FTP不支持锁定。
原因很简单:通过 FTP 协议编辑文件时,你实际上是不是编辑服务器端文件本身,而不是编辑下载的副本然后使用与原始文件相同的路径/名称重新上传。
另一方面,NFS 或 SMB 等协议是块交换协议,允许客户端软件直接编辑。
简而言之:如果您需要锁定,FTP 不是合适的工具。