2016-08-10 1 views
0

У меня есть файл со многими сервисами имена, некоторые из них запущены, некоторые из них не являются.Эффективно найти PID многих процессов, запущенных службами

foo.service bar.service baz.service

Я хотел бы найти эффективный способ получить ИДП запущенных процессов запущенных служб (для не работающих из них а 0, -1 или пустые результаты справедливы).

Желаемый выход пример:

foo.service:8484 bar.server: baz.service:9447

(bar.service не работает).

До сих пор мне удалось сделать следующее: (1)

cat t.txt | xargs -I {} systemctl status {} | grep 'Main PID' | awk '{print $3}'

С следующий вывод:

8484 9447

Но я не могу сказать, какой обслуживание каждого PID принадлежит.

(Я не обязан использовать xargs, grep или awk .. просто ищет наиболее эффективный способ).

До сих пор мне удалось сделать следующее: (2)

for f in `cat t.txt`; do 
    v=`systemctl status $f | grep 'Main PID:'`; 
    echo "$f:`echo $v | awk '{print \$3}'`"; 
done; 

- это дает мне мой желаемый результат. Это достаточно эффективно?

Спасибо!

ответ

0

Вы также можете сделать:

while read -r line; do 
    statuspid="$(sudo service $line status | grep -oP '(?<=(process|pid)\s)[0-9]+')" 

    appendline="" 
    [[ -z $statuspid ]] && appendline="${line}:${statuspid}" || appendline="$line" 

    "$appendline" >> services-pids.txt 
done < services.txt 

Для использования в переменной, вы можете также иметь ассоциативный массив:

declare -A servicearray=() 

while read -r line; do 
    statuspid="$(sudo service $line status | grep -oP '(?<=(process|pid)\s)[0-9]+')" 

    [[ -z $statuspid ]] && servicearray[$line]="statuspid" 
done < services.txt 

# Echo output of array to command line 
for i in "${!servicearray[@]}"; do # Iterating over the keys of the associative array 
    # Note key-value syntax 
    echo "service: $i | pid: ${servicearray[$i]}" 
done 

делает его более эффективным:

Перечислять все процессы с их командами выполнения и PID.Это может дать нам больше, чем один PID за команду, которая может оказаться полезной:

ps -eo pid,comm 

Итак:

psidcommand=$(ps -eo pid,comm) 

while read -r line; do 
    # Get all PIDs with the $line prefixed 
    statuspids=$(echo $psidcommand | grep -oP '[0-9]+(?=\s$line)') 

    # Note that ${statuspids// /,} replaces space with commas 
    [[ -z $statuspids ]] && appendline="${line}:${statuspids// /,}" || appendline="$line" 

    "$appendline" >> services-pids.txt 
done < services.txt 

ВЫВОД:

kworker:5,23,28,33,198,405,513,1247,21171,22004,23749,24055 

Если вы уверены, что ваш файл имеет полный название процесса, вы можете заменить:

grep -oP '[0-9]+(?=\s$line)' 

с

grep -oP '[0-9]+(?=\s$line)$' # Note the extra "$" at the end of the regex 

, чтобы убедиться, что это точное совпадение (в grep без закрывающего $, линия «Мыс» будет соответствовать с «MySQL»; в grepс trailing $, это не так, и будет соответствовать только «mysql»).

+0

Итак, производительность, выполняющая 'grep -oP ...', более эффективна, чем 'systemctl status ...'? Недостатком, как вы сказали, является несколько PID. – bomba6