LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-30-2011, 07:04 AM   #1
nachaz
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Rep: Reputation: Disabled
Getting a certain Parameter from the command-line of a foreign process in bash...


Hi everyone,

until now I used a certain command to extract positional arguments from the command line of certain processes I want to monitor:

Code:
#!/bin/bash
ps aux|grep Dxxx.home|grep -v grep|awk '{print "\tConf: " $19, "\tProcess: " $25, "\tPID: " $2}'
Here is what it does exaclty:
"ps aux" returns all processes including their command-line
"grep Dxxx.home" returns only the processes I'm interested in
"grep -v grep" excludes grep commandos...
"awk '{print "\tConf: " $19, "\tProcess: " $25, "\tPID: " $2}'" returns the 19th, the 25th as well as the 2nd column of the output

Regrettably returning the 19th and the 25th parameter doesn't not work anymore because the processes are now called using a different number of command line arguments. So I need a way to find and print the values following certain arguments, e.g:
instead of $25 I'd have to find the argument following the "-p"-Argument
instead of $17 I'd have to find the argument following the "-c"-Argument

Does anyone know how to accomplish this in a single bash-script?

Thanks in advance!
 
Old 12-31-2011, 12:25 PM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958
Could you give us an example of the ps output that needs to be processed? It's kind of hard to test solutions when you don't know what the input looks like.

In any case, the original command is a fairly good example of Useless Use of grep, as awk is perfectly capable of handling all line filtering internally.

It looks like the modified version would have to iterate through every field on the line, check it for the patterns you want, and output the value of a matching field + 1. Certainly doable, but it would require a bit of testing.

Finally, have you taken the time to look into all the options of ps? It's possible that you may already be able to get it to output only what you want, or at least format the lines in a way that's easier to parse.


To give you a head start, here are a few useful awk references:

http://www.grymoire.com/Unix/Awk.html
http://www.gnu.org/software/gawk/man...ode/index.html
http://www.pement.org/awk/awk1line.txt
http://www.catonmat.net/blog/awk-one...ined-part-one/

Last edited by David the H.; 12-31-2011 at 12:27 PM. Reason: linky fixxy
 
1 members found this post helpful.
Old 01-02-2012, 05:01 AM   #3
nachaz
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Well, here is an example ps-output:
Code:
xxxx     24824  154  6.6 6887532 2190560 pts/1 Sl   10:41  16:25 /usr/bin/java -server -Xms256m -Xmx4096m -XX:MaxPermSize=2048m -Dxxxx.home=/opt/xxxx/App -Djava.util.logging.config.file=/opt/xxxx/App/conf_xxxxTitan/logging.properties de.comp.xxxx.services.ProcessRunner -c /opt/xxxx/App/conf_xxxxTitan -u PROC_KOMM_USER -k xx -p KOMM -f
xxxx     24842  336 11.3 7013100 3749568 pts/1 Sl   10:41  35:40 /usr/bin/java -server -Xms256m -Xmx4096m -Dxxxx.home=/opt/xxxx/App -Djava.util.logging.config.file=/opt/xxxx/App/conf_xxxxTitan/logging.properties de.comp.xxxx.services.ProcessRunner -c /opt/xxxx/App/conf_xxxxTitan -u PROC_PROC_USER -k xx -p PROC -f
xxxx     22375  131  0.3 6649572 129588 pts/1  Sl   10:53   0:09 /usr/bin/java -server -Xms256m -Xmx4096m -Dxxxx.home=/opt/xxxx/App -Djava.util.logging.config.file=/opt/xxxx/App/conf_xxxxCallisto/logging.properties de.comp.xxxx.services.ProcessRunner -c /opt/xxxx/App/conf_xxxxCallisto -u PROC_KOMM_USER -k xx -p KOMM -f
xxxx     22376  128  0.4 6657764 134288 pts/1  Sl   10:53   0:08 /usr/bin/java -server -Xms256m -Xmx4096m -XX:MaxPermSize=2048m -Dxxxx.home=/opt/xxxx/App -Djava.util.logging.config.file=/opt/xxxx/App/conf_xxxxCallisto/logging.properties de.comp.xxxx.services.ProcessRunner -c /opt/xxxx/App/conf_xxxxCallisto -u PROC_PROC_USER -k xx -p PROC -f
Thanks for the awk-references - didn't know it was that powerful.

