Find the answer to your Linux question:
Results 1 to 9 of 9
Hi, I need to create a shell script of which only one instance may run on the system at any moment in time. So I thought I would ps -ef ...
  1. #1
    Just Joined!
    Join Date
    May 2008
    Posts
    6

    one shell script started, two are spawned?

    Hi,

    I need to create a shell script of which only one instance may run on the system at any moment in time.
    So I thought I would ps -ef and count the number of unique PIDs returned.

    I created the following script and stored it in a file named test.sh:
    Code:
    #!/bin/sh
    ps -ef | grep test.sh | grep -v "grep test.sh"
    
    When I run it, I sometimes see test.sh twice in ps, with different PIDs:
    Code:
    bheinsius@bheinsius-laptop:~$ ./test.sh
    1000      6723  6216  0 17:36 pts/0    00:00:00 /bin/sh ./test.sh
    1000      6725  6723  0 17:36 pts/0    00:00:00 /bin/sh ./test.sh
    PID 6216 is the PID of my bash, so apparently my bash with PID 6216 spawned test.sh with PID 6723, which in turn spawned test.sh with PID 6725.
    What is happening here?

    regards Bart.

  2. #2
    Linux User
    Join Date
    Jun 2007
    Posts
    318
    Does your script have a loop that has data piped to it? In those situations the shell spawns a child process for the loop. Run this test script and you'll see two processs:

    Code:
    #!/bin/bash -vx
    
    df -hP | while read _lne
        do
            sleep 60
        done

  3. #3
    Just Joined!
    Join Date
    May 2008
    Posts
    6
    No I don't. What I wrote down is the only thing in test.sh:
    Code:
    bheinsius@ubuntu:~$ cat test.sh
    #!/bin/sh
    ps -ef | grep test.sh | grep -v "grep test.sh"
    bheinsius@ubuntu:~$

  4. #4
    Just Joined!
    Join Date
    May 2008
    Posts
    6
    like I said, sometimes it returns one PID, sometimes two.
    Here's a couple of times I ran the script:
    Code:
    bheinsius@ubuntu:~$ ./test.sh
    1000      7246  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ 
    bheinsius@ubuntu:~$ ./test.sh
    1000      7250  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7254  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7258  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7262  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7266  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7270  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7274  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7278  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    1000      7280  7278  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7282  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    1000      7284  7282  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7286  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7290  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$ ./test.sh
    1000      7294  7218  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    1000      7296  7294  0 00:17 pts/0    00:00:00 /bin/sh ./test.sh
    bheinsius@ubuntu:~$
    I run this on Ubuntu 8.04 but the original problem occurred for me on AIX. On AIX, I saw that ps -ef reported test.sh running with the same PID on different CPU's (if I recall correctly). But then sometimes also with two different PIDs.

  5. #5
    Just Joined!
    Join Date
    May 2008
    Posts
    6
    Or could this be due to the two greps, that they are somehow executed in separate shells?

  6. #6
    scm
    scm is offline
    Linux Engineer
    Join Date
    Feb 2005
    Posts
    1,044
    Do you get the same behaviour if you use #!/bin/ksh instead of #!/bin/sh?

  7. #7
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    Let's try this: try adding a third pipe and see if you now get three entries in ps.

    I've implemented a shell before, and the way I did piping (and from my understanding, the common way of doing it, if not the only) was to fork a number of shells with the pipes connected. I find it interesting that you get multiple shells (as each shell should almost immediately replace itself with the process, and you shouldn't be getting results until everybody has done their stuff), but maybe something strange is going on.

    Actually, the way for implementing this often involves forking a second shell to handle the executions, so it's possible that it may stick around for a second after the last command is run.

    This is all speculation, but I bet it has to do with the piping.

    In any event, this is not a good way to ensure that the program is only running once. What if I renamed the script? What if I copy it and only rename one of them? A better way would be to create some file in a known location, and check for its existence whenever the process starts. Just be sure that the file gets deleted when the master process exits (you can use the trap command to check for signals, see the man page for more details).
    DISTRO=Arch
    Registered Linux User #388732

  8. #8
    Just Joined!
    Join Date
    May 2008
    Posts
    6
    Quote Originally Posted by scm View Post
    Do you get the same behaviour if you use #!/bin/ksh instead of #!/bin/sh?
    Yes, #!/bin/ksh gives the same result.

  9. #9
    Just Joined!
    Join Date
    May 2008
    Posts
    6
    Quote Originally Posted by Cabhan View Post
    Let's try this: try adding a third pipe and see if you now get three entries in ps.
    no it doesn't. Still one or two show up.

    Quote Originally Posted by Cabhan View Post
    This is all speculation, but I bet it has to do with the piping.
    I agree.

    Quote Originally Posted by Cabhan View Post
    In any event, this is not a good way to ensure that the program is only running once. What if I renamed the script? What if I copy it and only rename one of them? A better way would be to create some file in a known location, and check for its existence whenever the process starts. Just be sure that the file gets deleted when the master process exits (you can use the trap command to check for signals, see the man page for more details).
    I agree. I thought ps would be easy to get what I wanted but it isn't. I'll try to create a lock file in the /tmp directory.

    This does remain a mystery to me though...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...