Cómo extraer un par de valores clave del comando ps

10

Estoy tratando de extraer el nombre de la aplicación de un pscomando como este:

ps -af -u sas |grep "java"| grep -v "grep"

y produce lo siguiente:

sas 24431     1  0 Oct10 ?        00:51:08 /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs

Intenté usar egreppero no parece estar funcionando:

ps -af -u sas|grep "java"| grep -v "grep"| egrep -o "-Dapp.name"

¿Cómo puedo obtener solo el -Dapp.namevalor "myApp"?

Sas
fuente
Si el greppatrón comienza con -, debe colocarlo después de la -eopción. De lo contrario, se tratará como una opción. Pero eso solo coincidirá con la palabra -Dapp.name, no con la parte posterior.
Barmar
alternativamente:grep -o -- -Dapp.name
strugee
puede usar grep [j]avapara evitar el comando grep -v "grep"(probado en bash)
HVNSweeting

Respuestas:

7

Con awk:

ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'
jasonwryan
fuente
8

No está mostrando el mensaje de error que está recibiendo, pero probablemente sea

grep: método de dispositivos desconocidos

Esto se debe a que, como todos o al menos la mayoría de los otros programas de línea de comandos, grepsupone que todo lo que comienza con una -es una opción e intenta analizarlo como tal. En este caso, -Dse utiliza para instruir grepsobre cómo tratar con un archivo de dispositivo (ver man greppara más detalles). Una forma de evitar esto es usar lo --que indica grepque todo lo que sigue no es un indicador de opción.

Combinando eso con la capacidad PCRE de GNU grep, puede hacer:

ps -af -u sas | grep -v grep | grep -Po -- '*-\KDapp.name=[^\s]+'

La expresión regular busca -ay lo descarta ( \K), luego la cadena Dapp.name=seguida de tantos caracteres que no sean espacios como sea posible. El resultado es:

Dapp.name=myApp

Si desea myAppguardar la parte en una variable, buscaría eso solo:

ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+'

Para asignarlo a una variable:

$ app="$(ps -af -u sas | grep -v grep | grep -Po -- '-Dapp.name=\K[^\s]+')"
$ echo $app
myApp

Sin embargo, nunca debe ser grepla salida de pseste tipo de cosas, para eso pgrepestá:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"
terdon
fuente
4
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*/\1/p'
Barmar
fuente
3

Cada vez que usa ps … | grep …y necesita excluir grep de los resultados, lo está haciendo mal.

La regla cero de analizar la salida de pses utilizar herramientas más confiables, como pgrepsi están disponibles. Si tiene pgrep, pgrep -f javaenumera todos los procesos que ejecutan el comando java. La opción -lagrega la línea de comando para cada proceso.

Para extraer el argumento -Dapp.name, puede usar sed. Haga coincidir toda la línea, organice la parte interesante en un grupo e imprima ese grupo.

pgrep -lf java | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'

La primera regla para analizar la salida de pses utilizar la opción -opara seleccionar los campos que necesita. Aquí, solo le interesan los argumentos del comando, así que imprima solo eso.

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$/\1/p'
Gilles 'SO- deja de ser malvado'
fuente
3

Más complicado que las otras respuestas, pero esto se usa getoptpara manejar el análisis por usted. Otra alternativa más.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. su comando: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "exprime" múltiples espacios en un solo espacio en preparación para cut
  3. cut -d' ' -f8- divide la línea por espacios y toma todos los campos después de 8 inclusive, el resultado es /usr/lib/jvm/java-1.7.0-oracle-1.7.0.25.x86_64/jre/bin/java -Denv=DEV -Dapp.name=myApp -Xms512m -Xmx1g -Dlog.dir=/apps/java/logs
  4. getopts -aql 'Dapp.name:' $(...)analiza las opciones de comando y genera solo el nombre largo que coincide con Dapp.namequién tiene un valor (indicado por :), el resultado es--Dapp.name 'myApp' --
  5. cut -d"'" -f2 agarra las cosas entre comillas simples
  6. El resultado es: myApp
zamnuts
fuente
0

Yo usaría en pgreplugar de psasí:

$ pgrep -fa java | grep -op "(<=-Dapp.name=)\w+"

Esto devolverá todos los procesos que coinciden javay luego los filtrará mostrando solo los que contienen -Dapp.name=. El último bit \w+mostrará el nombre del programa, suponiendo que no contiene espacios.

NOTA: El -Pcambio a grepalista la capacidad de especificar cosas usando PCRE - Expresiones regulares compatibles con Perl . No todas las versiones lo grepadmiten, pero la mayoría lo hacen con versiones más modernas de Linux.

Si desea la salida completa de la clave / valor, cambie las cosas así:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
slm
fuente