Problema com o AWK dentro do bash

1

Olá, há um longo histórico: Estou tentando criar um script para executar o servidor de IC para eliminar um processo específico.

Então, pesquisando pela internet, descobri este comando:

myuser@server:/home/myuser# ps -ef | grep someUniqueText | grep -v grep | awk '{print $2}'
5263

Quando eu o executo no console, ele me retorna exatamente o que preciso ( 5263 ), então criei este bash:

#!/bin/bash

PROCESSNAME=$1
PID=$(ps -ef | grep $PROCESSNAME | grep -v grep | awk '{print $2}');

echo $PID;

Quando eu executo como:

myuser@server:/home/myuser# ./killProcess.sh somename
5263 4587 1236

O script bash retorna 3 números sendo o primeiro o processo que eu preciso e não tenho idéia do que os outros dois são, Por quê? o.O

PS .: Estou usando echo para testar primeiro, vou mudar para kill -9

    
por Jorge Campos 11.05.2018 / 17:01

2 respostas

2

Ao executar ./killProcess.sh somename , um processo semelhante a

/bin/bash ./killProcess.sh somename

existe e a ps | grep | grep | awk -line também encontra essa porque tem o texto somename nela. Eu não sei exatamente porque você tem dois PIDs adicionais (e não apenas um), mas eu acho que é alguma coisa entre pais / filhos entre bash e killProcess.sh . Em uma linha, o PID aparece como PID e, no outro, como PPID.

Você pode evitar esses PIDs usando o nome do script. Ele é armazenado em $0 , então

PID=$(ps -ef | grep $PROCESSNAME | grep -v grep | grep -v $0 | awk '{print $2}');

ou (com menos chamadas de programa):

PID=$(ps -ef | grep $PROCESSNAME | grep -v -e grep -e $0 | awk '{print $2}');

Outra maneira (mais segura) seria remover o PID do script. Está armazenado em $$ :

PID=$(ps -ef | grep $PROCESSNAME | grep -v -e grep -e $$ | awk '{print $2}');

Ou faça tudo em awk :

PID=$(ps -ef | awk "/$PROCESSNAME/ && !/awk/ && !/$$/ {print \}");

Precisamos escapar do \ aqui, por isso não é interpretado pelo shell, mas sim por awk . Esse comando significa:

Se a linha contiver $PROCESSNAME e não contiver awk e não contiver nosso próprio PID, imprima a segunda coluna.

A vantagem é (em teoria) que isso é mais rápido porque apenas um comando adicional ( awk ) é necessário, em oposição a 3 greps e awk.

Mas:

Todos esses greps e awks não são perfeitos e você sempre encontrará uma situação que não temos aqui (como correspondências parciais, etc.). Por isso recomendo usar uma das ferramentas já escritas:

por PerlDuck 11.05.2018 / 19:39
2

Uma vez eu implementei uma idéia semelhante, como uma função de shell, que eu chamo de psg (para "ps | grep")

psg() {
    local -a patterns=()
    (( $# == 0 )) && set -- $USER
    for arg do 
        patterns+=( "-e" "[${arg:0:1}]${arg:1}" )
    done
    ps -ef | grep "${patterns[@]}"
}

Isso usa um truque para colocar o primeiro caractere do padrão entre colchetes, então você obtém

ps -ef | grep "[s]omename"

Isso permite descartar a parte grep -v grep do pipeline.

Se você não transmitir nenhum argumento, ele usará seu nome de usuário para pesquisar seus processos.

    
por glenn jackman 11.05.2018 / 18:48