java - 为什么有些命令在 Unix 上需要锁而其他命令则不需要?

标签 java unix aix io-redirection su

最近,我在我们的 AIX 7.1 环境中观察到一些有趣的事情。为了找出问题所在,我用 Java 创建了一个小型锁定应用程序:

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;

public class Locker {

    public static void main(String[] args) throws Exception {
        File file = new File("/etc/passwd");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
        FileLock lock;

        try {
            lock = channel.tryLock();

            if (lock != null) {
                System.out.println("I have the lock");
                while(true) {}
            }

        } catch (OverlappingFileLockException e) {
            e.printStackTrace();
        }

    }
}

据我所知,这会在/etc/passwd 上获得读写锁定。如果我尝试运行该应用程序的两个实例,我只能按预期获得一个实例中的锁。同样,如果我运行此命令:

su user2 -c echo test

该命令将挂起,直到我从 Java 应用程序释放锁定。另一方面,读取文件:

cat /etc/passwd

运行成功。甚至写入文件:

cat /etc/passwd > /etc/passwd

也不错。现在,显然 Java FileLock 实现是系统相关的,并且由于这种性质,没有指定的行为。然而,我很好奇的是为什么“su”需要等待。 “cat”重定向是否可能只是删除文件并使用新输出重新创建它,或者这只是锁定机制在命令之间不一致的情况?

编辑:自从提出问题以来,我向 Java 应用程序添加了一些写入语句,因此程序的结构如下:

Acquire Java Lock on /etc/passwd
IO-Redirect with a small change to /etc/passwd
Append some text to /etc/passwd in the Java application

所有这些信息都反射(reflect)在更新的/etc/passwd 中,因此 IO 重定向似乎不仅仅是删除该文件。因此,为什么“su”和“>”(可能还有许多其他东西)之间存在差异?

最佳答案

UNIX 上的文件锁定是建议性的,而不是强制的。也就是说,锁完全独立于任何试图读取或写入文件的人,并且不会产生任何影响。它只与尝试获取锁的其他程序交互。

由于 cat 和重定向不会尝试锁定文件,因此锁定对它们没有影响。 su 另一方面,在读取/etc/passwd 之前对其进行锁定,因此持有锁定的程序会导致它等待(获取锁定),直到您释放它。

关于java - 为什么有些命令在 Unix 上需要锁而其他命令则不需要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14838577/

相关文章:

linux - 在 vi 中移动光标会产生意外的字符。怎么会?

AIX 进程内存随着循环中的 malloc 释放调用而增加

linux - bash shell 脚本根据年份和月份创建子目录

java - 从第一个元素到最后一个元素迭代 json

java - lucene中为不同的查询词分配不同的权重

linux - 为什么 uniq -z 返回重复项?

linux - 在 bash 脚本中

linux - Shell 脚本正在复制父目录中的每个文件

java - 无法使用外部类路径执行类

java - Spring Security + LDAP + CustomLdapAuthoritiesPopulator + RememberMe