Why doesn't ulimit -n work when called inside a script?

5

This is very odd. I'm trying to set the ulimit to 60000 via my startup.sh:

#!/bin/bash

ulimit -n 60000
echo "Hello! File Descriptor set"

I can execute this with ./startup.sh (755 file permissions) and the echo line is printed, and no errors are shown. However, when I do ulimit -n it still shows 1024, what's going on?

What I also find fascinating is I can type ulimit -n 60000 in the terminal, and then do ulimit -n and it works perfectly. Why can't I set the file descriptor limit through a script?

Debian 8, 64-bit. OpenVZ Container

John Miller

Posted 2018-01-26T20:00:03.423

Reputation: 53

Answers

5

ulimits are per-process, not per-user nor per-system.

The ulimit command is built into the shell, so it remains within the same process; however, the adjusted limit only affects that process, as well as everything you run from it (child processes inherit the same limits).

However, ./startup.sh runs as a separate process – therefore it successfully adjusts its own limits but this does not magically propagate upwards to its parent.

(This is the same situation as with cd or `export – even though you can use those in a script, they all change parameters of the script's own process, not of the whole system, and will be forgotten once the script's process exits.)

Note: There is another command, prlimit, which lets you adjust resource limits of another process (specified by PID). A script could change the file limit of its parent process like this:

prlimit --pid=$PPID --nofile=4096

user1686

Posted 2018-01-26T20:00:03.423

Reputation: 283 655

Awesome, thank you for the detailed explanation. Kept thinking it was a global setting or something. – John Miller – 2018-01-26T21:12:23.793

@John Normally the closest thing to a global setting would be /proc/sys/fs/file-max. Since you're inside a container, OpenVZ may also be applying various limits seen in /proc/user_beancounters. – user1686 – 2018-01-26T21:16:09.720