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 0reindirizzerebbe 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.
-xparametro in pgrepmodo 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 abco pgrep abcdifettosa.
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 abcda qualche parte nel suo nome o argomenti), causando un falso positivo per il test. Ci sono varie opzioni che si possono applicare a ps, grepe pgrepper 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.
pgrepo 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.
rmcomando 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
pgrepha lo stesso limite di 15 caratteri "caratteristica" precedentemente menzionato, quindi per esempio pgrep gnome-power-managerfallirebbe
-xopzione 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 pidofcon 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 | grepdell'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 abcmostrerà 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 lxpanelo pidof lxpanelsegnala comunque che lxpanelè in esecuzione anche quando è defunto (zombi); quindi per ottenere un processo attivo, dobbiamo usare psegrep
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
zombieprocesso '(Non quello che descriverei come un processo "in esecuzione"). Un elenco completo di ciò che iSTATvalori di colonna, nell'output dips, indica è qui per coloro che sono inclini a scrivere una risposta che lo accolga o a modificare la propria.