Run a process to particular/dedicated pid only
I have a c program executable or shell script which I want to run very often. If I want to stop/pause or to notify something I will send signal to that process. So every time I have to check the pid of that process and I have to use kill to send a signal. Every time I have to check pid and remembering that upto system shutdown, really bad. I want that process has to run on particular pid only like init always run on 1. Is there any C api for that? and Also needed script for bash program.
@SGG There’s no way to set a processes PID. That would cause all kinds of trouble. But you can use killall instead of kill which takes a program name instead of its PID. Or does your program name change that often?
Note that just looking at the pid file is not enough to know if the process is running. If the power died, the file would be left behind so you should read the pid in the file and then check that a process with that pid is running. Of course, even this isn’t fool-proof as another process may have started with the same pid. See Goldilock’s answer for how to check it’s the right process
5 Answers 5
I don’t think you can reserve or assign PIDs. However, you could start your process in a script like this:
myprocess & echo "$!" > /tmp/myprocess.pid
This creates a «pid file», as some other people have referred to it. You can then fetch that in bash with, e.g., $(
Just beware when you do this that if the process died and the pid was recycled, you’ll be signalling the wrong thing. You can check with:
pid=$(cat /tmp/myprocess.pid) if [ "$(ps -o comm= -p "$pid")" = "myprocess" ]; then . send your signal. else echo "Myprocess is dead!" fi
See comments if «$(ps -o comm= -p «$pid»)» looks strange to you. You may want to do a more vigorous validation if there is a chance of someone doing something devious with the content of /tmp/myprocess.pid (which should not be writeable by other users!).
Why wouldn’t you want to add a newline? Without it, you obtain a non-text file. Use printf instead of echo -n , not all implementations of echo support -n . Use = instead of == , comm instead of cmd , $(cat< instead of $(< for portability (and quote your variables).
The -n switch to echo is pointless here. It’s perfectly fine to have a newline after the number, and in fact it’s preferable because otherwise the pidfile wouldn’t be a text file and some utilities might choke on it.
@Gilles Dunno where I acquired this issue with newlines in pid files but after observing 1) they generally do have such and 2) I can’t cause a problem with same, I’ve taken that bit out!
Note that processes can change their names and another process can start with the same pid and name. Another option could be to record the output of pid -o lstart= -p «$!» (if on Linux) in the pid file and compare when it comes to killing the process.
Fixing the pid is definitely the wrong solution to your problem, but note that with some versions of Linux, you can get a better chance to obtain the pid you’d like by writing a value to /proc/sys/kernel/ns_last_pid :
echo 9999 | sudo tee /proc/sys/kernel/ns_last_pid; ps -C ps 9999 PID TTY TIME CMD 10000 pts/3 00:00:00 ps
That only works if the pid 10000 is not already in use (and there’s been no pid or thread creation between the time you write to ns_last_pid and you spawn a process/thread).
Otherwise, you can always fork until you get the pid you like.
Since (official) kernel v3.3. This method is used by CRIU for PID restoration in process checkpoint and restore, it’s flock-able, and requires kernel option CONFIG_CHECKPOINT_RESTORE . See also the link added by Ciro to the question.
Something similar to what you want to do is normally done by the process early in its lifecycle writing out its own pid (which can be obtained through getpid(2) ) to a file with a known name. In general-use daemons the name of this file is often configurable, but in a special-use software you can probably get along with hardcoding it. (I strongly suggest at least using a macro for it, however.)
PID files are normally placed in /var/run or /run, but can be placed in other locations as well including /tmp. The «proper» location according to the Filesystem Hierarchy Standard is in /run, but /var/run also sees significant use (and on many modern systems is the same as /run) and /tmp don’t require root privileges on startup (which system daemons very often have before they drop privileges).
That file can then be read through a variety of means to obtain the PID of the process in question, in order to send a signal to it process in question.
+1 Note /var and /run require privileges to write to (which system daemons usually have, at least at start-up). If you don’t want to do that, /tmp , or some custom location, is fine.
You can not set the PID, but you can set the PGID: create or join a process group. Then you can send signals to this dedicated process group.
I had the impression that the new systemd init system has some automation on this part, which is superior to having the process to write its PID to a PID file and then using it for controlling it.
systemd seems to switch to a «process group» (as I can understand this) before starting a controlled process, and then everything is in this group. So, you can control all the child processes by remembering the special «group».
- If it functions like, this is superior to having the process to write out its PID, because you don’t need to modify the program.
- It might also be better then: myprocess & echo $! > /tmp/myprocess.pid
because this approach captures all the children of that process, too.
I don’t have a detailed documentation at hand to support my words, but here is the general idea of what systemd needs from cgroups,a nd this seems to match my impression:
Control Groups are two things: (A) a way to hierarchally group and label processes, and (B) a way to then apply resource limits to these groups. systemd only requires the former (A), and not the latter (B). That means you can compile your kernel without any control group resource controllers (B) and systemd will work perfectly on it. However, if you in addition disable the grouping feature entirely (A) then systemd will loudly complain at boot and proceed only reluctantly with a big warning and in a limited functionality mode.
Restart process on linux by its pidn number with kill command, how?
Well, I want to be able to restart processes on linux and so I looked into kill manpages for that. Apparently kill -l would list all the signals I could send to a process to do what I need, which are:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
I thought that I would get the desired effect by using SIGSTOP signal (number 19) and then SIGCONT signal (number 18) like this:
kill -19 $PID_NUMBER # It stops! nice, we are reaching just what we wanted. kill -18 $PID_NUMBER # Ok. it continues to death. that isn't funny though.
I also tried with signal number 1 : SIGHUP with pretty much the same results, am I missing something? Does anyone know what I need to reach what I want?
2 Answers 2
There is no “restart” signal. You need to record the environment (environ, cwd, cmdline, security context…) from /proc/ and manually start the process again.
SIGHUP is close, but it is only used by convention to ask the program to reload its settings.
SIGHUP is the ‘abbreviation’ of Hang Up. Like a telephone conversation. It is typically used in such situation where the running program is prepared to receive such a signal and restart when it receives the HUP. It doesn’t really restart either. In most cases it just resets its internal state, without really stopping. So, there is no way to restart a program unless the program is written to respond to those signals.
@jcoppens If i have the exact copy of some /proc/[pid] can I recreate it by wrapping it into exec() or something?
I suspect that there are some parameters in the /proc/pid, which might raise alarms. But I’m not an expert on that part.
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.
Can process be reloaded by PID?
I run a daemon which cannot be restarted via init.d or service command. Is there a way to restart a process just by passing a process id to some command?
Can you clarify what you mean? You want to restart a running process by passing the PID of that process?
yes, exactly. instead of killing a process and retyping a command with lots of params, i’d like to restart a process just by passing it’s PID (or is there something better for doing it then passing a PID?)
Ok, so is there a reason why it can’t be restarted with init.d/service? If the appropriate script doesn’t exist it might be better to write it.
2 Answers 2
Killing or Reconfiguring a Daemon without Restarting
Restarts the process 1721 by sending the hangup signal.
Causes the daemon to reload its config file by sending the hangup signal.
Restarts inetd by sending signal number 1 which is the hangup signal.
The difference between this example and the previous one is the signal is called by name here rather than number.
thanks a lot for the link. it’s what i’ve been looking for. oh, i’ve forgot to mention that i can reload a process like this, but it only works for programs i installed via apt (like apache, mysql). the one i compiled is not affected
It only works for those applications which explicitly setup a SIGHUP signal handler. It is not a general solution to restart processes.
you can use the following command
CMD=`cat /proc/1234/cmdline |sed 's/\x0/ /g'` && kill 1234 && `$CMD` &
where 1234 is the process id.
What this line does is that first it copies the command line that was used to run that process into a variable, then it kills that process and restarts it using the stored command line.
Update: above command line has been updated