limits(1) describes the behavior of -n as adjusting the maximum number of open file descriptors. I think this is the correct behavior. However, the kernel seems to implement this as setting a limit on the maximum file descriptor that is opened. This leads to a number of discrepancies: - The limit can be set while there are too many open descriptors and more files can continue to be opened as long as there are free slots below the given maximum - Even if there are fewer than the given number of descriptors open, dup operations can fail if the "minimum fd" parameter to fcntl(F_DUPFD) is given. I encountered this while running testcases for git. I had dozens of file descriptors open from my desktop environment (probably shouldn't but whatever), the test (t5324-split-commit-graph.sh) sets ulimit -n32 and does some operations to make sure it works correctly under this kind of duress. It fails in confusion over some combination of the above two points.