How to run a normal C program using monit - linux

I'm trying to monitor a normal C program in Monit, but I don't know how to run the program, what configuration should be set in the control file of Monit.

You need to get the PID of the program to be able to monitor it with Monit. Some programs allow commandline arguments to give the location of a file that they are to write their PID to. Otherwise, you can try starting the program from a wrapper script that writes the PID to a known location, e.g. /usr/bin/myprogram & && jobs -p > /var/run/myprogram.pid in bash.

Related

How to start C Program on Server to run in background

I have programmed a C program and tested it on my linux computer.
I have uploaded it to my server now and want it to run there the entire time as a background progress.
How is it possible to start a program which will continue to run after i close putty?
Thanks for any help!
you can leave the program running by adding a & to the call
So when you have been executing your code before like this in SSH:
./mycode
you would to it like:
./mycode &
If you want running your program in background you must add the '&' character to command.
./program &
But the process will be associated to the current tty. If you close the current tty (in your case the SSH session) the SIGHUP signal is sent to all processes associated with the tty, causing them finish. You can see the associated tty to one process with ps command.
The disown command can be used to mark jobs so that a SIGHUP signal is not sent to them if the parent shell receives it. Before closing the current tty you can write:
disown %jobID
You can see the jobID enclosed in brackets when you run the program in background. Also you can see the jobID with jobs command.
You can run the command directly so that a SIGHUP signal is not sent to him. For this you can use nohup command.
nohup ./program &
Another way to avoid ending the program with the SIGHUP signal is to catch this signal in the program. In a C program you can do this with signal function that is in signal.h
But if you want run the program as a daemon or server, better write a Systemd service or a System V init script.
In the middle of the executing your program, if you want to run your program in background.
First press ctrl + z then type bg.

Is there a way to run a shell script as one whole task(with single PID)?

I have a shell script called run.sh. In it, I may call other shell scripts like:
./run_1.sh
./run_2.sh
.........
If I call the script by ./run.sh, I have found actually it will invoke different tasks inside the script sequentially with different PIDs(i.e., run_1.sh will be a task and run_2.sh will be another task). This disables me to kill the whole group of tasks using one "kill" command or run the whole group of tasks all in background by running "./run.sh &".
So is there a way to run the script just as one whole task?
pkill can be used for killing the children of a process, using the -P option.
pkill -P $PID
where $PID is the PID of the parent process.
You can source the run_1.sh command so that it is executed in the same shell (This could cause side effects, since now all scripts will share the same scope).
source run_1.sh
source run_2.sh

Launch gdb automatically on Linux

Is there a way to automatically start a process under gdb on Linux? An equivalent of setting the Image File Execution Options on Windows.
I am trying to debug start-up phase of a process that is launched from another one.
I would normally move the real program out of the way, and replace it with a script that launches the program under GDB with the same parameters.
#!/bin/bash
exec gdb -args <realprog> "$#"
If that doesn't work due to the output being redirected to file, or something, then try this:
#!/bin/bash
exec xterm -e gdb -args <realprog> "$#"
That should give you a pop-up terminal with GDB running inside.
You don't have to go through all that registry voodoo on Linux :)
Simply:
1) Rename your program
2) Write a shell script that calls gdb with your (renamed) program and passes any arguments you want. Make sure you "chmod +rx" your script.
3) Name the shell script the original name of your program, and put it in the same directory as your program
4) Execute!

How to restart background php process? (how to get pid)

