Come posso determinare se un processo è in esecuzione o meno e quindi fare in modo che uno script bash esegua alcune cose in base a tale condizione?
Per esempio:
se il processo
abc
è in esecuzione, farlose non è in esecuzione, farlo.
Come posso determinare se un processo è in esecuzione o meno e quindi fare in modo che uno script bash esegua alcune cose in base a tale condizione?
Per esempio:
se il processo abc
è in esecuzione, farlo
se non è in esecuzione, farlo.
Risposte:
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 verificando se il programma "gedit" è in esecuzione.
Oppure puoi solo verificare se il programma non funziona in questo modo:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
/dev/null
: "/ dev / null reindirizza l'output standard del comando sul dispositivo null, che è un dispositivo speciale che scarta le informazioni scritte su di esso" ... usando 0
reindirizzerebbe l'output del comando su un file chiamato 0
. In questo caso, consiglierei di sentirti più a tuo agio > /dev/null
: lo vedrai ovunque, poiché è il modo standard / corretto di scartare l'output.
-x
parametro in pgrep
modo che stia cercando l'applicazione esatta, altrimenti otterrà un falso corretto se trova la stessa stringa all'interno del nome di un'altra app. Ho appena trascorso 1 ora per scoprirlo.
! pgrep
Qualsiasi soluzione che utilizza qualcosa di simile ps aux | grep abc
o pgrep abc
difettosa.
Poiché non si sta verificando se un processo specifico è in esecuzione, si sta verificando se esistono processi in esecuzione che corrispondono abc
. Qualsiasi utente può facilmente creare ed eseguire un eseguibile chiamato 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 si possono applicare a ps
, grep
e pgrep
per restringere la ricerca, ma ancora non sarà possibile ottenere un test affidabile.
Dipende da cosa è necessario il test.
Ecco a cosa servono init e upstart. Inizieranno il servizio e si assicureranno che il suo pid venga archiviato in un pidfile. Prova a riavviare il servizio (tramite init o upstart) e controllerà il file pid, o lo avvierà se non è lì, o 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, utilizzare un file di blocco o un lockdir. Per esempio
#!/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 FAQ Bash 45 per altri modi di blocco.
pgrep
o ps
è perfettamente adeguato e il tuo approccio sembra eccessivo. Se stai scrivendo uno script per la distribuzione pubblica, tuttavia, dovresti scriverlo nel modo più sicuro possibile.
rm
comando viene eseguito. Quindi, fintanto che termina dopo che è stata impostata la trappola, il blocco dovrebbe essere disattivato.
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 povere : se 'pgrep' restituisce 0, il processo è in esecuzione, altrimenti non lo è.
Lettura correlata:
Bash Scripting :: Confronti di stringhe
Ubuntu Manuals pgrep
pgrep
ha lo stesso limite di 15 caratteri "caratteristica" precedentemente menzionato, quindi per esempio pgrep gnome-power-manager
fallirebbe
-x
opzione di pgrep : " Abbina solo i processi il cui nome (o riga di comando se -f è specificato) corrisponde esattamente al modello."
Di solito ho un pidof -x $(basename $0)
mio script per verificare se è già in esecuzione.
Riffing sull'idea di @ rommel-cid, puoi usarlo pidof
con il || (||) per eseguire un comando se il processo non esiste e && per eseguire qualcosa se il processo esiste, creando così un condizionale rapido if / then / else. Ad esempio, eccone uno con un processo in esecuzione (il mio browser Chrome, il cui nome del processo è "chrome") e un test per un processo che non esiste. Ho soppresso l'output standard usando 1> / dev / null in modo che non venga stampato:
$ (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
$
Nessuna delle soluzioni "semplici" ha funzionato per me perché il binario che devo controllare non è installato a livello di sistema, quindi devo controllare con il percorso, che a sua volta richiede l'uso ps -ef | grep
dell'approccio:
app="$_sdir/Logic 1.2.18 (64-bit)/Logic"
app_pid=`ps -ef | grep "$app" | awk '{print $2}'`
if `ps -p $app_pid > /dev/null`; then
echo "An instance of logic analyzer is appear to be running."
echo "Not starting another instance."
exit 5
else
nohup "$app" &> /dev/null &
fi
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 righe o il tempo per cui è in esecuzione e confrontare con zero o qualsiasi altra manipolazione. Quando esegui il comando sopra ti mostrerà almeno una riga di output, ovvero i dettagli sul processo creato dal comando grep .. Quindi prenditi cura di quello.
Questo dovrebbe fare come un semplice trucco. Inseriscilo nello script bash e vedi se è utile.
Utilizzando start-stop-daemon
:
/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2
Funziona come un normale utente.
Ho scoperto che la risposta accettata inviata 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 ha funzionato per verificare se un processo PHP era in esecuzione o meno per me, sto eseguendo CentOS 7.
La risposta di @ geirha si assicura solo che un'istanza non sia già in esecuzione prima di avviarne un'altra. Questa non era la domanda originale, la domanda originale era verificare se un processo è in esecuzione o meno.
Ecco cosa ha funzionato per me:
Supponiamo che il mio processo abbia la stringa "Jane" nel nome del processo. Questo troverà se è in esecuzione o meno. Funziona con 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
segnala comunque che lxpanel
è in esecuzione anche quando è defunto (zombi); quindi per ottenere un processo attivo, dobbiamo usare ps
egrep
A partire dal 23 settembre 2016, pgrep sembra richiedere un'opzione "-x" affinché la sceneggiatura 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. Godere!
#!/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
zombie
processo '(Non quello che descriverei come un processo "in esecuzione"). Un elenco completo di ciò che iSTAT
valori di colonna, nell'output dips
, indica è qui per coloro che sono inclini a scrivere una risposta che lo accolga o a modificare la propria.