Question about awk

Hi,

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

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:

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.

I hope not to interfere with your awk learning process, but a look at the ps manpage revealed an easier method to get child processes:

ps --ppid 13783

Thanks. I knew about that, but I need to use awk. Used --ppid before and that one also produces 3 where it should be 2.

I can't really tell where it's coming from either, as I can't see your input, and without that, can't follow your logic.

It'd be much easier to control it though, if you weren't running awk | sed | cut | fold | kitchen | sink, just running one awk instead. One process to exclude instead of 9.

Post your input, and post the output you want, please.

Ok I solved the issue with the extra number. I had to grep out bash.

Now storing in the array doesn't work

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:

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
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.

It really would.

I've seen the output you want, but not the input. So I will take a wild uninformed guess at what you actually want and hope that ps -aef looks the same on my system as yours:

# Apache's PID is 10820
$ ps 10820
  PID TTY      STAT   TIME COMMAND
10820 ?        Ss     0:28 /usr/sbin/apache2 -D INFO -D SSL -D LANGUAGE -D PHP5
# So, list all PIDs where PPID, col 3, are 10820
$ ps -aef | awk -v PARENT="10820" '$3 == PARENT { print $2 }'

19832
20286
20304
20305
25669
25690
25692
25693
25694
25770
30264

# This time, put them in an array
$ ARRAY=( `ps -aef | awk -v PARENT="10820" '$3 == PARENT { print $2 }'` )

$ echo ${ARRAY[0]}
19832
$ echo ${ARRAY[1]}
20286
$

By hunting for meaningful values rather than blind text matches, all the grep -v | grep -v | grep -v | grep -v | grep -v | grep -v | grep -v | grep -v can be avoided.

How about

ps -aef | awk '$3 == 13783 {print $2}'

? Adapt if PPID is NOT field 3...

EDIT: Hoppla - this is pretty close to what Corona668 posted just a few minutes ago - sorry!

would it be ok if I message you with my code?

[EDIT]: It appears that the problem was putting a # before the array name: ${#arrayOfChildren[0]}
removing that solved the problem. Still using

 ps -aef | awk -v PARENT="10820" '$3 == PARENT { print $2 }'

produces 3 PIDs where only 2 are the children.

[EDIT] the 3rd one is the script process I am running. How can I exclude it using your code?

You should post to the forums and obscure anything you don't want seen.

I'm guessing this means my code didn't work?

Please see my edit above.

If it didn't have a parent PID of 12345, it wouldn't be extracted, I'm not convinced this is actually wrong.

If the process you're running happens to be a child of the process in question, it will appear as a side-effect of course. If all you want is your own children, you could just do ps -ef without the a, no?

Ok so the processes are as follows:

csuser1  13324 13306 -bash
csuser1  13783 13324  \_ bash
csuser1  13971 13783      \_ vim ff
csuser1  14000 13783      \_ vim ss

I am running the script like this:

./myscript 13783

It is supposed to only show the two vim children processes.

right now, using your code, running the script and echoing the array contents shows:

PID TTY TIME CMD 13971 pts/0 00:00:00 vim
PID TTY TIME CMD 14000 pts/0 00:00:00 vim
PID TTY TIME CMD 22202 pts/0 00:00:00 myscript
ps -aef | awk -v SELF="$0" -v PARENT="10820" '($2 != SELF) && ($3 == PARENT) { print $2 }'

still prints the process itself.

Which itself? The script (which I know nothing of its contents), the awk, the ps, or something else?

Try this:

(       ps -ef > /tmp/$$
        exec 0</tmp/$$
        rm /tmp/$$
        exec awk -v SELF="$!" -v PARENT="9611" '($3 == PARENT) && ($2 != SELF) { print $2 }' )

[edit] This won't work. $! is a background process, not awk's own pid.

$$ is also the parent's own PID, even in the subshell. Not sure how to get the subshell's pid yet.

How about

ps -aef | awk -v SELF="$$" -v PARENT="13783" '($2 != SELF) && ($3 == PARENT) { print $2 }'

Yes the script.

---------- Post updated at 01:28 PM ---------- Previous update was at 01:27 PM ----------

If I assign this to an array, the PIDS won't be separated into indices.

pgrep -P 13783

I'm not allowed to use pgrep.