Jak mogę ustalić, czy proces jest uruchomiony, czy nie, a następnie uruchomić skrypt bash w celu wykonania pewnych czynności w oparciu o ten warunek?
Na przykład:
jeśli proces
abc
jest uruchomiony, zrób tojeśli nie działa, zrób to.
Jak mogę ustalić, czy proces jest uruchomiony, czy nie, a następnie uruchomić skrypt bash w celu wykonania pewnych czynności w oparciu o ten warunek?
Na przykład:
jeśli proces abc
jest uruchomiony, zrób to
jeśli nie działa, zrób to.
Odpowiedzi:
Skrypt bash do zrobienia czegoś takiego wyglądałby mniej więcej tak:
#!/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
Ten skrypt sprawdza, czy program „gedit” jest uruchomiony.
Lub możesz tylko sprawdzić, czy program nie działa w następujący sposób:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
/dev/null
: „/ dev / null przekierowuje standardowe wyjście polecenia do urządzenia zerowego, które jest specjalnym urządzeniem, które odrzuca zapisane na nim informacje” ... użycie 0
spowoduje przekierowanie wyjścia polecenia do pliku o nazwie 0
. W takim przypadku radzę poczuć się bardziej komfortowo > /dev/null
- zobaczysz to wszędzie, ponieważ jest to standardowy / właściwy sposób odrzucania danych wyjściowych.
-x
parametr, aby pgrep
szukał dokładnej aplikacji, w przeciwnym razie otrzyma fałszywą poprawkę, jeśli znajdzie ten sam ciąg w nazwie innej aplikacji. Właśnie spędziłem 1 godzinę, aby się tego dowiedzieć.
! pgrep
Każde rozwiązanie, które wykorzystuje coś takiego ps aux | grep abc
lub pgrep abc
jest wadliwe.
Ponieważ nie sprawdzasz, czy określony proces jest uruchomiony, sprawdzasz, czy są uruchomione procesy, które się zgadzają abc
. Każdy użytkownik może łatwo utworzyć i uruchomić plik wykonywalny o nazwie abc
(lub który zawiera abc
gdzieś w nazwie lub argumentach), co powoduje fałszywie dodatni wynik testu. Istnieją różne opcje można zastosować do ps
, grep
i pgrep
, aby zawęzić wyszukiwanie, ale nadal nie będzie wiarygodny test.
To zależy od tego, do czego potrzebujesz testu.
Po to są init i upstart. Uruchomią usługę i upewnią się, że jej pid zostanie zapisany w pliku pid. Spróbuj ponownie uruchomić usługę (przez init lub upstart), a ona sprawdzi plik pid i uruchom go, jeśli go nie ma, lub przerwij, jeśli już działa. To wciąż nie jest w 100% niezawodne, ale jest tak blisko, jak to tylko możliwe.
Zobacz Jak mogę sprawdzić, czy mój serwer gier nadal działa ... w przypadku innych rozwiązań.
W takim przypadku użyj pliku blokady lub lockdir. Na przykład
#!/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 ...
Zobacz Bash FAQ 45, aby uzyskać informacje na temat innych sposobów blokowania.
pgrep
lub ps
całkowicie wystarczającego, a twoje podejście wydaje się przesadne. Jeśli piszesz skrypt do publicznej dystrybucji, powinieneś napisać go w najbezpieczniejszy możliwy sposób.
rm
polecenie jest uruchamiane. Tak długo, jak kończy się po ustawieniu pułapki, zamek powinien zniknąć.
Oto, czego używam:
#!/bin/bash
#check if abc is running
if pgrep abc >/dev/null 2>&1
then
# abc is running
else
# abc is not running
fi
W prostym języku angielskim: jeśli „pgrep” zwraca 0, proces jest uruchomiony, w przeciwnym razie nie.
Powiązana lektura:
Skrypty Bash :: Porównania ciągów
Instrukcje Ubuntu pgrep
pgrep
ma tę samą „cechę” limitu 15 znaków, o której wspominano wcześniej, dlatego też na przykład pgrep gnome-power-manager
również by się nie powiodła
-x
opcji pgrep : „ Dopasowuj tylko procesy, których nazwa (lub wiersz poleceń, jeśli podano -f) jest dokładnie zgodny ze wzorcem”.
Zwykle mam pidof -x $(basename $0)
na swoich skryptach, aby sprawdzić, czy już działa.
Riffując pomysł @ rommel-cid, możesz użyć pidof
z || (||), aby uruchomić polecenie, jeśli proces nie istnieje, i &&, aby uruchomić coś, jeśli proces istnieje, tworząc w ten sposób szybką warunek if / then / else. Na przykład tutaj jest jeden z uruchomionym procesem (moja przeglądarka chrome, którego nazwa procesu to „chrome”) i jeden testujący proces, który nie istnieje. Pominąłem standardowe wyjście, używając 1> / dev / null, aby nie drukowało:
$ (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
$
Żadne z „prostych” rozwiązań nie działało dla mnie, ponieważ plik binarny, który muszę sprawdzić, nie jest zainstalowany w całym systemie, więc muszę sprawdzić ścieżkę, która z kolei wymaga zastosowania ps -ef | grep
podejścia:
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
Pierwsza rzecz, jaka przyszła mi do głowy dla twojego problemu:
ps aux | grep -i abc
pokaże szczegóły procesu, jeśli jest on uruchomiony. Możesz dopasować liczbę linii lub czas, przez który jest uruchomiony, i porównać z zerem lub inną manipulacją. Po uruchomieniu powyższego polecenia wyświetli się co najmniej jeden wiersz danych wyjściowych, tj. Szczegóły dotyczące procesu utworzonego za pomocą tego polecenia grep. Zajmij się tym.
To powinno wystarczyć jako zwykły hack. Umieść go w skrypcie bash i sprawdź, czy jest pomocny.
Używanie start-stop-daemon
:
/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2
Działa jak zwykły użytkownik.
Odkryłem, że zaakceptowana odpowiedź wysłana przez @Johna Vrbanaca nie działała dla mnie i że odpowiedź wysłana przez @geirha nie odpowiada na pierwotne pytanie.
Rozwiązanie Johna Vrbanaca nie działało, aby sprawdzić, czy proces PHP jest uruchomiony, czy nie dla mnie, używam CentOS 7.
Odpowiedź @ geirha tylko upewnia się, że instancja nie jest jeszcze uruchomiona przed uruchomieniem kolejnej. To nie było oryginalne pytanie, pierwotne pytanie polegało na sprawdzeniu, czy proces jest uruchomiony, czy nie.
Oto, co zadziałało dla mnie:
Powiedzmy, że mój proces miał ciąg „Jane” w nazwie procesu. Przekona się, czy jest uruchomiony, czy nie. Działa to dla skryptów BASH i 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 &)
Uwaga : pgrep -x lxpanel
lub pidof lxpanel
nadal zgłasza, że lxpanel
działa, nawet gdy jest nieczynny (zombie); więc aby uzyskać żywy proces, musimy użyć ps
igrep
Według stanu na 23 września 2016 r. Pgrep wymaga opcji „-x”, aby skrypt Muru działał.
#!/bin/bash
if pgrep -x "conky" > /dev/null 2>&1
then
echo "conky running already"
else
echo "now starting conky"
conky
fi
exit 0
Próbowałem i przetestowałem powyższy skrypt na komputerze Ubuntu 16.04.1. Cieszyć się!
#!/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
proces ”(nie to, co nazwałbym„ działającym ”procesem). Pełna lista tego, co wskazująSTAT
wartości kolumny na wyjściups
, jest tutaj dla tych, którzy są skłonni do napisania odpowiedzi, która to uwzględnia, lub edycji własnych.