I want to profile a process, so first get its pid, then use "perf top
" to check it:
$ pgrep program
14472
$ sudo perf top -p 14472
It works as expected:
Then I want to use pipe to connect these two commands, so I use xargs
:
$ pgrep program | sudo xargs perf top -p
But this time "perf top
" seems not work normally:
I compared processes of these two operations:
(1) Run pgrep
and perf
separately:
$ ps -ef | grep perf
root 18468 16827 0 09:34 pts/3 00:00:00 sudo perf top -p 14472
root 18469 18468 91 09:34 pts/3 00:00:06 perf top -p 14472
nanxiao 18477 18295 0 09:34 pts/4 00:00:00 grep --color=auto perf
(2) Use xargs
to connect pgrep
and perf
:
$ ps -ef | grep perf
nanxiao 18250 16827 0 09:32 pts/3 00:00:00 xargs sudo perf top -p
root 18251 18250 0 09:32 pts/3 00:00:00 sudo perf top -p 14472
root 18252 18251 87 09:32 pts/3 00:01:47 perf top -p 14472
nanxiao 18442 18295 0 09:34 pts/4 00:00:00 grep --color=auto perf
IMHO, it seems same. Anyone can give some clues? Thanks in advance!
P.S., my OS is CentOS 7
.
2
Answers
After checking manual again, I find
-o
option can fix this issue:The command is like this:
But unfortunately,
CentOS 7
'sxargs
is a little old, and doesn't provide this option.The root cause is: without
-o
option, thestdin
ofperf
program is/dev/null
:And the
perf
is blocked in SLang_getkey():Read of
/dev/null
will returnEOF
, thenselect()
will return1
.With
-o
option thestdin
ofperf
program is/dev/tty
:In above code, the
select()
will return0
, and the whole function will return accordingly.A better approach would be to directly run the
top
on the output ofpgrep
instead of piping overxargs
. I believetop
command by default does not read information over standard inputThis way the
$(..)
returns the output of thepgrep
command and the returned value is passed as a positional argument value to the-p
flag.