Score:3

How do I use the output of "pgrep" with "ps -p"?

mn flag

I'm trying to display Conkys process uptime. If I type the following into the terminal one line at a time it all works and I get the result I'm after.

getPID=$(pgrep -f conky)

conkyPID=$(ps -p $getPID -o etime=)

echo $conkyPID

Naive me thought a bash script would look like this.

#!/bin/bash
getPID=$(pgrep -f conky)
conkyPID=$(ps -p "$getPID" -o etime=)
echo "$conkyPID"

I've asked a couple of friends and the most helpful info I received was I need a command line separator and I think it's a |. I've tried a lot of variations of brackets, quotes and pipes to no avail. In my experimenting it appears the 2nd line has no idea I have set the variable "getPID" in the previous line. When I run the script I get.

error: process ID list syntax error

Output of running script with bash -x:

ricky@Shitmobile:~$ bash -x conkypid.sh
++ pgrep -f conky 
+ getPID='45990
153098'
++ ps -p '45990 153098' -o etime=
error: process ID list syntax error 
Score:5
vn flag

In your case, since each line is a separate command, it doesn't make any difference - the script should work: (note that $getPID and $conkyPID should be quoted)

#!/bin/bash
getPID=$(pgrep -f conky)
conkyPID=$(ps -p "$getPID" -o etime=)
echo "$conkyPID"

I have tested, and this works fine for me.

However, since pgrep can return multiple values as output (which is true in your case), you should isolate the output so you only fetch the earliest PID. So modify like this:

#!/bin/bash
getPID=$(pgrep -fo conky)
# getPID=$(pgrep -f conky | head -n 1) # another, but not as elegant method
conkyPID=$(ps -p "$getPID" -o etime=)
echo "$conkyPID"

This will only fetch the first PID for conky, and display the elapsed time for this PID.

On the other hand, if you wish to process all PIDs that might be output by pgrep, then you can pipe the output to xargs with ps like so:

 pgrep -f conky | xargs -I _ ps -p _ -o etime=

Where -I _ will both process only one arguments line(pgrep outputs each single PID on a newline by default) at a time and pass it to ps -p _ ... in-place/position of the place-holder _. ... You can also assign the value/s to the variable directly with command substitution and even shorten your script like so:

conkyPID=$(pgrep -f conky | xargs -I _ ps -p _ -o etime=)
echo "$conkyPID"
Artur Meinild avatar
vn flag
I added a fix by taking only the first PID with `head -n 1`.
justchillin avatar
mn flag
Bazinga, head did the trick. Thank you. I cant even remember why I wanted conky uptime, but found I learnt a ton in the process.
justchillin avatar
mn flag
Thanks @Raffa for being the first to point out the probability of more than one process with conky in the name. I didn't/don't see any other conky processes in the system monitor, if I had I don't think I would have been quite so naive looking for a PID by a keyword that was in more than one process.
Raffa avatar
jp flag
@justchillin You're welcome ... `-f` doesn't really match the process's name but, rather matches the full command line(*or part of it*) that was used to launch a process while system monitor shows exact process's name ... So, it's probable that the other process just happened to have `conky` in its command or filename or as an argument.
hr flag
fyi `pgrep` has a `-o` / `--oldest` and `-n` / `--newest` that would provide an alternate method for selecting just a single PID
Artur Meinild avatar
vn flag
@steeldriver right, I remember that now..
Artur Meinild avatar
vn flag
@Raffa please add the `xargs` solution - I'm not that familiar with it.
Raffa avatar
jp flag
@ArturMeinild done :-)
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.