Filtrar procesos por nombre y buen número.

Filtrar procesos por nombre y buen número.

Estoy intentando crear un script para encontrar el número PID solo con el nombre del proceso y el número bonito, pero no puedo.

Respuesta1

Usar pgreppara obtener primero los PID de todos los procesos que coincidan con la expresión dada como primer argumento, y luego recorrerlos para extraer los que tienen un buen valor correspondiente al segundo argumento.

find_pid_by_name_and_nice () {
    pgrep -- "${1:?missing process name}" |
    xargs -I {} ps -o pid= -o nice= -p {} |
    awk -v nice="${2?missing nice value}" '$NF == nice { print $1 }'
}

Pruebas:

$ find_pid_by_name_and_nice
find_pid_by_name_and_nice:1: 1: missing process name
find_pid_by_name_and_nice:3: 2: missing nice value
$ find_pid_by_name_and_nice netdata
find_pid_by_name_and_nice:3: 2: missing nice value
$ find_pid_by_name_and_nice netdata 19
258881
258937
$ find_pid_by_name_and_nice netdata 15

(ninguna salida)

Respuesta2

by_name_and_nice(){ grep -hoPs "^[^ ]+(?= \($1\)( [^ )]+){16} $2 )" /proc/*/stat; }

by_name_and_nice bash 0encontrará todos bashlos procesos con su amabilidad = 0 (el valor predeterminado),

by_name_and_nice 'b.*' '.*'encontrará todos los procesos cuyo nombre comience con a b, sin importar su amabilidad, y así sucesivamente.

Si sigue lo anterior para obtener procesos con nuevas líneas y basura binaria en sus nombres, es posible que necesite algo un poco más complicado:

by_name_and_nice(){
    local -; set -o pipefail
    LC_ALL=C grep -zhoPs "^[^ ]+(?= \($1\)( [^ )]+){16} $2 )" /proc/*/stat | xargs -0rn1
}

Para hacer coincidir una nueva línea en el nombre del proceso, debe usar by_name_and_nice '(?s:foo.*)' 0(lea más sobre elsintaxis de expresiones regulares pcreutilizado por la opción GNU grep -P).


Esto es sólo para fines de demostración; es bastante inútil intentar seleccionar por buen valor sin algún operador mayor o menor que. Además, seleccionar por nombre de proceso no es muy confiable, porque el nombre del proceso está bajo el control total del proceso, que es abusado implacablemente por cualquier malware de dos bits y software basura que se llame a sí mismo pso bash. Una mejor idea sería seleccionar por el nombre base del binario, como en

find /proc/*/exe -lname '*/whatever'

Desarrollando todo esto queda como ejercicio para el lector ;-)

Respuesta3

POSIXly, con psy awk:

by_name_and_nice() {
  # returns pids of processes with $2 as niceness and whose
  # process name matches the $1 extended regexp
  ps -A -o pid= -o nice= -o comm= |
    NAME=$1 NICE=$2 awk '
      $2 == ENVIRON["NICE"] {
        pid = $1
        sub(/^[[:space:]]*[^[:space:]]+ +[^[:space:]]+ /, "")
        if ($0 ~ ENVIRON["NAME"]) print pid
      }'
}

Eso supone que hay un solo carácter de espacio entre la columna de amabilidad y el nombre del proceso. Ese es el caso de la implementación procps-ng que normalmente se encuentra en los sistemas basados ​​en Linux, pero POSIX no lo garantiza. Podrías eliminar todos los espacios en blanco después de la columna de amabilidad, pero eso corre el riesgo de tergiversar los procesos cuyo nombre comienza con espacios en blanco.

Tenga en cuenta que procps-ng psal menos cambia los caracteres no imprimibles ?en la salida y lo que constituye un carácter no imprimible depende de la ubicación de la persona que llama a ps. Por ejemplo, un proceso con UTF-8 Stéphanecomo nombre podría representarse como St??phanesi la configuración regional usara un juego de caracteres diferente al de UTF-8.

Sin embargo, las procps-ngimplementaciones de psDoes admiten una -Copción para hacer coincidir procesos en el nombre (inspirado en HP/UX' ps), aunque se trata de una coincidencia exacta de igualdad byte a byte en lugar de una coincidencia de expresión regular, por lo que podría hacer:

by_name_and_nice() {
  # returns pids of processes with $2 as niceness and whose
  # process name is exactly $1
  ps -C "$1" -o pid= -o nice= |
    awk -v nice="$2" '$2 == nice {print $1}'
}

información relacionada