为什么 "xargs sudo perf top" 没有按预期工作?
Why doesn't "xargs sudo perf top" work as expected?
我想分析一个进程,所以首先获取它的 pid,然后使用“perf top
”来检查它:
$ pgrep program
14472
$ sudo perf top -p 14472
它按预期工作:
然后我想用管道连接这两个命令,所以我用xargs
:
$ pgrep program | sudo xargs perf top -p
但是这次“perf top
”似乎不能正常工作:
我比较了这两个操作的过程:
(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) 使用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
恕我直言,好像一样。任何人都可以提供一些线索吗?提前致谢!
P.S.,我的OS是CentOS 7
.
更好的方法是在 pgrep
的输出上直接 运行 top
,而不是通过管道 xargs
。我相信 top
默认情况下命令不会通过标准输入读取信息
sudo perf top -p "$(pgrep program)"
这样 $(..)
returns pgrep
命令的输出和返回值作为位置参数值传递给 -p
标志。
再次检查manual后,我发现-o
选项可以解决这个问题:
-o, --open-tty
Reopen stdin as /dev/tty in the child process before executing
the command. This is useful if you want xargs to run an
interactive application.
命令是这样的:
$ pgrep program | sudo xargs -o perf top -p
但不幸的是,CentOS 7
的xargs
有点老了,没有提供这个选项。
根本原因是:没有-o
选项,perf
程序的stdin
是/dev/null
:
$ sudo lsof -p 1495
......
perf 1495 root 0r CHR 1,3 0t0 2052 /dev/null
......
并且 perf
在 SLang_getkey() 中被阻止:
......
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;
......
读取 /dev/null
将 return EOF
,然后 select()
将 return 1
.
使用 -o
选项 perf
程序的 stdin
是 /dev/tty
:
$ sudo lsof -p 1394
......
perf 1394 root 0u CHR 136,25 0t0 28 /dev/pts/25
......
在上面的代码中,select()
将 return 0
,并且整个函数将相应地 return。
我想分析一个进程,所以首先获取它的 pid,然后使用“perf top
”来检查它:
$ pgrep program
14472
$ sudo perf top -p 14472
它按预期工作:
然后我想用管道连接这两个命令,所以我用xargs
:
$ pgrep program | sudo xargs perf top -p
但是这次“perf top
”似乎不能正常工作:
(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) 使用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
恕我直言,好像一样。任何人都可以提供一些线索吗?提前致谢!
P.S.,我的OS是CentOS 7
.
更好的方法是在 pgrep
的输出上直接 运行 top
,而不是通过管道 xargs
。我相信 top
默认情况下命令不会通过标准输入读取信息
sudo perf top -p "$(pgrep program)"
这样 $(..)
returns pgrep
命令的输出和返回值作为位置参数值传递给 -p
标志。
再次检查manual后,我发现-o
选项可以解决这个问题:
-o, --open-tty Reopen stdin as /dev/tty in the child process before executing the command. This is useful if you want xargs to run an interactive application.
命令是这样的:
$ pgrep program | sudo xargs -o perf top -p
但不幸的是,CentOS 7
的xargs
有点老了,没有提供这个选项。
根本原因是:没有-o
选项,perf
程序的stdin
是/dev/null
:
$ sudo lsof -p 1495
......
perf 1495 root 0r CHR 1,3 0t0 2052 /dev/null
......
并且 perf
在 SLang_getkey() 中被阻止:
......
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;
......
读取 /dev/null
将 return EOF
,然后 select()
将 return 1
.
使用 -o
选项 perf
程序的 stdin
是 /dev/tty
:
$ sudo lsof -p 1394
......
perf 1394 root 0u CHR 136,25 0t0 28 /dev/pts/25
......
在上面的代码中,select()
将 return 0
,并且整个函数将相应地 return。