質問

注記:bash を使用していると思っていましたが、/bin/sh は /bin/dash にリンクされており、この奇妙な exec 問題が発生します。

Linux上にサーバープロセス(私が作成または制御したものではありません)を起動するために使用される単純なbashシェルスクリプトがあり、bashシェルスクリプトに起動されたプロセスのPIDをpidfileに出力させたいと考えています。

問題は、bash-exec コマンドが自身のプロセスを起動されたサーバー プロセスに置き換えないことです。

それで:

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

これはそうなります ない ファイル内の pid はサーバー プロセスではなく bash のものになるため、機能します。そして、サーバープロセスが終了すると、bash が終了せず、愚かな起動スクリプトがプロセスリストに残ったままになる可能性があります。

誰かが bash (またはダッシュ) を使用して次のことを行う方法を知っていますか?

  1. 出来ますか?
  2. 起動されたサーバーサーバープロセスのPIDはpidfileに含まれますか?
  3. 起動されたサーバーが存在するときに bash スクリプトが終了し、プロセス リストに無効なシェル プロセスが残らないようにしますか?

編集:このスニペットは、 bash リファレンスマニュアル 役に立ちますように...

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

コマンドを指定すると、新しいプロセスを作成せずにシェルが置き換えられます。-l オプションが指定されている場合、シェルはコマンドに渡される 0 番目の引数の先頭にダッシュを置きます。これがログイン プログラムの動作です。-c オプションを使用すると、コマンドが空の環境で実行されます。-a を指定すると、シェルは name を 0 番目の引数として command に渡します。コマンドが指定されていない場合、リダイレクトを使用して現在のシェル環境に影響を与える可能性があります。リダイレクト エラーがない場合、戻りステータスは 0 です。それ以外の場合、戻りステータスはゼロ以外になります。


編集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
役に立ちましたか?

解決

あなたのディストリビューションにはstart-stop-daemon(8)が含まれていますか?素晴らしく便利な小さなツールは、それがシェルスクリプトからデーモンを起動するために特別に造られました。 (それは完全にマッチではないかもしれないので、もちろん、デーモンは、シェルスクリプトをより長生き - 。それはあなたがシェルがあなたのデーモンをより長生きする理由によって異なります)。

それとも、単純に何かのために:

あなたの問題は、bashののexecコマンドで解決していませんか?それはあなたが実行するために頼むどんなプログラムでシェルプロセスを置き換えます:

#!/bin/bash

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

$ ./show_exec.sh 
[nothing happens]

また、別のシェルでます:

$ 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

他のヒント

私は今、の本当のの問題が何だったか実感します

#!/bin/shを使用することにより、私はbashのを呼び出すが、ダッシュませんでした。

ダッシュの幹部は、exec問題とシェルです。私は最初から#!/bin/bashを使用した場合、期待どおり、それが働いていると思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top