Score:2

I cannot set ulimit on subshell

ru flag

I have a bash script. This bash script needs to be ran every 5 minutes so I created this code block:

#!/bin/bash
ulimit -n 600000
ulimit -u 600000
echo -e "This is another bash script to run mybashscript.sh"

# Lets create mycronscript.sh
echo "#!/bin/bash
ulimit -n 600000
ulimit -u 600000
while true; do
sleep 300
bash mybashscript.sh
done" >> mycronscript.sh
bash mycronscript.sh&

Whenever It runs itself after 5 minutes, the mybashscript.sh isn't running properly because ulimit settings aren't applied. How can I fix it?

terdon avatar
cn flag
How are you checking this? What is the expected behavior here? The subshell won't be able to affect other shells, are you expecting the `ulimit` builtin to have some sort of effect outside the shell it is running in?
Raffa avatar
jp flag
@terdon OP seems to have included a simplified example code while their actual script has more and a limit per shell might be needed ... At least that's what I understood as the example is actually only a `sleep` call, so nothing useful is expected from that ... Erikli, is this the case? or otherwise you might be just launching subshells with `sleep` calls and the `ulimit` is internally applied to each of those shells and will have no external effects on other shells.
Cyrus avatar
cn flag
You cannot increase either value as non-root in your script.
Erikli avatar
ru flag
@Raffa Yes. That is the case. I have a application(s) that needs a lot limit more than shell default provides. So I had to set them like this. PS: I have root access.
Erikli avatar
ru flag
@terdon Since the application that I will be running to needs a lot ulimit to be ran, I can check it. If the application didn't start, then the ulimit values aren't applied properly.
Score:5
jp flag

There are two obvious issues with your code:

First, you need to use single quotes around the string after echo to prevent the shell from interpreting the ! in the shebang #!/bin/bash as the history expansion character which is expanded inside double quotes ... So it needs to look like this:

echo '#!/bin/bash
ulimit -n 600000
ulimit -u 600000
while true; do
sleep 300
bash mybashscript.sh
done' >> mycronscript.sh

You might not notice issues with that when run from inside a script in a non-interactive shell where history is not enabled by default versus when run from an interactive shell ... But, it might/will bite you back(e.g. it will automatically run the last command starting with /bin/bsh for example if you have previously run some script with /bin/bash scriptfile that command will be instantly run without asking for your confirmation at all) sometime soon e.g. when your shell settings/environment variables change to enable history in non-interactive shells.

I would, however, use better formatting mechanism alternatives for that with e.g. a Here Document like so:

cat > mycronscript.sh <<EOF
#!/bin/bash
ulimit -n 600000
ulimit -u 600000
while true; do
sleep 300
bash mybashscript.sh
done
EOF

or even the shell builtin printf(making use of its formatting capabilities) instead of echo.

Also, your use of the append operator >> might suggest that mycronscript.sh already has some lines/code and you're appending to it ... If this is the case then you'll end up with a messy unusable script ... If this is not the case, then use the > operator to overwrite the contents of the script file.

Second, you would need to run your script with elevated privileges i.e. sudo in order to increase the max user processes limit or the max open files limit ... etc. using ulimit above the hard limit ... So it needs to look like this:

sudo bash mainscript.sh

Notice: that if you use sudo on a script and send it to the background at the same time e.g.:

sudo bash mycronscript.sh &

you might need to bring that back to the foreground with fg in order to be able to enter the password for sudo or otherwise the script will be waiting for the password in the background and not executing without you noticing it ... So either run your main forground script with sudo as described above or you can login to a root shell with e.g. sudo -i then run your scripts there without sudo and be very careful as every command you run will run with root privileges.

I wouldn't be keen on using sudo inside scripts as well.

Also, please notice that ulimit is a shell builtin and it provides control over the resources available to processes started under the current shell it's run in and will have no effect on other external shells.

Also, notice that you can lower/increase the soft limit without root privileges using the -S option as long as it doesn't exceed the set hard limit ... like so:

ulimit -S -u {N}

where {N} is a number less than the hard limit ... You can print the hard limit for e.g. user processes with:

ulimit -H -u

or for all limits with:

ulimit -H -a

You can as well lower the hard limit without root privileges with e.g.:

ulimit -H -u {N}

or, as both -H and -S are the default when neither option is specified, with:

ulimit -u {N}

But, you can't raise it again without root privileges.

Erikli avatar
ru flag
I have ran ```mycronscript.sh``` with sudo but still after a while, It just stops again. (If it stops then ulimit settings aren't applied)
Raffa avatar
jp flag
@Erikli Then probably logging in to a `root` shell and running your scripts there might be what you want … Please see the description for how to do that in my answer.
Erikli avatar
ru flag
still doesn't work.
Raffa avatar
jp flag
@Erikli Are you sure your system's resources are enough for that large number of processes? ... Does your system freeze, become unresponsive or become very slow after you run your script?
Erikli avatar
ru flag
No, not at all. If you have a somewhere I can contact with you I can show my script and what it does.
Raffa avatar
jp flag
@Erikli Please add your script to your question as an [edit](https://askubuntu.com/posts/1464412/edit) so that we can look at it ... Please, also tell us why you think it's not working? ... how do you measure/know that? What do you expect to happen? in detail please.
Erikli avatar
ru flag
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/145484/discussion-between-erikli-and-raffa).
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.