Grepping uma variável

3

Eu escrevi um script init simples para iniciar e parar um script Python como um serviço. Eu tenho que ser explícito sobre a versão do Python que estou executando, porque isso está em uma caixa do CentOS 5 com o Python 2.4 & 2.6 instalado (ambos via yum).

Aqui está o que eu tenho até agora:

#!/bin/sh
# chkconfig: 123456 90 10

workdir=/usr/local/bin/Foo

start() {
    cd $workdir
    /usr/bin/python26 $workdir/Bar.py &
    echo "FooBar started."
}

stop() {
    pid='ps -ef | grep '[p]ython26 /usr/local/bin/Foo/Bar.py' | awk '{ print $2 }''
    echo $pid
    kill $pid
    sleep 2
    echo "FooBar stopped."
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: /etc/init.d/foobar {start|stop|restart}"
    exit 1
esac
exit 0

Então:

1) Eu quero ser "mais inteligente" sobre o nome do arquivo e o gerenciamento do nome do diretório, e configurar algumas variáveis para que qualquer coisa seja repetida posteriormente no script (como workdir). Meu principal problema é a declaração grep, e eu não descobri como lidar com as variáveis dentro do grep. Eu adoraria qualquer sugestão de uma maneira mais eficiente de fazer isso.

2) Eu quero adicionar suporte a "status" neste script de init e verificar se o Bar.py está sendo executado.

    
por SteveJ 19.07.2014 / 16:37

1 resposta

3

Eu posso estar sentindo falta de algo, mas não entendo por que você está mexendo com grep em primeiro lugar. É para isso que pgrep :

#!/bin/sh
# chkconfig: 123456 90 10

workdir=/usr/local/bin/Foo

start() {
    cd $workdir
    /usr/bin/python26 $workdir/Bar.py &
    echo "FooBar started."
}

stop() {
    pid='pgrep -f '/Bar.py$''
    echo $pid
    kill $pid
    sleep 2
    echo "FooBar stopped."
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: /etc/init.d/foobar {start|stop|restart}"
    exit 1
esac
exit 0

O comando pgrep foi projetado para retornar os PIDs dos processos cujo nome corresponde ao padrão fornecido. Como esse é um script python, o processo real é algo como:

python /usr/local/bin/Bar.py

Em que o nome do processo é python . Portanto, precisamos usar o sinalizador -f do pgrep para corresponder ao nome inteiro:

   -f, --full
          The pattern is normally only matched against the  process  name.
          When -f is set, the full command line is used.

Para garantir que isso não corresponda a coisas como fooBar.py , o padrão é /Bar.py$ , para que corresponda apenas à parte depois do último / e no final da string ( $ ).

Para referência futura, você nunca deve usar ps | grep para obter um PID. Isso sempre retornará pelo menos duas linhas, uma para o processo em execução e outra para o grep que você acabou de lançar:

$ ps -ef | grep 'Bar.py'
terdon   27209  2006 19 17:05 pts/9    00:00:00 python /usr/local/bin/Bar.py
terdon   27254  1377  0 17:05 pts/6    00:00:00 grep --color Bar.py
    
por 19.07.2014 / 17:06