Use daemontools . Você pode usar svok
para verificar se um processo de serviço / daemon / plano de fundo está sendo executado no momento.
Para outros métodos, consulte:
Posso criar uma linha de comando bash que execute apenas um determinado comando se o processo ainda não estiver em execução (em segundo plano)?
Como faço para verificar *, se um comando já está em execução?
(para que eu possa adicionar o próximo comando com &&
entre eles, então o próximo só será executado se o primeiro for verdadeiro).
*: teste, determine, descubra, descubra
Use daemontools . Você pode usar svok
para verificar se um processo de serviço / daemon / plano de fundo está sendo executado no momento.
Para outros métodos, consulte:
Eu usei essa técnica de tempos em tempos:
$ pgrep <process name> || <process name>
Antes de pgrep
, costumava ser feito assim:
$ ps -eaf | grep -q <[p]rocess name> || <process name>
O bit com o [p]
faz com que o grep
não seja encontrado como resultado.
$ ps -eaf | grep -q [s]leep || sleep 10
Isso pode ser complicado, porque você pode ter instâncias separadas do mesmo processo que vivem de forma independente. Por exemplo, servidores ouvindo em diferentes portas ou serviços em execução como usuários diferentes. Para distinguir entre essas instâncias, você precisa atribuir a cada uma delas uma tag exclusiva. A tag é geralmente um arquivo, mas pode ser um soquete local no namespace abstrato, uma porta TCP etc. - qualquer identificador exclusivo serve. Quando a tag é um arquivo, ela pode ser um arquivo regular contendo um ID de processo (um pidfile) ou um pipe ou soquete nomeado no qual o arquivo está escutando etc. Idealmente, a tag é um ponto de extremidade de comunicação que permite aos clientes se conectarem para esse processo.
Cada um desses diferentes tipos de tags resulta em uma maneira diferente de verificar se a instância que você está procurando está funcionando. Por exemplo, com um soquete de arquivo local, tente conectar-se a ele e inicie o processo se não houver processo escutando nesse soquete. Se a tag for um pidfile, verifique se há um processo com essa ID de processo, mas cuidado, pois isso é frágil, pois, se o processo tiver morrido, pode haver um processo não relacionado que reutilizou sua ID. Tenha em atenção que, se dois clientes tentarem alcançar o processo num curto espaço de tempo, ambos poderão descobrir que o processo não existe e ambos tentarem iniciá-lo; proteger adequadamente desta condição de corrida pode ser complicado.
É mais fácil gerenciar instâncias quando todas são iniciadas pelo mesmo processo de supervisor, e esse processo de supervisor detecta quando as instâncias morrem e reage de acordo. Se o programa não responder em um ponto de extremidade de comunicação conhecido e não for gerenciado por um programa de supervisor, a tag do homem pobre é um pidfile: um arquivo que contém o ID do processo. Quando você inicia o processo, escreva o pid em um arquivo com um nome pré-arranjado. Quando você precisar que o processo exista, leia o pidfile e veja se há um processo com esse pid. Quando você mata o processo, apague o pidfile. O problema mais saliente com um pidfile não supervisionado é que se o processo morrer, seu pid pode ser reutilizado por algum processo não relacionado. Você deve pelo menos verificar o nome do processo ou o executável do processo para garantir que está falando com o processo correto. Muitas variantes unix têm um comando pgrep : pgrep SOMENAME
lista os processos cujo nome contém SOMENAME como substring, com opções adicionais para limite a um usuário em particular, para exigir uma correspondência exata, para alterar qual das várias noções possíveis de "nome do processo" é usada, etc.
Você pode usar essa abordagem:
if [[ -z $(ps -C appname -opid=) ]]; then
appname && secondapp
fi
Outras opções:
pgrep -xq processname
remove as partes do dirname no OS X No GNU / Linux ps -eo comm= | sed 's|.*/||' | grep -xq processname
trunca nomes de comandos para 15 caracteres e sed 's|.*/||'
e ps -o comm
correspondem apenas aos primeiros 15 caracteres.
pgrep
(nomes de comando de correspondência) não é suportado no OS X.
No OS X ps -C
imprime os caminhos absolutos dos comandos e ps -C
apenas imprime os nomes dos comandos. Em% GNUps -o comm
apenas imprime nomes de comandos e ps -co comm
tem um significado diferente.
O pgrep do OS X não inclui processos ancestrais (como bash, Terminal ou launchd) sem ps -o comm
. O pgrep do GNU inclui-os por padrão e não suporta -c
.
-a
e -a
não implicam grep -x
, portanto use pgrep -x
se o nome do processo puder conter caracteres regex.
Sinto muito, mas todas essas soluções não suportam contab, pois a mesma linha de comando aparecerá duas vezes no resultado 'ps'.
Então aqui está a minha:
## Test pour voir si le même script tourne déjà
## Un fichier .pid est utilisé pour stocké le numéro de process
## Si le pid est en train de tourner alors on sort.
lock_file=$0".pid"
[ -r $lock_file ] && read pid <$lock_file
if [ "$pid" -gt 1 ] && [ 'ps --no-headers -p "$pid" | wc -l' -gt 0 ] ; then
echo "WARNING : le process $pid tourne deja : $0"
ps -edf | grep 'basename $0' | grep -v grep
echo "WARNING : Arrêt de cette instance ($$)."
exit 7
fi
echo $$ >$lock_file
Com Bash
#!/usr/bin/env bash
[[ $# -eq 0 ]] && { echo -e "Usage:\t\t $0 <Process_name> <Command here>"; exit 1; }
ifnotrun(){
local p=$1
if ! ps -C "$1" -opid=
then
cmd=($@)
echo ${cmd[@]:1}
else
echo "Process \"$p\" Already Running.."
exit 1
fi
}
ifnotrun $*
Nota: - remova echo
se a saída parecer Ok.
Vou explicar o caso em que você executa o comando no beckgreoud. O "$!" salve o PID do último processo em segundo plano. Assim, você pode usá-lo para encontrá-lo nas tabelas do processo seguindo as respostas acima:
sleep 4 &
ps -ef | grep -w $! ...
O comando interno "jobs" - tente isto:
sleep 4&
J='jobs'
while [ "$J" ]; do
sleep 1
jobs # This line flush the jobs' bufer.
J='jobs'
done
Com relação ao "& &" opção
Em vez de & & use o comando wait. No exemplo a seguir myproc2 não será executado até que myproc1 termine:
myproc1 &
wait
myproc2
Veja o estado do seu processo:
ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'
Referência:
D uninterruptible sleep (usually IO)
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped, either by a job control signal or because it is being traced
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent
Por exemplo, usei-o para reproduzir ou pausar condicionalmente o meu processo sox em uma sessão do tmux:
/usr/local/bin/tmux if-shell -t sox "[ $(ps -lp $(pgrep sox) | tail -1 | awk '{print $11}') == 'T' ]" \
'send -t sox "fg" Enter' \
'send -t sox C-z'
Você pode usá-lo dentro de um script:
if [ 'ps -ef | grep "script.sh" | grep -v grep | wc -l' -gt 1 ] ; then
echo "RUNNING...."
else
echo "NOT RUNNING..."
fi