Como extrair um par de valores de chaves do comando ps

10

Estou tentando extrair o nome do aplicativo do comando ps da seguinte forma:

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

e produz o seguinte:

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

Eu tentei usar egrep , mas parece que não está funcionando:

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

Como posso obter apenas o valor -Dapp.name "myApp"?

    
por Sas 15.10.2014 / 19:45

6 respostas

7

com awk :

ps -af -u sas | awk 'BEGIN {RS=" "}; /-Dapp.name/'
    
por 15.10.2014 / 20:02
8

Você não está mostrando a mensagem de erro que está recebendo, mas provavelmente

grep: unknown devices method

Isso porque, como todos ou pelo menos a maioria dos outros programas de linha de comando, grep assume que qualquer coisa que comece com - é uma opção e tenta analisá-lo como tal. Nesse caso, -D é usado para instruir grep sobre como lidar com um arquivo de dispositivo (consulte man grep para obter detalhes). Uma maneira de contornar isso é usar -- , que diz grep que qualquer coisa seguinte não é um sinalizador de opção.

Combinando isso com o recurso PCRE do GNU grep , você pode fazer:

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

A expressão regular procura por - e descarta-a ( \K ), depois a string Dapp.name= seguida por tantos caracteres não espaciais quanto possível. A saída é:

Dapp.name=myApp

Se você quiser que a parte myApp seja salva em uma variável, eu procuraria por ela sozinha:

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

Para atribuí-lo a uma variável:

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

No entanto, você nunca deve grep a saída de ps para esse tipo de coisa, é isso que pgrep é para:

app="$(pgrep -a java | grep -Po -- '^Dapp.name=\K[^\s]+')"
    
por 15.10.2014 / 19:57
4
ps -af -u sas | sed -n '/[j]ava/s/.*-Dapp\.name=\([^ ]*\).*//p'
    
por 15.10.2014 / 19:53
3

Mais complicado que as outras respostas, mas isso usa getopt para lidar com a análise para você. Ainda outra alternativa.

getopt -aql 'Dapp.name:' $(\
    ps -af -u sas | grep java | grep -v grep | tr -s ' ' | cut -d' ' -f8-\
) | cut -d"'" -f2
  1. seu comando: ps -af -u sas | grep java | grep -v grep
  2. tr -s ' ' "aperta" vários espaços em um único espaço em preparação para cut
  3. cut -d' ' -f8- divide a linha por espaços e pega todos os campos depois de 8 inclusive, o resultado é /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:' $(...) analisa as opções de comando e gera apenas o nome longo que corresponde a Dapp.name que tem um valor (denotado por : ), o resultado é --Dapp.name 'myApp' --
  5. cut -d"'" -f2 pega o material nas citações simples
  6. O resultado é: myApp
por 15.10.2014 / 23:21
2

Toda vez que você usa ps … | grep … e precisa excluir o grep dos resultados, está fazendo errado.

A regra zero de analisar a saída de ps é usar ferramentas mais confiáveis, como pgrep , se disponível. Se você tiver pgrep, pgrep -f java listará todos os processos executando o comando java . A opção -l adiciona a linha de comando para cada processo.

Para extrair o argumento para -Dapp.name , você pode usar sed. Combine toda a linha, organize a parte interessante em um grupo e imprima esse grupo.

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

A primeira regra de análise da saída de ps é usar a opção -o para selecionar os campos que você precisa. Aqui, você está interessado apenas nos argumentos do comando, então imprima apenas isso.

ps -e -o args= | sed -n 's/^.*-Dapp\.name=\([^ ]*\).*$//p'
    
por 16.10.2014 / 01:43
0

Eu usaria pgrep em vez de ps da seguinte forma:

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

Isso retornará todos os processos que correspondem a java e, em seguida, filtrará os que mostrarem apenas os que contiverem -Dapp.name= . O último bit, \w+ mostrará o nome do programa, assumindo que não contém espaços.

OBSERVAÇÃO: A opção -P para grep inscreve a capacidade de especificar coisas usando PCRE - Compatível com Perl Regular Expressões . Nem todas as versões do grep suportam, mas a maioria inclui versões mais modernas do Linux.

Se você quiser a saída de chave / valor inteira, altere as coisas da seguinte forma:

$ pgrep -fa java | grep -oP -- "-Dapp.name=\w+"
    
por 15.10.2014 / 20:26