Vivek Bernard
Vivek Bernard

Reputation: 2073

How to read input from the stdout of another command (pipe) in linux shell script?

My objective is to find the process that is consuming the most CPU and RAM by writing a script. I've managed to extract the info from TOP command however, I'm having trouble parsing the output.

The following command,

top -b -n 1 | tail -n +8 | head -n 1

Will output something similar to this single line,

915 root      20   0  209m  74m 8644 S    8  7.7   5:27.57 Xorg

I want this line of text to be the argument list for my script. I realize that I have to read it from the STDIN but, I want to read the above output word by word, or argument by argument as if it was given from the command line.

echo " Parameter is ${2} ${3}"

Upvotes: 3

Views: 2736

Answers (5)

Tony Delroy
Tony Delroy

Reputation: 106244

Given

# 915 root      20   0  209m  74m 8644 S    8  7.7   5:27.57 Xorg  

you can read it all straight into meaninfully-named variables:

top -b -n 1 | tail -n +8 | head -n 1 |
    read XPID XUSERID XPRIORITY XVIRTUAL XRESIDENT XSHARED XSTATE XCPU XMEM XTIME XCOMMAND

(only problem is if the values get so large the columns touch each other... in which case you need to use something like cut with hardcoded column numbers rather than rely on whitespace separation)

Upvotes: 1

jyz
jyz

Reputation: 6199

Just for fun :)

top -b -n1 | head -8 | tail -2 | awk '
{
    if (NR==1) {
        print "\nHey teacher, leave those kids alone! - Pink Floyd ;)\n";
        print $2,$1,$9,$10;
        next;
    }
    print $2,$1,$9,$10;
}'

Or if you want another report format:

top -b -n1 | head -8 | tail -1 | awk '{ printf "User: %s\nPID: %s\nCPU Usage: %s\nMEM Usage: %s\n", $2,$1,$9,$10 }'

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 247210

Use set -- to force the arguments to become positional parameters.

set -- $(top -b -n 1 | tail -n +8 | head -n 1)
echo " Parameter is ${2} ${3}"

Upvotes: 2

Richard Fearn
Richard Fearn

Reputation: 25511

Get the line into a variable:

OUTPUT=`top -b -n 1 | tail -n +8 | head -n 1`

Convert to an array:

LIST=($OUTPUT)

And output the fields:

echo ${LIST[1]}
echo ${LIST[2]}

Upvotes: 1

polemon
polemon

Reputation: 4782

save the output line with squeezing all whitespace characters:

LINE=$(top -b -n 1 | tail -n +8 | head -n 1 | tr -s ' ')

And then use cut to get the part you want:

echo " Parameter is $(echo $LINE | cut -d' ' -f2) $(echo $LINE | cut -d' ' -f3)"

etc.

granted, not the most elegant way, but the fastest I can come up with

Upvotes: 1

Related Questions