20

I have a script for launchd to run that starts a server, then tells it to exit gracefully when launchd kills it off (which should be at shutdown). My question: what is the appropriate, idiomatic way to tell the script to idle until it gets the signal? Should I just use a while-true-sleep-1 loop, or is there a better way to do this?

#!/bin/bash

cd "`dirname "$0"`"

trap "./serverctl stop" TERM
./serverctl start

# wait to receive TERM signal.
Thom Smith
  • 13,916
  • 6
  • 45
  • 91
  • 2
    `while : ; do sleep 1 ; done` seems OK for me. – choroba Dec 01 '11 at 10:25
  • 1
    Can you get the PID of the process spawned by `serverctl`? With `jobs -p` or `pgrep -P`? – nikc.org Feb 22 '13 at 07:50
  • The actual server process is running in a `screen` session. It might not be a bad idea to await that, so that an unexpected exit will cause this script to end and alert launchd that the process is down. On the other hand, it's been fifteen months and it working fine as-is. :-P – Thom Smith Feb 22 '13 at 20:42
  • @choroba: while-sleep spawns a new process every second. Given that the server process might run for days, that does not sound like an ideal solution to me. – matlehmann Apr 10 '14 at 10:16

3 Answers3

9

You can simply use "sleep infinity". If you want to perform more actions on shutdown and don't want to create a function for that, an alternative could be:

#!/bin/bash
sleep infinity & PID=$!
trap "kill $PID" INT TERM

echo starting
# commands to start your services go here

wait

# commands to shutdown your services go here
echo exited

Another alternative to "sleep infinity" (it seems busybox doesn't support it for example) could be "tail -fn0 $0" for example.

rosenfeld
  • 1,730
  • 15
  • 19
5

A plain wait would be significantly less resource-intensive than a spin lock, even with a sleep in it.

tripleee
  • 175,061
  • 34
  • 275
  • 318
1

Why would you like to keep your script running? Is there any reason? If you don't do anything later after signal then I do not see a reason for that.

When you get TERM from shutdown then your serverctl and server executable (if there is any) also gets TERM at the same time.

To do this thing by design you have to install your serverctl script as rc script and let init (start and) stop that. Here I described how to set up server process that is not originally designed to work as server.

Community
  • 1
  • 1
Cougar
  • 651
  • 4
  • 11
  • Serverctl will not receive a TERM because it does not persist. The actual persistent process is a Minecraft server, which I can't modify and which will die immediately when it gets a TERM. Also, rc (which would otherwise be the obvious way to do this) is deprecated on the Mac OS. – Thom Smith Dec 01 '11 at 13:44