2010-10-31 5 views
0

J'utilise le script suivant pour obtenir le processus en cours pour imprimer l'id, commande ..problème avec awk et grep


if [ "`uname`" = "SunOS" ] 
then 
    awk_c="nawk" 
    ps_d="/usr/ucb/" 
    time_parameter=7 
else 
    awk_c="awk" 
    ps_d="" 
    time_parameter=5 
fi 

main_class=RiskEngine 
connection_string=db.regression 

AWK_CMD='BEGIN{printf "%-15s %-6s %-8s %s\n","ID","PID","STIME","Cmd"} {printf "%-15s %-6s %-8s %s %s %s\n","MY_APP",$2,$time_parameter, main_class, connection_string, port}' 

while getopts ":pnh" opt; do 
    case $opt in 
    p) AWK_CMD='{ print $2 }' 
     do_print_message=1;; 
    n) AWK_CMD='{printf "%-15s %-6s %-8s %s %s %s\n","MY_APP",$2,$time_parameter,main_class, connection_string, port}' ;; 
    h) print "usage : `basename ${0}` {-p} {-n} : Returns details of process running " 
     print " -p : Returns a list of PIDS" 
     print " -n : Returns process list without preceding header" 
     exit 1 ; 

    esac 
done 

ps auxwww | grep $main_class | grep 10348 | grep -v grep | ${awk_c} -v main_class=$merlin_main_class -v connection_string=$merlin_connection_ 
string -v port=10348 -v time_parameter=$time_parameter "$AWK_CMD" 

# cat /etc/redhat-release 
Red Hat Enterprise Linux AS release 4 (Nahant Update 6) 
# uname -a 
Linux deapp25v 2.6.9-67.0.4.EL #1 Fri Jan 18 04:49:54 EST 2008 x86_64 x86_64 x86_64 GNU/Linux 

Quand j'exécute ce qui suit de le script indépendamment ou à l'intérieur du script

# ps auxwww | grep $main_class | grep 10348 | grep -v grep | ${awk_c} -v main_class=$merlin_main_class -v connection_string=$merlin_connection_string -v port=10348 -v time_parameter=$time_parameter "$AWK_CMD" 

Je reçois deux lignes sur Linux:

ID    PID STIME Cmd 
MY_APP  6217 2355352 RiskEngine 10348 
MY_APP  21874 5316  RiskEngine 10348 

Je viens d'une machine virtuelle (commande Java) en cours d'exécution en arrière-plan mais je vois 2 lignes.

Je connais l'un d'entre eux (Dupliquer avec pid 21874) vient de la commande awk que j'exécute. Il comprend à nouveau la classe principale et le port donc deux rangs. Pouvez-vous s'il vous plaît m'aider à éviter celui qui est en double rangée?

Pouvez-vous s'il vous plaît aidez-moi?

Répondre

0

Vous utilisez déjà l'astuce grep -v grep dans votre code, pourquoi ne pas simplement le mettre à jour pour exclure le processus awk ainsi que grep -v ${awk_c}?

En d'autres termes, la dernière ligne de votre script serait (sur une ligne et avec les paramètres de commande réelle à awk plutôt que blah blah blah) .:

ps auxwww 
    | grep $main_class 
    | grep 10348 
    | grep -v grep 
    | grep -v ${awk_c} 
    | ${awk_c} -v blah blah blah 

Cela garantira la liste des processus ne sera pas containg tout avec le mot awk dedans. Gardez à l'esprit que ce n'est pas toujours une bonne idée de le faire de cette façon (faux positifs) mais, puisque vous prenez déjà le risque avec des processus contenant grep, vous pouvez aussi le faire avec ceux contenant awk ainsi .

0

J'ai reformaté le code en code, mais vous devez apprendre que la clé de retour est votre ami. Les pipelines monstrueusement longs devraient être répartis sur plusieurs lignes - j'utilise généralement une ligne par commande dans le pipeline. Vous pouvez également écrire des scripts awk sur plus d'une ligne. Cela rend votre code plus lisible.

Ensuite, vous devez nous expliquer ce que vous faites.

Cependant, il est probable que vous utilisez « awk » en tant que variante grep et trouvent que la valeur 10348 (peut-être conçu comme un numéro de port sur une ligne de commande) est également dans la sortie de ps comme l'un des les arguments à awk (comme la valeur 'main_class'), donc vous obtenez les informations supplémentaires. Vous aurez besoin de réviser le script awk pour éliminer (ignorer) la ligne qui contient 'awk'. Notez que vous pouvez toujours être bousculé par une commande exécutant votre classe principale sur le port 9999 (n'importe quelle valeur autre que 10348) s'il se produit qu'il est exécuté par un processus avec PID ou PPID égal à 10348. Si vous ' Le script 'awk' doit analyser uniquement la partie 'commande plus options' de la ligne.

2

AWK peut tout faire pour vous.

Voici un exemple simple de la façon dont une commande AWK peut être sélective:

ps auxww | awk -v select="$mainclass" '$0 ~ select && /10348/ && ! (/grep/ || /awk/) && {print}' 

ps peuvent être apportées aux champs de manière sélective de sortie qui aideront un peu réduire les faux positifs. Cependant pgrep peut vous être plus utile puisque tout ce que vous utilisez vraiment est le PID du résultat.

pgrep -f "$mainclass.*10348" 
0

Vous pouvez ajouter ce code simple en face de tous vos awk args: '!/Awk/{.... code awk d'origine ....}

Le ' !/awk/' aura pour effet de dire à awk d'ignorer toute ligne contenant la chaîne awk.

Vous pouvez également supprimer votre grep -v si vous avez prolongé ma suggestion awk dans quelque chose comme: '!/Awk/& &/grep/{... code awk d'origine ...}' .