如何查找dash-exec命令的PID

时间:2010-09-01 11:45:43

标签: linux bash exec pid dash-shell

注意:我以为我正在使用bash,但/ bin / sh链接到/ bin / dash,这有一个奇怪的exec问题。

我在Linux上有一个简单的bash shell脚本用于启动服务器进程(我没有编写或控制),并希望让bash shell脚本将启动进程的PID输出到pid文件。

问题是bash-exec命令不会用启动的服务器进程替换它自己的进程!

所以:

echo $$ | cat > /var/run/launched-server.pid

not 不起作用,因为文件中的pid将是bash而不是服务器进程的pid。如果服务器进程退出bash可能不会退出,而愚蠢的启动脚本会在进程列表中挂起。

有没有人知道使用bash的方式(或者破折号可能?)以便:

  1. 有可能吗?
  2. 启动服务器服务器进程的PID将在我的pidfile中?
  3. 确保在启动服务器存在时bash脚本将会死亡,并且不会在进程列表中挂起已解散的shell进程吗?

  4. 编辑: 来自bash reference manual的此片段有用......

    exec
               exec [-cl] [-a name] [command [arguments]]
    
      

    如果提供了命令,它将替换shell而不创建新进程。如果提供了-l选项,则shell会在传递给command的第0个参数的开头放置一个破折号。这是登录程序的功能。 -c选项导致在空环境中执行命令。如果提供了-a,则shell将name作为命令的第0个参数传递。如果未指定命令,则可以使用重定向来影响当前的shell环境。如果没有重定向错误,则返回状态为零;否则返回状态为非零。


    编辑2: 这是脚本(已消毒):

    #!/bin/sh
    
    # this is where the server expects to run its services for Daemontools
    SERVICE_DIR='/var/service';
    
    # kill stdout, stderr, stdin
    exec </dev/null
    exec >/dev/null
    exec 2>/dev/null
    
    logger -ip daemon.debug -- stdout, stderr, stdin redirected to /dev/null
    
    if [ -d $SERVICE_DIR ]; then
        # sanitized...
        logger -ip daemon.debug -- services and supervisors exited
    else
        logger -ip daemon.err -- $SERVICE_DIR does not exist, exiting
        exit 1;
    fi
    
    if [ -d /var/run/pid ]; then
        echo $$ | cat > /var/run/pid/launched-server.pid
        logger -ip daemon.debug -- creating launched-server pidfile
    fi
    
    # start the server process
    logger -ip daemon.info -- launching server on $SERVICE_DIR
    exec /usr/local/bin/launched-server
    

    有些ps输出可能更清楚了吗?

    me@chainsaw: ~/dev $ ps ax | grep launched-server
    13896 pts/1    S+     0:00 /bin/sh ./server_boot
    13905 pts/1    S+     0:00 launched-server /var/service
    13938 pts/2    R+     0:00 grep --color=auto launched-server
    

2 个答案:

答案 0 :(得分:2)

我现在意识到真正的问题是什么:

使用#!/bin/sh我没有调用bash,而是破折号。

Dash的exec是具有exec问题的shell。如果我从一开始就使用过#!/bin/bash,那就可以按预期工作了。

答案 1 :(得分:1)

您的发布内容是否包含start-stop-daemon(8)?非常有用的小工具,它专门为从shell脚本启动守护进程而构建。 (当然,守护进程比shell脚本更长,所以它可能不是完美的匹配 - 这取决于你希望shell比你的守护进程更长的原因。)

或者,对于更简单的事情:

你的问题可以用bash的exec命令解决吗?它用您要求执行的任何程序替换shell进程:

#!/bin/bash

echo $$ > /tmp/pidfile
exec /bin/sleep 60

$ ./show_exec.sh 
[nothing happens]

而且,在另一个shell中:

$ cat pidfile
24686
$ ps auxw | grep 24686
sarnold  24686  0.0  0.0   9728   816 pts/1    S+   04:53   0:00 /bin/sleep 60