I'm going to give it a shot and post the solution - if I can do it.
 
Old 01-02-2012, 05:54 AM   #4
nachaz
LQ Newbie
 
Registered: Dec 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
This is the solution to the problem:

Code:
ps aux|grep Dxxx.home|grep -v grep|awk '{ for (i=0;i<=NF;i++ ) { if ( $i=="-c" ) { config_arg=i+1 } } for (i=0;i<=NF;i++ ) { if ( $i=="-p" ) { process_arg=i+1 } }   printf "\t Conf: " $config_arg "\tProcess: " $process_arg "\tPID: " $2 "\n" }'
The beautification of the awk-code:
Code:
{
  # Loop over all arguments (NF is the argument-count)
  for (i=0;i<=NF;i++ )
  {
    # If the argument is -c...
    if ( $i=="-c" )
    { 
      #save it's position into the variable config_arg and add one
      config_arg=i+1
    }
  }
   
  # Another loop over all arguments...
  for (i=0;i<=NF;i++ )
  {
    # If the argument is -p...
    if ( $i=="-p" )
    {
      #save it's position into the variable process_arg and add one
      process_arg=i+1
    }
  }
      
  # Do the output. Precede vars with $ to get the arguments and not just
  # their position...
  printf "\t Conf: " $config_arg "\tProcess: " $process_arg "\tPID: " $2 "\n"
}
The comments are telling you what the code is doing...

Thank's again for the Doc and especially the "Famous one-liners"!
 
Old 01-02-2012, 04:52 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958
Well done! You learn quickly.

You don't need two separate loops, however. You can process both variables in one pass. Your printf function was using the wrong syntax too.

I've also looked a bit at ps, and you can indeed tell it to output only the fields you want.

First the awk script, which I set to be stand-alone. It's mostly just a modified version of what you posted .
Code:
#!/usr/bin/awk -f

{
	if ( $0 ~ /Dxxx.home/ ) {
		# Loop over all arguments (NF is the argument-count)
		for ( i=0 ; i<=NF ; i++ ) {
			# If the argument is either -c or -p save the position of the next argument into a variable
			if ( $i == "-c" ) { config_arg = i+1 }
			if ( $i == "-p" ) { process_arg = i+1 }
		}

		# Do the output. Precede vars with $ to get the arguments and not just their position...
		printf "\tConf: %s\tProcess: %s\tPID: %s\n" , $config_arg , $process_arg , $1
	}
}
And to run it:

Code:
ps -eo "pid cmd" | script.awk
( ps also has a -C option, which matches the name of a process. But I don't know if it would work in this case as the process name appears to be variable. )


In fact, if you want, you can use getline to incorporate the command input straight into the awk script itself, and just run it stand-alone.

Code:
#!/usr/bin/awk -f

BEGIN{
	while ( ( "ps -eo 'pid cmd'" ) | getline ) {

		if ( $0 ~ /Dxxx.home/ ) {
			# Loop over all arguments (NF is the argument-count)
			for ( i=0 ; i<=NF ; i++ ) {
				# If the argument is either -c or -p save the position of the next argument into a variable
				if ( $i == "-c" ) { config_arg = i+1 }
				if ( $i == "-p" ) { process_arg = i+1 }
			}

			# Do the output. Precede vars with $ to get the arguments and not just their position...
			printf "\tConf: %s\tProcess: %s\tPID: %s\n" , $config_arg , $process_arg , $1
		}
	}
}

Last edited by David the H.; 01-02-2012 at 05:13 PM. Reason: formatting fixes && other minor corrections
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to change crashkenel parameter value from command line sinoyms Linux - Newbie 1 10-21-2011 11:46 AM
how to set parameter at the boot command line? ufmale Linux - Newbie 2 08-20-2010 09:32 PM
Does bash shell parameter expansion run the risk of overflowing command line buffer? david1941 Linux - Software 1 04-28-2009 11:13 PM
pass parameter in command line lingyun Linux - Newbie 4 04-21-2009 11:42 PM
Awk - get a parameter from the command line benjalien Programming 1 01-24-2006 10:06 AM


All times are GMT -5. The time now is 11:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration