How do I get the pid of a process as soon as it opens. Like lets say we run ./file.pl and then ./file2.pl As both these files will create a pid in /proc/ folder. How do I instantly know if the process has been created when the executable is run.
I have a file with all the commands ready to be run as soon as it gets the green signal that there is a new process in the /proc/ folder. How do I do that?
EDIT:
Please don't answer with a shell command. I don't need to know the pid. I need to develop a script which can know right away that we have a guest in the proc department
If you start the process via a shell, then start process in background:
./your_prog &
Get the pid:
echo $!
If the script give you the shell prompt back, you can do :
./your_prog
pidof -x your_prog
Tested OK with this perl script :
#!/usr/bin/perl
if (fork() == 0) {
sleep(600);
}
you need to
chmod +x your_prog
before...
Every process can get its own pid with the getpid(2) syscall. At process creation by fork(2) the parent process (e.g. some shell) gets the pid of the new child process. Read e.g. Advanced Linux Programming for more. And the kernel (not the program) is creating some subdirectory /proc/1234/ see proc(5) as soon as it creates the process of pid 1234.
Actually, /proc/ is not a real file system. It is just a pseudo file system giving a view on the state of the kernel and the entire Linux system.
Perl gives you its POSIX module to interface the syscalls. The getpid() syscall is interfaced using the $PID or $$ Perl variable.
The /proc/ pseudo filesystem is filled by the kernel. You could perhaps use inotify to follow change in /proc/ but this is very probably a bad idea.
Your question is not clear, we cannot understand what you really want to do and what you have tried.
Try out below shell script.(You may have to include changes in below script for your expected output)
#!/bin/bash
nr_proc_before=`ls -l /proc | wc -l`
ls /proc > proc_list_before
./any_executable &
nr_proc_after=`ls -l /proc | wc -l`
ls /proc > proc_list_after
nr_new=`expr $nr_proc_after - $nr_proc_before`
echo "$nr_new processes are created newly"
echo "new processes pids are :"
diff proc_list_after proc_list_before > new_pids
sed "1d" new_pids
if [ nr_new > 0 ] ; then
#trigger your file which has commands.
fi
Insted of any_execuatble you can replace with your things so that new processes will be created.
Note : This is not a script which monitors for new process. This sample of script may give you idea to solve your problem.
Please do reply for this answer, i can redefine my answer.
Related
I am working with a client-server program. My server program is a daemon process. I need to write scripts that start and stop the daemon. For this, I need to find a way to store the daemon's processid . I've heard bash scripting might be a good solution. I want to store the processID of the daemon in a file called revd.pid under /var/run.
My program looks like this:
#!/bin/bash
pid = $!
echo pid >> /var/run/revd.pid
Use command pidof <application_name>
Here is your daemon process.
Below is an example of the above in a shell script.
Create empty file revd.pid under /var/run and give it proper permissions ...so that you can write into it.
pid=`pidof chrome`
echo "$pid" >> /var/run/revd.pid
I was trying to get pid of process I ran with setsid and which ought to run in background like this:
test.sh:
#/bin/bash
setsid nohup ./my_program &
echo $!
if I run ./test.sh it will print a pid of my_program process and it's exactly what I need. But if run this commands one by one in my shell like this:
$ setsid nohup ./my_program &
$ echo $!
It will give me a pid of setsid command (or may be something else, but it almost all times gives me pid of my_program minus one).
What is happening here? Why results of commands I ran in terminal by myself differs from results of test.sh script?
Btw, may be you know some easy way of process which I started with setsid and which I need to run in background?
Repost of comments above as an answer:
This is because setsid only forks the current process if it is the process group leader. A detailed explanation can be found here.
To get the pid of a process executed via setsid, the approaches given here may be tried.
setsid will call fork to ensure that it creates a new process group aswell as a new session, hence the resulting pid will not match the pid of setsid. The most clean work-around would be that my_program stores its pid into a file.
When you later want to send kill to my_program, you should check that the pid actually matches a program named my_program via /proc file system or calling the ps command with some magic code around it. (This is a very common method used by many daemons)
I have seen many discussions here on kill command. But my confusion is different. I have many processes with the same name and I have to automate the killing. Hence I can't use the pid. So is it possible that if I go to a specific path and use kill <pname> then only the process related to that path will get killed?
Or is there some way to incorporate the path name in kill command?
Instead of using a pid, you could always use the pkill command and have it check against some regular expression. If you pass it the -f flag, it allows you to check against the entire command line rather than just the process name.
Something like this would probably do the trick:
pkill -TERM -u username -f "mwhome.*weblogic\\.NodeManager"
-f is where you would pass in your regex
-u is also useful so that you only affect pid's running as specific users
No, but you when you start the process with
yourcommand & echo $!
or wrap it in a small script
#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file
you can save the pid. And then kill the process with this pid. This is the normal way how to manage the processes. If you look in the normal init.d scripts of perhaps nginx, they do it the same way. Just saving the pid in a file, and at stopping just read the pid and kill the process.
I had given a job in a remote server yesterday from my home. The command was
sh run.sh >& out &
The run.sh will excute a program (average.f) more than 1000 times recurssively.
Today, in my office, I found some mistake in my run.sh. So I would like to kill it.
I used top command, but it is not showing the run.sh. It is only showing average.f. So, once, I killed it with kill PID, it is again starting average.f with another PID and producing outputs.
ps -u is not showing either run.sh or average.f.
Can anybody please help me how to kill this job.
find your job id with the process or application name . example is given below - I am killing java process here
ps -aef|grep java
// the above command will give you pid, now fire below command to kill that job
kill -9 pid
// here pid is a number which you get from the first command
ps -ef | grep run.sh | grep -v grep | awk '{print $2}' | xargs kill -9
Use pstree(1) (probably as pstree -p) to list the process tree hierarchy, then kill(1) (first with -TERM, then with -QUIT, and if that does not work, at last with -KILL) your topmost shell process running run.sh (or else the few "higher" processes). Perhaps use killall(1) or pidof(1) (or pgrep(1) or pkill)
You might want to kill the process group, with a negative pid.
You should never at first kill -KILL a process (but only at last resort); some programs (e.g. database servers, sophisticated numerical computations with application checkpointing, ...) have installed a SIGTERM or SIGQUIT signal handler to clean up their mess and e.g. save some state (on the disk) in a sane way. If you kill -KILL them, they could leave the mess uncleaned (since SIGKILL cannot be caught, see signal(7)....)
BTW, you should use ps auxw to list all processes, read ps(1)
How to run a program and know its PID in Linux?
If I have several shells running each other, will they all have separate PIDs?
Greg's wiki to the rescue:
$! is the PID of the last backgrounded process.
kill -0 $PID checks whether $PID is still running. Only use this for processes started by the current process or its descendants, otherwise the PID could have been recycled.
wait waits for all children to exit before continuing.
Actually, just read the link - It's all there (and more).
$$ is the PID of the current shell.
And yes, each shell will have its own PID (unless it's some homebrewed shell which doesn't fork to create a "new" shell).
1) There is a variable for that, often $$:
edd#max:~$ echo $$ # shell itself
20559
edd#max:~$ bash -c 'echo $$' # new shell with different PID
19284
edd#max:~$ bash -c 'echo $$' # dito
19382
edd#max:~$
2) Yes they do, the OS / kernel does that for you.
the top command in linux(Ubuntu) shows the memory usage of all running programs in linux with their pid. Kill pid can kill the process.