[英]Why doesn't “xargs sudo perf top” work as expected?
I want to profile a process, so first get its pid, then use " perf top
" to check it:我想分析一个进程,所以首先获取它的 pid,然后使用“
perf top
”来检查它:
$ 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
:然后我想使用 pipe 来连接这两个命令,所以我使用
xargs
:
$ pgrep program | sudo xargs perf top -p
But this time " perf top
" seems not work normally:但这一次“
perf top
”似乎无法正常工作: I compared processes of these two operations:
我比较了这两个操作的过程:
(1) Run pgrep
and perf
separately: (1)分别运行
pgrep
和perf
:
$ 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
: (2) 使用
xargs
连接pgrep
和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!
提前致谢!
PS, my OS is CentOS 7
. PS,我的操作系统是
CentOS 7
。
After checking manual again, I find -o
option can fix this issue:再次检查手册后,我发现
-o
选项可以解决此问题:
-o, --open-tty Reopen stdin as /dev/tty in the child process before executing the command.
-o, --open-tty 在执行命令之前,在子进程中重新打开标准输入为 /dev/tty。 This is useful if you want xargs to run an interactive application.
如果您希望 xargs 运行交互式应用程序,这将很有用。
The command is like this:命令是这样的:
$ pgrep program | sudo xargs -o perf top -p
But unfortunately, CentOS 7
's xargs
is a little old, and doesn't provide this option.但不幸的是,
CentOS 7
的xargs
有点老了,没有提供这个选项。
The root cause is: without -o
option, the stdin
of perf
program is /dev/null
:根本原因是:没有
-o
选项perf
stdin
的标准输入是/dev/null
:
$ sudo lsof -p 1495
......
perf 1495 root 0r CHR 1,3 0t0 2052 /dev/null
......
And the perf
is blocked in SLang_getkey() :并且性能在
perf
()中被阻止:
......
FD_ZERO(&read_set);
FD_SET(0, &read_set);
if (delay_secs) {
timeout.tv_sec = delay_secs;
timeout.tv_usec = 0;
}
err = select(1, &read_set, NULL, NULL, ptimeout);
if (err == 0)
return K_TIMER;
if (err == -1) {
if (errno == EINTR)
return K_RESIZE;
return K_ERROR;
}
key = SLang_getkey();
if (key != K_ESC)
return key;
......
Read of /dev/null
will return EOF
, then select()
will return 1
.读取
/dev/null
将返回EOF
,然后select()
将返回1
。
With -o
option the stdin
of perf
program is /dev/tty
:使用
-o
选项, perf
程序的标准输入是/dev/tty
stdin
$ sudo lsof -p 1394
......
perf 1394 root 0u CHR 136,25 0t0 28 /dev/pts/25
......
In above code, the select()
will return 0
, and the whole function will return accordingly.在上面的代码中,
select()
将返回0
,整个 function 将相应地返回。
A better approach would be to directly run the top
on the output of pgrep
instead of piping over xargs
.更好的方法是直接在
pgrep
的 output 上运行top
,而不是通过xargs
管道。 I believe top
command by default does not read information over standard input我相信默认情况下
top
命令不会通过标准输入读取信息
sudo perf top -p "$(pgrep program)"
This way the $(..)
returns the output of the pgrep
command and the returned value is passed as a positional argument value to the -p
flag.这样
$(..)
返回pgrep
命令的 output 并且返回的值作为位置参数值传递给-p
标志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.