简体   繁体   English

为什么“xargs sudo perf top”没有按预期工作?

[英]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)分别运行pgrepperf

$ 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连接pgrepperf

$ 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 7xargs有点老了,没有提供这个选项。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM