Unix/Linux Go Back    


Shell Programming and Scripting BSD, Linux, and UNIX shell scripting — Post awk, bash, csh, ksh, perl, php, python, sed, sh, shell scripts, and other shell scripting languages questions here.

Avoid running unnecessary repetitive ps command

Shell Programming and Scripting


Reply    
 
Thread Tools Search this Thread Display Modes
    #1  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
SkySmart's Unix or Linux Image
SkySmart SkySmart is offline
Registered User
 
Join Date: Dec 2006
Last Activity: 14 January 2018, 11:38 AM EST
Posts: 907
Thanks: 748
Thanked 3 Times in 3 Posts
Avoid running unnecessary repetitive ps command

i have the following code:



Code:
                APIDS=$(echo $(ps -ef | awk -v gpid="${gpid}" '$2 == gpid || $3 == gpid {print $2,$3}') | sed 's~ ~|~g')
                AllProcs=$(ps -ef | awk -v allpids="${APIDS}" '$2 ~ allpids || $3 ~ allpids {print $0}' | sed '/^$/d')

it seems the above APIDS variable was created only to gather IPs. and then it is fed to the real command in the AllProcs variable.

can this be shortened into one command and also in an efficient way?
Sponsored Links
    #2  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
bakunin's Unix or Linux Image
bakunin bakunin is offline Forum Staff  
Bughunter Extraordinaire
 
Join Date: May 2005
Last Activity: 21 January 2018, 4:46 PM EST
Location: In the leftmost byte of /dev/kmem
Posts: 5,678
Thanks: 112
Thanked 1,633 Times in 1,198 Posts
Quote:
Originally Posted by SkySmart View Post
can this be shortened into one command and also in an efficient way?
At some point in this bla | foo | kitchen | sink-, ahem, -command i lost the ability to picture a possible outcome. Could you please explain what this supposed to achieve? Or let it run on the system it was designed for and show some sample outcome.

One point i immediately saw was that ps -ef | awk ... | sed ... must be nonsense because either use awk or use sed and furthermore probably both are superfluous because the output of ps cat be tailored using the -o option. See the man page for details.

I hope this helps.

bakunin
Sponsored Links
    #3  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
Don Cragun's Unix or Linux Image
Don Cragun Don Cragun is offline Forum Staff  
Administrator
 
Join Date: Jul 2012
Last Activity: 21 January 2018, 11:05 PM EST
Location: San Jose, CA, USA
Posts: 10,929
Thanks: 611
Thanked 3,819 Times in 3,263 Posts
Maybe something like this would work:


Code:
ps -ef | awk -v gpid="$gpid" '
{	line[NR] = $0
	pid[NR] = $2
	ppid[NR] = $3
}
$2 == gpid || $3 == gpid {
	PrintPid[$2]
	PrintPid[$3]
}
END {	for(i = 1; i <= NR; i++)
		if(pid[i] in PrintPid || ppid[i] in PrintPid)
			print line[i]
}'

but, of course, ps -ef output may vary somewhat from operating system to operating system and you haven't told us what OS you're using. And, if you're using a Solaris/SunOS system, you'll need to change awk to /usr/xpg4/bin/awk or nawk.
The Following User Says Thank You to Don Cragun For This Useful Post:
SkySmart (1 Week Ago)
    #4  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
RudiC's Unix or Linux Image
RudiC RudiC is online now Forum Staff  
Moderator
 
Join Date: Jul 2012
Last Activity: 22 January 2018, 3:28 AM EST
Location: Aachen, Germany
Posts: 11,966
Thanks: 354
Thanked 3,688 Times in 3,386 Posts
After sorting out some lome logical errors(e.g. the allpids matching), I guess you want a listing of the gpid process and its subprocesses. Try


Code:
ps -ef | awk -vGPID="$gpid" '$2 " " $3 ~ GPID'

The Following User Says Thank You to RudiC For This Useful Post:
SkySmart (1 Week Ago)
Sponsored Links
    #5  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
apmcd47's Unix or Linux Image
apmcd47 apmcd47 is offline
Registered User
 
Join Date: Feb 2011
Last Activity: 19 January 2018, 6:57 AM EST
Posts: 294
Thanks: 13
Thanked 80 Times in 77 Posts
Quote:
Originally Posted by SkySmart View Post
i have the following code:



Code:
                APIDS=$(echo $(ps -ef | awk -v gpid="${gpid}" '$2 == gpid || $3 == gpid {print $2,$3}') | sed 's~ ~|~g')
                AllProcs=$(ps -ef | awk -v allpids="${APIDS}" '$2 ~ allpids || $3 ~ allpids {print $0}' | sed '/^$/d')

it seems the above APIDS variable was created only to gather IPs. and then it is fed to the real command in the AllProcs variable.

can this be shortened into one command and also in an efficient way?
So it looks to me that you are trying to list all the processes with the PID or PPID of "${gpid}"

Consider this:


Code:
ps --ppid "${gpid}" -opid=

This will list the PIDs of all processes whose PPID is the gpid. If you have it,


Code:
pgrep -P${gpid} -d,

will do the same but give them in a comma-delimited list. So perhaps this?


Code:
ps -f --pid$(pgrep -P${gpid} -d,),${gpid}

If you don't have pgrep then you have to turn the output of my earlier ps command into a comma-delimited list and use that.

Caveat: GNU ps, GNU pgrep.

Andrew
The Following User Says Thank You to apmcd47 For This Useful Post:
SkySmart (1 Week Ago)
Sponsored Links
    #6  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
MadeInGermany's Unix or Linux Image
MadeInGermany MadeInGermany is offline Forum Staff  
Moderator
 
