Até agora eu costumava
pidof -o %PPID -x "my-tool"
Detectar o pid de uma instância eventualmente em execução da minha ferramenta.
Esta é a versão curta do arquivo my-tool, um script executável do bash
#!/bin/bash
if pidof -o %PPID -x "my-tool"; then
echo "Already running"
exit 1
fi
... if not running go on
Mas agora eu preciso permitir uma única instância por usuário e várias por máquina , para que possamos ter até 100 my-tool em execução no mesmo momento, mas apenas 1 por usuário.
Note que eu preciso de um teste para criar algo como um singleton. Se a ferramenta for iniciada e houver outra instância em execução, ela se fechará.
Em resumo: eu preciso que um script bash possa detectar se ele já está sendo executado para o usuário atual e, nesse caso, ele deve sair.
Como ?
pidof
, existem ferramentas mentira melhorpgrep
Respostas:
Use em
pgrep
vez disso:As opções usadas são:
Se você quiser usar isso em um script bash que verifique se ele já está em execução, você pode usá-lo
$0
. Isso se expande para o caminho do script atual (por exemplo/home/username/bin/foo.sh
), mas precisamos apenasfoo.sh
. Para conseguir isso, nós podemos remover tudo até o último/
usando da festança ferramentas de manipulação de corda :${0##*/}
. Isso significa que podemos fazer algo como:Você também pode considerar o uso de arquivos de bloqueio para isso:
fonte
touch /tmp/$USER.foo.lock
usar o PID do processo, aecho $$ >/tmp/$USER.foo.lock
lógica poderia ser incluída para testar se esse processo realmente existe.$(< pidfile)
vez de$(cat pidfile)
.Você pode usar
pgrep
para descobrir se um processo está sendo executado por um usuário específico e, em seguida, iniciar o processo se ainda não estiver sendo executado pelo usuário:A variável de ambiente,,
$USER
será expandida para o usuário conectado no momento, ou seja, o usuário executando o script. Como estamos interessados apenas emmy-tool
executar ou não, basta usar o status de saída diretamente com aif
construção.Use este script como invólucro para iniciar
my-tool
e faça com que os usuários usem apenas isso ou renomeie-o comomy-tool
e renomeie o originalmy-tool
para outra coisa (e altere o nome dentro do script também).fonte
Experimente com este trecho:
É importante não escrever,
pgrep|tr
porque isso entraria em um mesmo shell nomeado.fonte
Quebre o comando que você deseja executar em um lote para garantir que apenas uma cópia seja executada por vez. Use um lock_file armazenado na árvore de diretórios pessoais do usuário para que cada usuário tenha seu próprio arquivo de bloqueio. Por exemplo:
'comando' pode ser qualquer comando ou script do bash.
man flock
dá exemplos de usofonte
flock
comando de todos