LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Question about awk (https://www.linuxquestions.org/questions/linux-newbie-8/question-about-awk-4175594225/)

backslashV 11-25-2016 10:59 AM

Question about awk
 
Hi,

I am printing the children of a process using this command:

Code:

ps -aef | grep 13783 | grep -v grep | grep -v ps | grep -v $0
and it shows the children correctly. (2 in my case)

The thing is that when I pipe it to awk to get the PIDs like this:

Code:

ps -aef | grep 13783 | grep -v grep | grep -v ps | grep -v $0 | awk '{print $2}'
I get 3 numbers. I don't know where that 3rd number is coming from.

jpollard 11-25-2016 11:47 AM

You might check that "grep 13783" looks for the string 13783 - and that may be a substring of another process id.

I did a "ps -aef | grep $$ | grep -v grep | grep -v ps" to see what this looked like - and got two processes, one mine (1245), and one from another user (11245).

You can prevent that by doing better pattern search: grep " $pid " as the spaces will reduce that issue. It doesn't prevent the resulting string from being in some other field though.

To do that would require more of the effort to be put into the awk script. Let it do the search for the parent pid ( third field), as well as being able to remove the cmd 'ps' from the selected list.

backslashV 11-25-2016 11:53 AM

if i just do:

Code:

ps-aef | grep 13783
I get:

Code:

cs11amb  13783 13324  0 08:44 pts/0    00:00:00 bash
cs11amb  13971 13783  0 08:44 pts/0    00:00:00 vim ff
cs11amb  14000 13783  0 08:44 pts/0    00:00:00 vim ss
cs11amb  19461 13783  7 09:49 pts/0    00:00:00 ps -aef
cs11amb  19463 13783  0 09:49 pts/0    00:00:00 grep 13783

when i grep out the extras, I only get

Code:

cs11amb  13971 13783  0 08:44 pts/0    00:00:00 vim ff
cs11amb  14000 13783  0 08:44 pts/0    00:00:00 vim ss

which are the correct children and what I want.

The problem is when I use awk, it prints:

Code:

13971
14000
21253


Turbocapitalist 11-25-2016 12:02 PM

Is that last PID that of the "awk" process itself?

Also, with "awk" there you don't need any of the "grep" processes at all.

backslashV 11-25-2016 12:06 PM

Quote:

Originally Posted by Turbocapitalist (Post 5634484)
Is that last PID that of the "awk" process itself?

Also, with "awk" there you don't need any of the "grep" processes at all.

I swear to god I tried to grep out awk before but it still showed up.
It is working now. Thank youuu.

Could you be more specific when you say I don't need any of the greps?

backslashV 11-25-2016 12:13 PM

In a script, I am trying to put the children in an array by saying:

Code:

for child in `ps -aef | grep $pid | grep -v grep | grep -v ps | grep -v $0 | grep -v awk | grep -v bash | awk '{print $2}'`; do
        arrayOfChildren+=("$child")
done

but echoing the array afterward
instead of the children PIDs as the array contents I get:

5
5

If I do
Code:

echo `ps -p ${#arrayOfChildren[0]}`
echo `ps -p ${#arrayOfChildren[1]}`

I get

PID TTY TIME CMD 5 ? 00:00:00 stopper/0
PID TTY TIME CMD 5 ? 00:00:00 stopper/0

pan64 11-25-2016 12:47 PM

why don't you try pgrep -P ?

backslashV 11-25-2016 12:48 PM

Quote:

why don't you try pgrep -P ?
I am not allowed.

pan64 11-25-2016 01:16 PM

You will not be able to list all the children "in one", because all the members of your chain (grep, awk, whatever) will be children and you need to exclude them, but actually there can be other grep/awk/whatever children which should be reported but will be ignored too. The best you can do is to save the output of the command ps and process the result afterward, or use a single awk which will exclude itself and print everything else.
ps -aef | awk -vmypid=$$ { look for $3 as parent pid and also look for aw }

why aren't you allowed to use pgrep?

backslashV 11-25-2016 01:23 PM

Quote:

Originally Posted by pan64 (Post 5634504)
You will not be able to list all the children "in one", because all the members of your chain (grep, awk, whatever) will be children and you need to exclude them, but actually there can be other grep/awk/whatever children which should be reported but will be ignored too. The best you can do is to save the output of the command ps and process the result afterward, or use a single awk which will exclude itself and print everything else.
ps -aef | awk -vmypid=$$ { look for $3 as parent pid and also look for aw }

why aren't you allowed to use pgrep?

I want to store the result of ps in an array.

Code:

for child in `ps -aef | grep $pid | grep -v grep | grep -v ps | grep -v $0 | grep -v awk | grep -v bash | awk '{print $2}'`; do
      arrayOfChildren+=("$child")
done

echoing the contents with ps shows:

Code:

PID TTY TIME CMD 5 ? 00:00:00 stopper/0
PID TTY TIME CMD 5 ? 00:00:00 stopper/0

so basically the contents of the array are:
5
5

but before putting into the array I echo the output of
Code:

ps -aef | grep $pid | grep -v grep | grep -v ps | grep -v $0 | grep -v awk | grep -v bash | awk '{print $2}'
and i get the correct children PIDs like this:
13432 13324

I am not sure why I am not allowed to use that. I just asked and the TA said no.

backslashV 11-25-2016 02:35 PM

Solved
 
It appears that the problem was putting a # before the array name: ${#arrayOfChildren[0]}
removing that solved the problem.
Thanks everyone.

grail 11-25-2016 02:54 PM

Also, here is your possible all awk solution to feed your loop:
Code:

ps -aef | awk -vpid=$pid '$3 == pid && $NF != "-aef" && $NF !~ "pid"'


All times are GMT -5. The time now is 07:54 PM.