Come posso determinare se un processo è in esecuzione o meno e poi fare in modo che uno script di bash esegua alcune cose in base a quella condizione?
Ad esempio:
-
se process
abc
è in esecuzione, fai questo -
se non è in esecuzione, fallo.
Come posso determinare se un processo è in esecuzione o meno e poi fare in modo che uno script di bash esegua alcune cose in base a quella condizione?
Ad esempio:
se process abc
è in esecuzione, fai questo
se non è in esecuzione, fallo.
Uno script bash per fare qualcosa del genere sarebbe simile a questo:
#!/bin/bash
# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern.
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Stopped"
fi
Questo script sta solo controllando se il programma "gedit" è in esecuzione.
Oppure puoi controllare solo se il programma non è in esecuzione in questo modo:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
Qualsiasi soluzione che utilizza qualcosa come ps aux | grep abc
o pgrep abc
è difettosa.
Poiché non stai controllando se un processo specifico è in esecuzione, stai controllando se ci sono processi in esecuzione che corrispondono a abc
. Qualsiasi utente può facilmente creare ed eseguire un eseguibile denominato abc
(o che contiene abc
da qualche parte nel suo nome o argomenti), causando un falso positivo per il test. Ci sono varie opzioni che puoi applicare a ps
, grep
e pgrep
per restringere la ricerca, ma non otterrai un test affidabile.
Dipende da cosa ti serve il test.
Questo è ciò a cui servono init e upstart. Avvieranno il servizio e assicureranno che il suo pid venga archiviato in un file pid. Prova ad avviare nuovamente il servizio (tramite init o upstart) e controllerà il file pid e lo avvierà se non è presente, oppure interromperà se è già in esecuzione. Questo non è ancora affidabile al 100%, ma è il più vicino possibile.
Vedi Come posso verificare se il mio server di gioco è ancora in esecuzione ... per altre soluzioni.
In questo caso, usa un lockfir o un lockdir. Per es.
#!/usr/bin/env bash
if ! mkdir /tmp/abc.lock; then
printf "Failed to acquire lock.\n" >&2
exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT # remove the lockdir on exit
# rest of script ...
Vedi Domande frequenti Bash 45 per altri modi di bloccare.
Questo è quello che uso:
#!/bin/bash
#check if abc is running
if pgrep abc >/dev/null 2>&1
then
# abc is running
else
# abc is not running
fi
In parole semplici: se 'pgrep' restituisce 0, il processo è in esecuzione, altrimenti non lo è.
Lettura correlata:
Bash Scripting :: Confronto tra stringhe
Manuali di Ubuntu pgrep
Di solito ho un pidof -x $(basename $0)
sui miei script per verificare se è già in esecuzione.
Riffing sull'idea di @ rommel-cid, puoi usare pidof
con || (||) per eseguire un comando se il processo non esiste e & amp; & amp; per eseguire qualcosa se il processo esiste, creando quindi un condizionale if / then / else. Ad esempio, ecco uno con un processo in esecuzione (il mio browser Chrome, il cui nome processo è "chrome") e un test per un processo che non esiste. Ho soppresso lo standard output usando 1 & gt; / dev / null in modo che non stampi:
$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
instead"
it's not running? ok i'll run instead
$
La prima cosa che mi è venuta in mente per il tuo problema:
ps aux | grep -i abc
mostrerà i dettagli del processo se è in esecuzione. È possibile abbinare il numero di linee o il tempo per cui è in esecuzione e confrontare con zero o qualsiasi altra manipolazione. Quando esegui il comando precedente, mostrerai almeno una riga di output, ad esempio i dettagli sul processo creato dal comando thi grep. Quindi prenditi cura di questo.
Questo dovrebbe essere un semplice trucco. Inseriscilo nello script di bash e verifica se è utile.
Uso di start-stop-daemon
:
/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2
Funziona come un utente normale.
Ho scoperto che la risposta accettata pubblicata da @John Vrbanac non ha funzionato per me e che la risposta inviata da @geirha non risponde alla domanda originale.
La soluzione di John Vrbanac non funzionava per verificare se un processo PHP era in esecuzione o meno per me, sto utilizzando CentOS 7.
@ la risposta di geirha fa in modo che un'istanza non sia già in esecuzione prima di iniziarne un'altra. Questa non era la domanda originale, la domanda iniziale era di verificare se un processo è in esecuzione o meno.
Ecco cosa ha funzionato per me:
Supponiamo che il mio processo abbia la stringa "Jane" nel suo nome di processo. Questo troverà se è in esecuzione o no. Questo funziona per gli script BASH e PHP.
ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
echo "It's running"
else
echo "It's not running"
fi
## bash
## function to check if a process is alive and running:
_isRunning() {
ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}
## example 1: checking if "gedit" is running
if _isRunning gedit; then
echo "gedit is running"
else
echo "gedit is not running"
fi
## example 2: start lxpanel if it is not there
if ! _isRunning lxpanel; then
lxpanel &
fi
## or
_isRunning lxpanel || (lxpanel &)
Nota : pgrep -x lxpanel
o pidof lxpanel
riporta ancora che lxpanel
è in esecuzione anche quando è defunct (zombie); quindi, per ottenere un processo in corso, dobbiamo utilizzare ps
e grep
A partire dal 23 settembre 2016, pgrep sembra richiedere l'opzione "-x" perché lo script di muru funzioni.
#!/bin/bash
if pgrep -x "conky" > /dev/null 2>&1
then
echo "conky running already"
else
echo "now starting conky"
conky
fi
exit 0
Ho provato e testato lo script sopra su una macchina Ubuntu 16.04.1. Buon divertimento!
#!/bin/bash
while [ true ]; do # Endless loop.
pid='pgrep -x ${1}' # Get a pid.
if [ -z $pid ]; then # If there is none,
${1} & # Start Param to background.
else
sleep 60 # Else wait.
fi
done
isProcessRunning () {if [$ (pidof $ 1) & gt; / dev / null]; quindi retval = 'true'; else retval = 'false'; fi; echo $ retval; }
isProcessRunning geany
true