Мені потрібна незалежна від платформи (Linux / Unix | OSX) команда shell / bash, яка визначатиме, чи працює конкретний процес. наприклад mysqld
, httpd
... Який найпростіший спосіб / команда це зробити?
Мені потрібна незалежна від платформи (Linux / Unix | OSX) команда shell / bash, яка визначатиме, чи працює конкретний процес. наприклад mysqld
, httpd
... Який найпростіший спосіб / команда це зробити?
Відповіді:
Хоча pidof
і pgrep
є чудовими інструментами для визначення того, що працює, вони, на жаль, недоступні в деяких операційних системах. Безперечним відмовою в безпеці буде використання наступного:ps cax | grep command
Вихід на Gentoo Linux:
14484? S 0:00 apache2 14667? S 0:00 apache2 19620? Sl 0:00 apache2 21132? Ss 0:04 apache2
Вихід на OS X:
42582 ?? Z 0: 00,00 (smbclient) 46529 ?? Z 0: 00,00 (smbclient) 46539 ?? Z 0: 00,00 (smbclient) 46547 ?? Z 0: 00,00 (smbclient) 46586 ?? Z 0: 00,00 (smbclient) 46594 ?? Z 0: 00,00 (smbclient)
І в Linux, і в OS X grep повертає вихідний код, тому легко перевірити, знайдено процес чи ні:
#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
Крім того, якщо ви хочете, щоб список PID-кодів, ви також можете легко похвалитися за ці:
ps cax | grep httpd | grep -o '^ [] * [0-9] *'
Чий вихід однаковий для Linux та OS X:
3519 3521 3523 3524
Вихід із наведеного нижче є порожнім рядком, що робить цей підхід безпечним для процесів, які не виконуються:
відлуння ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'
Цей підхід підходить для написання простого тесту порожнього рядка, а потім навіть повторення через виявлені PID.
#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
echo "Process not running." 1>&2
exit 1
else
for PID in $PIDS; do
echo $PID
done
fi
Ви можете перевірити його, збереживши його у файл (названий "запущеним") з дозволами на виконання (chmod + x running) та виконавши його з параметром: ./running "httpd"
#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
echo "Process is running."
else
echo "Process is not running."
fi
УВАГА!!!
Будь ласка, майте на увазі, що ви просто розбираєте вихід, а ps ax
це означає, що, як видно з виходу Linux, це не просто збігання процесів, а й аргументи, передані цій програмі. Я настійно рекомендую бути максимально конкретним при використанні цього методу (наприклад ./running "mysql"
, також відповідатиме "mysqld" процесам). Я настійно рекомендую використовувати, which
щоб перевірити повний шлях, де це можливо.
Список літератури:
grep
також виявиться запущеним (наприклад ps cax | grep randomname
, завжди поверне 0, тому що grep
знаходить grep randomname
(сподіваюся, це зрозуміло ...). Одним виправленням є додавання квадратних дужок навколо першої літери імені процесу, наприклад ps cax | grep [r]andomname
.
ps cax | rev | cut -f1 -d' ' | rev
відображатиметься лише стовпець імені для полегшення розбору.
ps cax
не може виводити ім'я команди повністю. Наприклад, він друкує "Chrome-браузер" замість "Chrome-браузер".
Пошук процесу, намагаючись зробити якесь розпізнавання шаблонів на аргументах процесу (як pgrep "mysqld"
), - це стратегія, яка рано чи пізно приречена на збій. Що робити, якщо у вас працює два mysqld? Забудьте про такий підхід. Ви МОЖЕТЕ отримати це право тимчасово, і воно МОЖЕ працювати рік-два, але тоді трапляється щось, про що ви не думали.
Тільки ідентифікатор процесу (pid) справді унікальний.
Завжди зберігайте під, коли ви запускаєте щось у фоновому режимі. У Bash це можна зробити за допомогою $!
змінної Bash. Ви заощадите настільки багато проблем, зробивши це.
Тож тепер стає питання, як дізнатись, чи працює пуд.
Просто робіть:
ps -o pid = -p <pid>
Це POSIX і, отже, портативний. Він поверне сам pid, якщо процес запущений, або нічого не поверне, якщо процес не працює. Строго кажучи, команда поверне один стовпець, pid
але, оскільки ми дали, що порожній заголовок заголовка (матеріал, що безпосередньо передує знаку рівності), і це єдиний запитуваний стовпець, тоді команда ps взагалі не буде використовувати заголовка. Що ми хочемо, тому що це полегшує розбір.
Це буде працювати на Linux, BSD, Solaris тощо.
Іншою стратегією було б перевірити значення виходу з вищевказаної ps
команди. Він повинен бути нульовим, якщо процес запущений, і не нульовим, якщо його немає. Специфікація POSIX говорить, що ps
необхідно вийти> 0, якщо сталася помилка, але мені незрозуміло, що являє собою "помилку". Тому я особисто не використовую цю стратегію, хоча я впевнений, що вона буде добре працювати на всіх платформах Unix / Linux.
grep <sometext>
щоб знайти заданий процес, то ви зробили щось не так, коли ви розпочали процес, IMHO. Я беру на думку питання ОП, що він справді має контроль над тим, як розпочато процес.
У більшості дистрибутивів Linux можна використовувати pidof
(8).
Він надрукує ідентифікатори процесу всіх запущених екземплярів зазначених процесів, або нічого, якщо не буде запущених екземплярів.
Наприклад, у моїй системі (у мене є чотири екземпляри bash
та один екземпляр remmina
запуску):
$ pidof bash remmina
6148 6147 6144 5603 21598
В інших Уніках pgrep
або в поєднанні ps
та grep
досягнуть того самого, як справедливо зазначали інші.
pidof httpd
прекрасно працює на Red Hat 5. Але на моїй Red Hat 4, pidof
немає :-(
Це має працювати на більшості ароматів Unix, BSD та Linux:
PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep
Тестовано на:
PATH=...
]ps
. Щоб уникнути другого, grep
пропоную:ps aux | grep [h]ttpd
grep
.
Найпростішим способом є використання ps та grep:
command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
echo "Command is running"
else
echo "Command is not running"
fi
Якщо у вашій команді є декілька аргументів команди, ви можете також поставити більше 'grep cmd_arg1' після 'grep $ command', щоб відфільтрувати інші можливі процеси, які вас не цікавлять.
Приклад: покажіть мені, чи є який-небудь процес Java з наданим аргументом:
-Djava.util.logging.config.file = logging.properties
біжить
ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l
ps cax
виключає необхідність використання grep -v
. Так, наприклад, ви можете використовувати: ps cax | grep java > /dev/null || echo "Java not running"
.
Лише незначне доповнення: якщо ви додасте -c
прапор до ps, після цього не потрібно видаляти рядок, що містить процес grep grep -v
. Тобто
ps acux | grep cron
- це все, що вам потрібно набрати в системі bsd-ish (сюди входить MacOSX) Ви можете залишити -u
подалі, якщо вам потрібно менше інформації.
У системі, де генетика нативної ps
команди вказує на SysV, ви використовуєте
ps -e |grep cron
або
ps -el |grep cron
для списку, що містить більше, ніж просто pid та ім'я процесу. Звичайно, ви можете вибрати конкретні поля для друку, використовуючи цю -o <field,field,...>
опцію.
Поєднуючи різні пропозиції разом, найчистіша версія, яку мені вдалося придумати (без ненадійного жадання, що запускає частини слів), це:
kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
kill -0 не вбиває процес, але перевіряє, чи він існує, а потім повертає true, якщо у вас немає pidof у вашій системі, зберігайте pid під час запуску процесу:
$ mysql &
$ echo $! > pid_stored
потім у сценарії:
kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
Я використовую, pgrep -l httpd
але не впевнений, що він присутній на будь-якій платформі ...
Хто може підтвердити на OSX?
pidof
будь ласка? Добре, що ти зробив. Дякую. Тому ми повинні знайти щось інше, що працює над OSX ... Вашим основним ps|grep
може бути єдине рішення ;-)
Коли ви запускаєте його, його PID буде записаний у $!
змінну. Збережіть цей PID у файл.
Тоді вам потрібно буде перевірити, чи відповідає цей PID виконуваному процесу. Ось повний сценарій скелета:
FILE="/tmp/myapp.pid"
if [ -f $FILE ];
then
PID=$(cat $FILE)
else
PID=1
fi
ps -o pid= -p $PID
if [ $? -eq 0 ]; then
echo "Process already running."
else
echo "Starting process."
run_my_app &
echo $! > $FILE
fi
Виходячи з відповіді о peterh
. Хитрість дізнатися, чи працює даний PID, є в ps -o pid= -p $PID
інструкції.
Цей підхід може бути використаний у випадку, якщо команди "ps", "pidof" та інші недоступні. Я особисто дуже часто використовую PROFS у своїх інструментах / скриптах / програмах.
egrep -m1 "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3
Невелике пояснення, що відбувається:
Це друкує кількість процесів, базовим ім'ям яких є "Chrome-браузер":
ps -e -o args= | awk 'BEGIN{c=0}{
if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"
Якщо це надрукує "0", процес не запущений. Команда припускає, що шлях процесу не містить пробільного простору. Я не перевіряв цього з призупиненими процесами чи процесами зомбі.
Тестовано з використанням gwak
в якості awk
альтернативи в Linux.
Ось більш універсальне рішення з прикладом використання:
#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
local quiet=1;
shift
else
local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
name=$2
if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}
process='chromium-browser'
printf "Process \"${process}\" is "
if isProcessRunning -q "$process"
then printf "running.\n"
else printf "not running.\n"; fi
printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"
Ось моя версія. Особливості:
сценарій:
#!/bin/bash
# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
for i in $(pidof $1); do
cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
if [ $? -eq 0 ]; then
return 0
fi
done
return 1
}
isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
echo "not running, starting..."
fi
Жодна з відповідей не працювала для мене, тому ось моя:
process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
echo "Process is not running."
else
echo "Process is running."
fi
Пояснення:
|tr -d '\n'
Це видаляє повернення каретки, створене терміналом. Решту можна пояснити цією публікацією.
Наступна функція оболонки, що базується лише на стандартних командах та параметрах POSIX, повинна працювати на більшості (якщо такої немає) системи Unix та Linux. :
isPidRunning() {
cmd=`
PATH=\`getconf PATH\` export PATH
ps -e -o pid= -o comm= |
awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
`
[ -n "$cmd" ] &&
printf "%s is running\n%s\n\n" "$1" "$cmd" ||
printf "%s is not running\n\n" $1
[ -n "$cmd" ]
}
$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd
$ isPidRunning ksh
ksh is running
5230 ksh
$ isPidRunning bash
bash is not running
Зауважте, що він задихнеться при передачі сумнівного імені команди "0]", а також не зможе визначити процеси, що мають вбудований простір у свої імена.
Зауважте також, що найбільш схвалене та прийняте рішення вимагає переносних ps
параметрів і безперешкодно використовує оболонку, яка, незважаючи на свою популярність, не гарантується, щоб бути присутнім на кожній машині Unix / Linux ( bash
)
$ isPidRunning 0]
друкує, наприклад, "0] працює 3 [ksoftirqd / 0] 8 [rcuop / 0] 17 [rcuos / 0] 26 [rcuob / 0] 34 [міграція / 0] 35 [сторожовий / 0]" тут.