Linux: How to know where a process was started and how it was started?
I was checking a Linux box and found a perl process running and taking a good share of cpu usage. With top, i could only perl in process name. When i pressed c, to view the command-line, it showed /var/spool/mail. Which does not make sense, since this is directory. My questions are: 1) Why did this happen? How this perl process could mask its command-line? 2) What is the most reliable way of finding out where and how a process was started? Thanks!
9 Answers 9
In most cases just running ps is usually sufficient, along with your favorite flags to enable wide output. I lean towards ps -feww , but the other suggestions here will work. Note that if a program was started out of someone’s $PATH , you’re only going to see the executable name, not the full path. For example, try this:
$ lftp & $ ps -feww | grep ftp lars 9600 9504 0 11:30 pts/10 00:00:00 lftp lars 9620 9504 0 11:31 pts/10 00:00:00 grep ftp
It’s important to note that the information visible in ps can be completely overwritten by the running program. For example, this code:
int main (int argc, char **argv)
If I compile this into a file called «myprogram» and run it:
$ gcc -o myprogram myprogram.c $ ./myprogram & [1] 10201
And then run ps , I’ll see a different process name:
$ ps -f -p 10201 UID PID PPID C STIME TTY TIME CMD lars 10201 9734 0 11:37 pts/10 00:00:00 foobar
You can also look directly at /proc//exe , which may be a symlink to the appropriate executable. In the above example, this gives you much more useful information than ps :
$ls -l /proc/9600/exe lrwxrwxrwx. 1 lars lars 0 Feb 8 11:31 /proc/9600/exe -> /usr/bin/lftp
Get PID of a process as it opens
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
The /proc/ directory (not folder) is filled by the kernel. Every running process has some subdirectory in it (and programs don’t need to do anything particular to get that created). Your question is not clear.
Please edit your question to explain really what you want to do, and show some code that you tried. Your question is unclear.
Please also explain the context, and why you want to do all this (and in which language you are coding, also show the code you have tried). There might be a simpler way to achieve your goal.
4 Answers 4
If you start the process via a shell, then start process in background:
If the script give you the shell prompt back, you can do :
./your_prog pidof -x your_prog
Tested OK with this perl script :
Hello @sputnick. Thanks for the response but I am looking for a script which does that. I don’t want to run the file. I mean the file has more processes in it. I just want to get the pid asap
If you don’t have the prompt back immediately, then you can run pidof -x your_prog in another pseudo-terminal
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.
Get PID of process started by time
Say I run time ./a.out , then I can get the PID of time by the variable $! . But how do I get the PID of a.out ? Of course, I could parse the output of ps , but I want a more elegant solution. I’ve checked man time and couldn’t find anything. The closest I’ve gotten is time (sleep 10 & echo $!) , but because of the fork, the time taken is basically 0 and not 10s as it should be.
Add a wait to the end of your subshell and you’ll get the «right» answer: time (sleep 10 & echo $!; wait) . Or see my suggested Answer for a slightly more sophisticated suggestion
5 Answers 5
By definition, a.out is a child process of time . So time is the parent pid of a.out ! here’s a test where I replace a.out with sleep 60 :
$ time sleep 50 & timepid=$! $ aoutpid=$(pgrep -P $timepid) $ ps -o ppid,pid,start,cmd w -p $$,$timepid,$aoutpid PPID PID STARTED CMD 2065 2068 21:34:57 -bash 2068 3297 22:16:05 -bash 3297 3298 22:16:05 sleep 50
(note: where time is actually a shell build-in, so the command above is bash !)
If the time to start a shell is negligible compared to the time it takes to run the command, you can run an intermediate shell, and use the exec builtin to ensure that a.out replaces the shell rather than being executed as a subprocess.
time sh -c 'echo $$; exec ./a.out'
Try pgrep to find the PID:
Thanks, but I was looking for a more direct method that would guarantee an accurate pid. If there are multiple processes named a.out there would be an ambiguity
That doesn’t seem to work. If I run sleep 200 in two different terminals, pgrep «sleep» | xargs ps -fp gets both. Of course I may be making a mistake. What I want is to guarantee I only get the pid of the process I run with time, not any other processes with the same name
@texasflood: You are right but you have all info like PPID, STIME, TTY to easily differentiate between two..
That’s true, and that would work most of the time, but it doesn’t scale well. It’s also more involved. There may be multiple processes with the same name running in the same TTY and processes may be starting concurrently from different threads within the same TTY. It is possible to construct a scenario in which it is practically impossible to differentiate two processes.
Job control lets you put it in the background and get it back in foreground again:
time ( set -m; sleep 10 & echo $! ; fg >/dev/null ; )
Hmm … the complete command winds up as a stopped job, though. Odd. Here’s a workaround:
bash -c ' time ( set -m; sleep 10 & echo $! ; fg >/dev/null ; ) '
Of course, by then it might as well be:
I’d prefer avoiding that bash -c , but I’m kinda fresh out of ideas. :-\
ETA: Of course, if you don’t have job control enabled in your shell, the first version works. If you do have job control enabled in your shell, you can turn it off first, and on again afterwards:
set +m; time ( set -m; sleep 10 & echo $! ; fg >/dev/null ; ) ; set -m
But for the general case, where the shell may or may not have job control enabled? Check for monitor in $SHELLOPTS and pick one?
Linux — How do I see when a process started?
If you want only the start time, you can select the field and suppress the header by doing this:
the output will look like this:
which is ctime(3) format and you can parse it to split out the relevant parts.
Other start fields such as start , stime , bsdstart and start_time age the time (after 24 hours only the date is shown, for example).
You can, however, use them directly for recently started processes without further parsing:
which would output something like:
awk » /proc/$pid/stat — gives you the start time in jiffies after boot
Riddle me this. A system with an uptime of ’17:57′ has a process with a start time of ‘727975’. Looks like the process started 8 days from now?
Way too obscure! And besides, now you have to look up the boot time and do the math to convert jiffies to seconds and calculate the offset to get clock time. Easy, but too many steps. See Chopper3’s answer.
The amount of jiffies per second is stored in system variable HZ. It is mostly 100. To calculate it in shell you might use this: stackoverflow.com/a/44524937/1950345
«ps -f» — it’s in the man pages
Actually this works if the process was started the same day, but if it was started another day you only get the day, but not the time of day as on @DennisWilliamson answer
If there’s a single process with a given name (e.g. openvpn ) on the host, you can do:
ps -p `pgrep openvpn` -o lstart=
Following Dennis Williamson’s excellent answer, the ps command also has the -O option which, according to the man page: is «Like -o, but preloaded with some default columns.» This allows you to grep for the command (program) associated with the PID, if you don’t know the PID itself.
Example: finding when an apt-get process hanging on Debian/Ubuntu started:
ps -A -O lstart= | grep apt-get | grep -v grep
Piping to grep -v grep filters out lines containing the string «grep», which removes the command we just typed in (since we don’t want it).
On my system right now, this gives:
1461407 Apr 15 06:00:00 2021 S ? 00:05:09 apt-get autoremove -y
How to find the Process ID (PID) of a running terminal program?
I am running a program in the terminal that I can’t escape with Ctrl — C and that I want to kill. How can I find its PID?
This is a branch of What should I do when Ubuntu freezes? as a reference to prevent details in that question from becoming too technical.
11 Answers 11
Open another terminal and run ps ax | grep foo where foo is the name of the unresponsive program. This should return a line of output that looks something like this:
$ ps ax | grep firefox 2222 ? S 0:00 /bin/sh /usr/lib/firefox-3.6.9/firefox 2231 ? Sl 514:36 /usr/lib/firefox-3.6.9/firefox-bin 30290 pts/2 S+ 0:00 grep --color=auto firefox
The first field of each line of output is a number which represents the Process ID of the program matched by grep (you can safely ignore the last one, which represents grep itself.
To halt the offending process, do: kill pid where pid is the Process ID of the program. You might have to use your judgment as to which of the matches needs to be kill ed, or you could use top instead. Using kill by itself sends SIGTERM, which you should try first as it allows the program to properly clean up after itself. If SIGTERM fails, try SIGHUP, which is stonger medicine: kill -HUP pid . If all else fails, send SIGKILL. But, you should only do so as a last resort, because SIGKILL causes the kernel to terminate the process immediately with no possibility for cleanup. This can at times result in data corruption or other problems. So again, only send SIGKILL as a last resort. To do so, do kill -KILL pid or kill -9 pid .
If you are running a graphical interface, of course, you don’t have to fool with this crazy command-line stuff to get the job done. Just open «System Monitor», navigate to the Processes tab, choose the process you want to halt (Hm, could it be the one using 90% CPU?) and right-click it. Since the process is already stopped, (that’s the problem, right?) choose End Process or Kill Process from the resulting menu.