从 strace 输出中提取系统调用名称

extract syscall names from strace output

我使用以下命令从 strace 输出中提取系统调用名称:

strace ls 3>&1 1>&2 2>&3 3>&- | grep -P -o '^[a-z]*(?=\()'

但是此命令的输出中还包含 ls 输出。 我该如何预防?

最后我在这个 link 的帮助下找到了解决方案:http://mywiki.wooledge.org/BashFAQ/047

strace ls 2>&1 >/dev/null | grep -P -o '^[a-z]*(?=\()'

和一个有用的变体来计算系统调用:

strace ls 2>&1 >/dev/null | grep -P -o '^[a-z]*(?=\()' | sort | uniq -c | sort -nr

更好的解决方案是使用 Mark Plotnick 的回答:

strace -o >(grep -P -o '^[a-z]*(?=\()' | sort | uniq -c | sort -nr) ls &>/dev/null

strace 有两个选项可以帮助您获得想要的结果:

  • -c 将通过命令输出所有系统调用 运行 的 table,以及它们被调用的次数和 CPU 使用情况。
$ strace -c ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 31.07    0.000653          20        32           mmap
  9.94    0.000209          20        10           mprotect
  9.80    0.000206          12        16           read
  8.28    0.000174          15        11           close
  7.61    0.000160          16        10           fstat
  6.90    0.000145          16         9           openat
  2.47    0.000052          17         3         3 ioctl
...
  • -o 选项会将 strace 的输出发送到一个文件,因此它不会与您的进程的输出混在一起。

以下将 运行 ls 命令,将其输出转移到 /dev/null,并将 strace 的输出发送到 awk 脚本以提取最后一列:

$ strace -o >(awk ' ~ /^-----/ { toprint = !toprint; next } { if (toprint) print $NF }') \
  -c ls >/dev/null 2>/dev/null
mmap
mprotect
read
close
fstat
openat
ioctl
...