Pergunta

OBSERVAÇÃO:Eu pensei que estava usando o bash, mas /bin/sh está vinculado a /bin/dash, que tem um problema estranho de execução.

Eu tenho um script de shell bash simples no Linux que é usado para iniciar um processo de servidor (que eu não escrevi ou controlei) e gostaria que o script de shell bash gerasse o PID do processo iniciado em um arquivo pid.

O problema é que o comando bash-exec não substitui seu próprio processo pelo processo do servidor iniciado!

Então:

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

Isso faz não funcionará porque o pid no arquivo será o do bash e não o processo do servidor.E se o processo do servidor sair, o bash pode não sair, deixando o script de inicialização estúpido pendurado na lista de processos.

Alguém sabe uma maneira de usar o bash (ou talvez o dash?) Para que:

  1. É possível?
  2. O PID do processo do servidor lançado estará no meu pidfile?
  3. Garantir que o script bash morra quando o servidor iniciado existir e não deixe processos shell extintos pendurados na lista de processos?

Editar:Este trecho do manual de referência do bash ser útil...

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

Se o comando for fornecido, ele substituirá o shell sem criar um novo processo.Se a opção -l for fornecida, o shell colocará um travessão no início do argumento zero passado ao comando.Isto é o que o programa de login faz.A opção -c faz com que o comando seja executado com um ambiente vazio.Se -a for fornecido, o shell passa name como o argumento zero para o comando.Se nenhum comando for especificado, os redirecionamentos poderão ser usados ​​para afetar o ambiente shell atual.Se não houver erros de redirecionamento, o status de retorno será zero;caso contrário, o status de retorno será diferente de zero.


Editar 2:Este é o script (higienizado):

#!/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

E alguma saída ps para talvez ser mais clara?

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
Foi útil?

Solução

Sua distribuição inclui start-stop-daemon(8)?Pequena ferramenta maravilhosamente útil, foi construída especificamente para iniciar daemons a partir de scripts shell.(Claro, os daemons sobrevivem aos scripts de shell, então pode não ser uma combinação perfeita - depende de por que você deseja que o shell sobreviva ao seu daemon.)

Ou, para algo mais simples:

Seu problema poderia ser resolvido com o bash exec comando?Ele substitui o processo shell por qualquer programa que você solicitar para executar:

#!/bin/bash

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

$ ./show_exec.sh 
[nothing happens]

E, em outra concha:

$ 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

Outras dicas

Agora percebo o que real problema foi:

Usando #!/bin/sh Eu não estava invocando o bash, mas o dash.

O exec do Dash é o shell com o problema do exec.se eu tivesse usado #!/bin/bash desde o início, teria funcionado conforme o esperado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top