0

I have the following script

hello.sh
--------
while :
do
    echo "hello"
    sleep 20
done

And when I ran the above script, I got 2627 as the PID of the script

root@localhost ~]# ./hello.sh &
[1] 2627
[root@localhost ~]#

Now when I'm running the ps command in another terminal, I'm not getting the script name in the output

[root@localhost ~]# ps -ef| grep 262[7]
root      2627  1582  0 19:19 pts/1    00:00:00 -bash
root      3427  2627  0 19:52 pts/1    00:00:00 sleep 20
[root@localhost ~]#

$$ is the PID of the main shell where I'm running the script. I know that inside the script I can put $$ to get the PID of the script, but that's not my intention here.

Once I ran the long running script in the background and suppose I have closed the terminal accidentally, then is there a way to grep the PID using the script name or any other means?

FYI

[root@localhost ~]# echo $$
2586
[root@localhost ~]# ps -ef| grep 262[7]
root      2627  1582  0 19:19 pts/1    00:00:00 -bash
root      3657  2627  0 20:02 pts/1    00:00:00 sleep 20
[root@localhost ~]# ps -ef| grep bas[h]
root      1517  1513  0 18:43 pts/18   00:00:00 -bash
root      1582  1578  0 18:45 pts/1    00:00:00 -bash
root      2586  2581  0 19:18 pts/54   00:00:00 -bash
root      2627  1582  0 19:19 pts/1    00:00:00 -bash
[root@localhost ~]#

2586 is the PID of the main shell and inside it, I have run the hello.sh script. It created a new shell and started running the commands inside it. All these basic I know. This is not a duplicate question. Please see the output to understand it.

  • Possible duplicate of what is $$ in bash? – Kiwy Oct 22 '18 at 14:28
  • consult the duplicate, it's basicaly $$ – Kiwy Oct 22 '18 at 14:28
  • Do you want the PID ? or do you want the command running ? – Kiwy Oct 22 '18 at 14:30
  • 2
    What if someone else ran a "./hello.sh", or if you ran a second one? – Jeff Schaller Oct 22 '18 at 14:32
4

You should add a proper she-bang line (#! /bin/sh or #! /bin/bash) to your script if you want it to appear with its name in the process list.

Example:

$ cat foo
sleep 10

$ ./foo &
[4] 4403
$ ps -q 4403
  PID TTY          TIME CMD
 4403 pts/3    00:00:00 bash

$ cat bar
#! /bin/sh
sleep 10

$ ./bar &
[5] 4406
$ ps -q 4406
  PID TTY          TIME CMD
 4406 pts/3    00:00:00 bar

Otherwise, on linux you can still find the name of the script from the /proc/PID/fd directory:

$ ./foo &
[2] 5125
$ ls -l /proc/5125/fd
total 0
lrwx------ 1 ahq ahq 64 Oct 22 17:57 0 -> /dev/pts/3
lrwx------ 1 ahq ahq 64 Oct 22 17:57 1 -> /dev/pts/3
lrwx------ 1 ahq ahq 64 Oct 22 17:57 2 -> /dev/pts/3
lr-x------ 1 ahq ahq 64 Oct 22 17:57 254 -> /tmp/foo
lrwx------ 1 ahq ahq 64 Oct 22 17:57 255 -> /dev/pts/3

Notice to forth line, the 254 fd which points to the path of the script being run. With other shells than bash it will be other fd, like 3 or 10.

That could also be reverse searched with lsof /tmp/foo.

  • Thanks it worked, I got another question now. when I killed the 2627 PID and then I grepped for it, I got the below and it showed me the path of the script as well. If I run the script with the absolute path I will get it in ps output and if I run with the relative path i.e ./ in this case [root@localhost ~]# kill -9 2627 [root@localhost ~]# ps -ef| grep 262[7] [1]+ Killed ./hello.sh (wd: /tmp/test/scripts/hello.sh) (wd now: ~) – k_vishwanath Oct 22 '18 at 15:00
  • The ps output could show either the "process name" (the first 15 characters of the basename of the executable) or the full command line, as it was passed to execve. ps -ef will show the latter. ps -eo pid,comm,args will show both. There is no difference if it was run via an absolute or relative path, or a simple command looked up in $PATH. – mosvy Oct 22 '18 at 15:35
1

On Linux, you could:

grep -l hello.sh /proc/*/task/*/comm 2>/dev/null

... which would report back any of your processes with "hello.sh" in their command-line (pid 26560, when I ran it):

/proc/26560/task/26560/comm

The stderr redirection is to drop grep's complaint about your current process' comm file (/proc/self/task/$$/comm) disappearing between the time the shell expands the wildcarded path and when grep decides to open it for reading/grepping.

If you run a second "hello.sh", you'll get two results back, etc:

$ ./hello.sh &
[2] 28328
$ grep -l hello.sh /proc/*/task/*/comm 2>/dev/null
/proc/26560/task/26560/comm
/proc/28328/task/28328/comm
  • I'm getting nothing when I ran your command and I'm running this on CentOS Linux release 7.4.1708 – k_vishwanath Oct 22 '18 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.