I'm a PHP developer, and know very little about shell scripting... So I appreciate any help here.
I have four php scripts that I need running in the background on my server. I can launch them just fine - they work just fine - and I can kill them by looking up their PID.
The problem is I need my script to, from time to time, kill the processes and restart them, as they maintain long standing HTTP requests that sometimes are ended by the other side.
But I don't know how to write a command that'll find these processes and kill them without looking up the PID manually.
We'll start with one launch command :
/usr/local/php5/bin/php -f /home/path/to/php_script.php > /dev/null &
Is there a way to "assign" a PID so it's always the same? or give the process a name? and how would I go about writing that new command?
Thank you!
Nope, you can't "assign" the process PID; instead, you should do as "real" daemons do: make your script save its own PID in some file, and then read it from that file when you need to kill.
Alternative would be to use something like supervisor, that handles all that for you in a quite nice way.
Update - supervisor configuration
Since I mentioned supervisor, I'm also posting here a short supervisor configuration file that should do the job.
[program:yourscriptname]
command=/usr/local/php5/bin/php -f /home/path/to/php_script.php
Have a look here for more configuration options.
Then you can use it like this:
# supervisorctl status
to show the process(es) status.
# supervisorctl start yourscriptname
to start your script
# supervisorctl stop yourscriptname
to stop your script
Update - real world supervisor configuration example
First of all, make sure you have this in your /etc/supervisor/supervisord.conf.
[include]
files = /etc/supervisor/conf.d/*.conf
if not, just add those two lines and
mkdir /etc/supervisor/conf.d/
Then, create a configurtion file for each process you want to launch:
/etc/supervisor/conf.d/script1.conf
[program:script1]
command=/usr/local/php5/bin/php -f /home/path/to/php_script.php
stdout_logfile=/var/log/script1.log
stderr_logfile=/var/log/script1-error.log
/etc/supervisor/conf.d/script2.conf
[program:script2]
command=/usr/local/php5/bin/php -f /home/path/to/php_script2.php
stdout_logfile=/var/log/script2.log
stderr_logfile=/var/log/script2-error.log
...etc, etc.. for all your scripts.
(note that you don't need the trailing & as supervisor will handle all the daemonization thing for you; in fact you shouldn't execute programs that are self-daemonizing inside supervisor).
Then you can start 'em all with:
supervisorctl start all
or just one with something like:
supervisorctl start script1
Starting supervisor from php
Of course, you can start/stop the supervisor-controlled processes using the two commands above, even from inside a script.
Remember however that you'll need root privileges, and it's quite risky to allow eg. a web page to execute commands as root on the server..
If that's the case, I recommend you have a look at the instructions on how to run supervisor as a normal user (I never did that, but you should be able to run it as the www-data user too..).
The canonical way to solve this is to have the process write its PID into a file in a known location, and then any utility scripts can look up the file, read the PID, and manipulate that process. Add a command line argument to the script that gives the name of the PID file to write to.
A work around to this would be to use ps aux, this will show all of the processes with the command that called them. This presumes of course that the 4 scripts are different files, or can be uniquely identified by the command that called them. Pipe that through a grep and you're all set ps aux | grep runningscript.php
OK! so this has been a headache and a half for my who knows NOTHING about shell/bash whatever scripting...
#redShadow 's response would had been perfect, except my hosting provider will not give me access to the /etc/supervisor/ directory. as he said, you must be root - and even using sudo was an admin wouldn't let me make any chances there...
Here's what I came up with:
kill -9 `ps -ef | grep php | grep -v grep | awk '{print $2}'`
because the only types of commands I was executing showed up in the top command as php this command loops thru running processes, finds the php commands and their corresponding PIDs and KILLS them! woot!!
What I do is have my script check for a file that I name "run.txt". If it does not
exist, they exit. Then just br renaming that (empty) file, I can stop all my scripts.

How to capture pid of a linux daemon run from init.d

I have started a service daemon , by running the binary(written in C++) through script file stored rc5.d .
But I am not sure how to capture the pid of the daemon process and store it in pid file in /var/run/.pid . So that I can use the pid for termination.
How can I do this?
Try using start-stop-daemon(8) with the --pidfile argument in your init script. Have your program write its PID to a specified location (usually determined in a configuration file).
What you have to look out for is stale PID files, for instance, if a lock file persisted across a reboot. That logic is best implemented in the init script itself, hence the --exec option to start-stop-daemon.
E.g, if /var/run/foo.pid is 1234, and /proc/1234/exe isn't your service, the lock file is stale and should be quietly removed, allowing the service to start normally.
As far as your application goes, just make sure the location of the lockfile is configurable, and some means exists to tell the init script where to put it.
For instance: (sample: /etc/default/foo) :
PIDFILE=/var/run/foo.pid
OTHEROPTION=foo
Then in /etc/init.d/foo :
[ -f /etc/default/foo ] && . /etc/default/foo
Again, other than writing to the file consistently, all of this logic should be handled outside of your application.
If you know the port the program has open, use fuser command to determine the pid.
You could go about more than one way:
In your program use getpid to write it to a configurable file (perhaps looking in ENV)
Use $! after starting the program (this doesn't work for me on archlinux though :-?)
After starting the program, use pidof

Resources