[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [shell-script] Como saber se meu shell já está executando?
From: |
Gustavo Chaves |
Subject: |
Re: [shell-script] Como saber se meu shell já está executando? |
Date: |
15 Mar 2005 14:26:45 -0300 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 |
Usando o comando ps (ou suas variantes) pra verificar se um processo
está rodando é um tanto lento e arriscado. Arriscado porque você pode
ter outro processo com o mesmo nome mas que não tenha nenhuma relação
com o seu rodando.
Uma maneira bastante elegante de resolver este e outros problemas é
implementar um MUTEX com arquivos, conforme descrito em
<http://sbl.salk.edu/lb/doc/UNIX_CD/upt/ch45_36.htm>.
(Aliás, o livro "UNIX Power Tools" é excelente. Vale a pena comprá-lo
ou, pelo menos, anotar o seu site nos bookmarks.)
Basicamente, a solução seria a seguinte:
# Define o nome do arquivo de trava
LOCKFILE=/tmp/lock.myname
# Tenta obter a trava
if (umask 222; echo $$ >$LOCKFILE) 2>/dev/null; then
trap "rm -f $LOCKFILE" EXIT
else
set x `ls -l $LOCKFILE`
echo >&2 "Já há um processo executando pelo usuário $4 desde $7 $8
$9"
exit 1
fi
O 'if' testa uma subshell que tenta sobrescrever o arquivo $LOCKFILE.
Ele só vai conseguir fazer isto se o arquivo já não existir, pois, se
ele já existir, não terá permissão para escrita devido à umask com que
foi criado. Se a criação for bem sucedida, programamos o comando "rm
-f $LOCKFILE" pra ser executado ao final do script, de modo a liberar
a trava.
Se já houver um processo executando e "de posse" da trava, outros
processos não conseguirão sobrescrever o LOCKFILE e terminarão no
'else' com uma mensagem.
Uma vantagem desta solução é que você pode usá-la para delimitar
regiões críticas no seu script substituindo o 'if' por um 'until' e
executando o "rm -f $LOCKFILE" explicitamente no final da região.
Outra coisa interessante é que você pode coordenar a entrada em
regiões críticas entre scripts diferentes. Basta acordar o nome do
LOCKFILE.
Gustavo.