Como encontrar o PID de um comando dash-exec
-
26-09-2019 - |
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:
- É possível?
- O PID do processo do servidor lançado estará no meu pidfile?
- 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
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.