Join Date: May 2012
Last Activity: 22 January 2018, 3:00 AM EST
Location: Simplicity
Posts: 3,947
Thanks: 335
Thanked 1,322 Times in 1,192 Posts
post#4 is unprecise (like post#1), for example will find pid 22 when searching for 2.
While the overall sense is not clear for me, this is certainly *not* intended.
Fix:


Code:
ps -ef | awk -vGPID="$gpid" '($2 == GPID || $3 == GPID)'

Doesn't give this the same result as the code in post#3 ?
Linux
The Following 2 Users Say Thank You to MadeInGermany For This Useful Post:
RudiC (1 Week Ago), SkySmart (1 Week Ago)
Sponsored Links
    #7  
Old Unix and Linux 1 Week Ago   -   Original Discussion by SkySmart
Don Cragun's Unix or Linux Image
Don Cragun Don Cragun is offline Forum Staff  
Administrator
 
Join Date: Jul 2012
Last Activity: 21 January 2018, 11:05 PM EST
Location: San Jose, CA, USA
Posts: 10,929
Thanks: 611
Thanked 3,819 Times in 3,263 Posts
Quote:
Originally Posted by MadeInGermany View Post
post#4 is unprecise (like post#1), for example will find pid 22 when searching for 2.
While the overall sense is not clear for me, this is certainly *not* intended.
Fix:


Code:
ps -ef | awk -vGPID="$gpid" '($2 == GPID || $3 == GPID)'

Doesn't give this the same result as the code in post#3 ?
Linux
No. It doesn't give the same result as the code in post #3. With slightly modified versions of these scripts:
./tester:


Code:
#!/bin/ksh
gpid=${1:-$$}
ps -ef | tee ps.out | awk -v gpid="$gpid" '
{	line[NR] = $0
	pid[NR] = $2
	ppid[NR] = $3
}
$2 == gpid || $3 == gpid {
	PrintPid[$2]
	PrintPid[$3]
}
END {	for(i = 1; i <= NR; i++)
		if(pid[i] in PrintPid || ppid[i] in PrintPid)
			print line[i]
}'

Note that this captures the output from ps in ps.out which will be used as input for the other two scripts instead of rerunning ps. The above script produces the output:


Code:
  501   766   763   0  7Dec17 ttys003    0:01.40 -ksh
  501 27188   766   0 12:40PM ttys003    0:01.01 du /
  501 27189   766   0 12:40PM ttys003    0:00.01 /bin/ksh ./tester
    0 27190 27189   0 12:40PM ttys003    0:00.00 ps -ef
  501 27191 27189   0 12:40PM ttys003    0:00.00 tee ps.out
  501 27192 27189   0 12:40PM ttys003    0:00.00 awk -v gpid 27189

during a period where the command du / > du.out was running in the background while this script was running.

With this version of SkySmart's code modified to read from the ps.out produced by the above script:
./SkySmart:


Code:
#!/bin/ksh
gpid=${1:-$$}
APIDS=$(echo $(awk -v gpid="${gpid}" '$2 == gpid || $3 == gpid {print $2,$3}' ps.out) | sed 's~ ~|~g')
AllProcs=$(awk -v allpids="${APIDS}" '$2 ~ allpids || $3 ~ allpids {print $0}' ps.out | sed '/^$/d')
printf '%s\n' "$AllProcs"

and run with the operand 27189, we get the output:


Code:
  501   766   763   0  7Dec17 ttys003    0:01.40 -ksh
  501 27188   766   0 12:40PM ttys003    0:01.01 du /
  501 27189   766   0 12:40PM ttys003    0:00.01 /bin/ksh ./tester
    0 27190 27189   0 12:40PM ttys003    0:00.00 ps -ef
  501 27191 27189   0 12:40PM ttys003    0:00.00 tee ps.out
  501 27192 27189   0 12:40PM ttys003    0:00.00 awk -v gpid 27189

which is identical to the output produced by the code in post #3. But with a similarly modified version of MadeInGermany's code:
./MadeInGermany:


Code:
#!/bin/ksh
gpid=${1:-$$}
awk -v GPID="$gpid" '($2 == GPID || $3 == GPID)' ps.out

and run with the operand 27189, we only get the output:


Code:
  501 27189   766   0 12:40PM ttys003    0:00.01 /bin/ksh ./tester
    0 27190 27189   0 12:40PM ttys003    0:00.00 ps -ef
  501 27191 27189   0 12:40PM ttys003    0:00.00 tee ps.out
  501 27192 27189   0 12:40PM ttys003    0:00.00 awk -v gpid 27189

MadeInGermany's simpler code doesn't catch the parent, sibling, or grandchild processes of the process specified by $gpid. It only catches the process specified by $gpid and its children.

I do, however, agree that SkySmart's code works by accident when $gpid specifies a PID that isn't small enough to accidentally match several other unintended PIDs of unrelated running processes.
The Following 2 Users Say Thank You to Don Cragun For This Useful Post:
Chubler_XL (6 Days Ago), MadeInGermany (6 Days Ago)
Sponsored Links
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Linux More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
How to avoid error with ln command? mohtashims Shell Programming and Scripting 4 12-02-2016 01:14 PM
How to avoid running duplicated task? ken6503 Shell Programming and Scripting 5 01-07-2015 06:30 PM
how to avoid time command output selvaka UNIX for Dummies Questions & Answers 5 12-07-2010 06:59 AM
Avoid script running multiple times by filelock edenCC Shell Programming and Scripting 4 10-23-2009 12:12 AM
How to avoid historying my command ting123 UNIX for Dummies Questions & Answers 2 05-06-2006 05:58 AM



All times are GMT -4. The time now is 04:30 AM.