Estou tentando detectar se um processo ( goland.sh
) está em execução. Eu usei isso:
#!/bin/bash
if pgrep "goland.sh" >/dev/null 2>&1 ; then
echo "running"
exit 1
fi
echo "not running"
Isso funciona, mas não entendo duas coisas:
- Por que se eu usar
if [[ pgrep "goland.sh" >/dev/null 2>&1 ]] ; then
não funciona (sempre imprime 'running' mesmo que o processo não esteja em execução) - Por que se eu usar
if [ pgrep "goland.sh" >/dev/null 2>&1 ] ; then
não funciona (sempre imprime 'running' mesmo que o processo não esteja em execução)
Eu suspeito que 1 tem algo a ver com a forma como >
é analisado, mas estou totalmente sem noção sobre 2.
Parece que há um mal-entendido em como as construções de teste do shell
[ ... ]
(ou[[ ... ]]
no caso do Bash) funcionam.if
instrução verifica se o comando seguinte retorna um status de saída de0
, que significa "sem erro" e é interpretado como "true". Se sim, a execução muda para athen
ramificação do script (veja o manual do Bash , por exemplo).pgrep
comando retorna0
(ou seja, "true") se encontrou um processo que corresponda ao padrão. É por isso que você obtémrunning
apenas se uma instância degoland.sh
estiver ativa.[
é um comando especial (geralmente um shell embutido) que permite realizar testes em arquivos, strings e números e retornará "true" se a condição entre os colchetes de abertura e fechamento for verdadeira. No entanto, ele é projetado para verificar de acordo com uma sintaxe específica se uma operação em um ou mais operandos é verdadeira, por exemplo, se um número (operando 1) é maior que (operador) outro número (operando 2). Por exemplo, supondo que a variável shelln
tenha o valor5
, o teste retornará true e, quando usado como comando de teste de umaif
instrução, a execução mudará para athen
ramificação.[ ... ]
Existem várias construções de teste definidas para que você possa verificar , por exemplo, se uma string está vazia ou não, se um arquivo existe e/ou é executável etc. que você obtenha o resultado esperado.Agora, você incluiu um comando shell "bruto" dentro de seus parênteses de construção de teste. O que acontece então depende um pouco das circunstâncias, mas em qualquer caso constitui um erro de sintaxe porque você tem vários tokens de string (constantes) entre colchetes sem um operador válido.
[[ ... ]]
você receberá um erro de sintaxe imediatamente porque é um elemento de sintaxe Bash e o Bash reconhece a sintaxe errada.[ ... ]
entanto, seu comando falhará silenciosamente, porque[
na verdade é um comando (embora muitas vezes embutido) que só espera que seus argumentos façam sentido em termos de operadores predefinidos e espera que seu último argumento seja o fechamento]
- mas como você redirecionou sua saída de erro para/dev/null
, a mensagem de erro será perdida.running
como saída com a sintaxe errada, em ambos os casos.Em suma, você não precisa usar as construções
[ ... ]
(ou[[ ... ]]
) porque o programa que você está usando para o teste já retorna "true" se um processo em execução for encontrado. Se você quisesse basear o teste na saída depgrep
, precisaria usar uma "substituição de comando" como em$(pgrep ...)
(e, é claro, remover o redirecionamento de saída para/dev/null
).Eu recomendaria verificar seus scripts de shell com
shellcheck
, também disponível como programa autônomo em muitas distribuições Linux, para se proteger contra erros de sintaxe (e alguns lógicos).