Linux bash start process

How do I write a bash script to restart a process if it dies?

How do I write a bash script that will check if it’s running, and if not, start it. Roughly the following pseudo code (or maybe it should do something like ps | grep ?):

# keepalivescript.sh if processidfile exists: if processid is running: exit, all ok run checkqueue.py write processid to processidfile 
# crontab */5 * * * * /path/to/keepalivescript.sh 

Just to add this for 2017. Use supervisord. crontab is not mean to do this kind of task. A bash script is terrible on emitting the real error. stackoverflow.com/questions/9301494/…

How about using inittab and respawn instead of other non-system solutions? See superuser.com/a/507835/116705

10 Answers 10

Avoid PID-files, crons, or anything else that tries to evaluate processes that aren’t their children.

There is a very good reason why in UNIX, you can ONLY wait on your children. Any method (ps parsing, pgrep, storing a PID, . ) that tries to work around that is flawed and has gaping holes in it. Just say no.

Instead you need the process that monitors your process to be the process’ parent. What does this mean? It means only the process that starts your process can reliably wait for it to end. In bash, this is absolutely trivial.

until myserver; do echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2 sleep 1 done 

The above piece of bash code runs myserver in an until loop. The first line starts myserver and waits for it to end. When it ends, until checks its exit status. If the exit status is 0 , it means it ended gracefully (which means you asked it to shut down somehow, and it did so successfully). In that case we don’t want to restart it (we just asked it to shut down!). If the exit status is not 0 , until will run the loop body, which emits an error message on STDERR and restarts the loop (back to line 1) after 1 second.

Why do we wait a second? Because if something’s wrong with the startup sequence of myserver and it crashes immediately, you’ll have a very intensive loop of constant restarting and crashing on your hands. The sleep 1 takes away the strain from that.

Читайте также:  Нет сети linux ubuntu

Now all you need to do is start this bash script (asynchronously, probably), and it will monitor myserver and restart it as necessary. If you want to start the monitor on boot (making the server «survive» reboots), you can schedule it in your user’s cron(1) with an @reboot rule. Open your cron rules with crontab :

Then add a rule to start your monitor script:

@reboot /usr/local/bin/myservermonitor 

Alternatively; look at inittab(5) and /etc/inittab. You can add a line in there to have myserver start at a certain init level and be respawned automatically.

Let me add some information on why not to use PID files. While they are very popular; they are also very flawed and there’s no reason why you wouldn’t just do it the correct way.

  1. PID recycling (killing the wrong process):
    • /etc/init.d/foo start : start foo , write foo ‘s PID to /var/run/foo.pid
    • A while later: foo dies somehow.
    • A while later: any random process that starts (call it bar ) takes a random PID, imagine it taking foo ‘s old PID.
    • You notice foo ‘s gone: /etc/init.d/foo/restart reads /var/run/foo.pid , checks to see if it’s still alive, finds bar , thinks it’s foo , kills it, starts a new foo .
  2. PID files go stale. You need over-complicated (or should I say, non-trivial) logic to check whether the PID file is stale, and any such logic is again vulnerable to 1. .
  3. What if you don’t even have write access or are in a read-only environment?
  4. It’s pointless overcomplication; see how simple my example above is. No need to complicate that, at all.

By the way; even worse than PID files is parsing ps ! Don’t ever do this.

  1. ps is very unportable. While you find it on almost every UNIX system; its arguments vary greatly if you want non-standard output. And standard output is ONLY for human consumption, not for scripted parsing!
  2. Parsing ps leads to a LOT of false positives. Take the ps aux | grep PID example, and now imagine someone starting a process with a number somewhere as argument that happens to be the same as the PID you stared your daemon with! Imagine two people starting an X session and you grepping for X to kill yours. It’s just all kinds of bad.
Читайте также:  Справочник системный администратор linux

If you don’t want to manage the process yourself; there are some perfectly good systems out there that will act as monitor for your processes. Look into runit, for example.

Источник

Bash script to start process, wait random, kill process, restart

I’m an absolute beginner and am trying to create a bash script to randomize the start and exit of a command line app. I plan to autostart the script on boot (Crunchbang) after a slight delay with the following in autostart.sh (found here: http://interwebworld.co.uk/2011/10/23/how-to-launch-programs-automatically-at-startup-in-crunchbang-linux/ )

(sleep 300s && /home/myuser/Scripts/randomizer.sh) & 
start applicationfile wait a random period of time if applicationfile is still running kill its process wait a random period of time exit this script and restart this script else exit this script and restart this script 

The randomizer.sh as I have it so far and which I’d welcome some help with, is as follows (containing remnants of the pseudocode), and the sleep delay found here: http://blog.buberel.org/2010/07/howto-random-sleep-duration-in-bash.html

/path/to/applicationfile -s 111.222.333.444 -u username -p password sleep $[ ( $RANDOM % 150 ) + 60 ]m if applicationfile is still running kill $(ps aux | grep '[u]sername' | awk '') sleep $[ ( $RANDOM % 150 ) + 60 ]m exec $randomizer.sh else exec $randomizer.sh 

I «think» the non-pseudo parts should work pretty much as they are, but please correct me or adjust if I’m wrong. The initial applicationfile command line works as it is, and I already tested the process kill line and it works as expected. Applicationfile doesn’t have a built-in way to end itself from commandline, but the dead connection on the remote machine will be killed after 5 minutes of being killed locally, so killing it locally is acceptable for my needs. What I don’t have any idea how to handle is the line above the kill, which checks «if» the process is running in the first place. Sorry for the wall of text but I wanted to show I’ve done as much as I could already.

Читайте также:  Linux create uefi bootable usb

Источник

Bash script to start and then shutdown/restart various processes

When I start up my development environment, there are a variety of processes I need to run in the background. It is a pain to start them all individually so I want to write a script that starts each one. I can do this just fine but the problem comes when I need to restart them (something I will need to do regularly). What is the easiest way to capture the process upon starting it and saving that information so that when I run the script again, it will check to see if that information has been saved and then close down those processes before restarting them. I also want the script to be flexible enough such that if I shutdown the process manually, it will a) not throw an error if it can’t find the process and b) not accidentally shut down some other process that has since then shared whatever identifying information I have stored.

Update

  1. Change to my working directory
  2. Start faye as a background process
  3. Start watchr as a background process
  4. Start passenger
#!/bin/bash cd ~/path/to/my/working-directory rackup faye.ru -s thin -E production & watch refresh.watchr & passenger start 

This works fine but the problem comes when I need to restart all these processes. I first have to track down all their process ids and then kill them before running start-dev again. Therefore I would like to:

4) Type a short command like «restart-dev» which tracks down the processes I have previously run in the background and then kill them before running «start-dev» again. It needs to be able to not throw an error if I have shut down any of these manually and not accidentally shutdown an incorrect process.

Источник

Оцените статью
Adblock
detector