关于bash:如何从命令行获得Linux中CPU/内核的数量?

How to obtain the number of CPUs/cores in Linux from the command line?

我有这个脚本,但我不知道如何获取打印输出中的最后一个元素:

1
cat /proc/cpuinfo | awk '/^processor/{print $3}'

最后一个元素应该是CPU的数量,减去1。


处理EDOCX1[1]的内容是不必要的巴洛克风格。使用coreutils的一部分nproc,所以它应该在大多数Linux安装中都可用。

command nproc打印当前进程可用的处理单元数,可能少于联机处理器数。

要查找所有已安装的核心/处理器的数量,请使用nproc --all

在我的8核机器上:

1
2
$ nproc --all
8


1
cat /proc/cpuinfo | awk '/^processor/{print $3}' | wc -l

或者简单地

1
grep -c ^processor /proc/cpuinfo

它将计算从/proc/cpuinfo中的"处理器"开始的行数。

对于具有超线程的系统,可以使用

1
grep ^cpu\\scores /proc/cpuinfo | uniq |  awk '{print $4}'

它应该返回(例如)8(而上面的命令将返回16)


我发现最便携的解决方案是getconf命令:

1
getconf _NPROCESSORS_ONLN

这在Linux和Mac OS X上都有效。与其他一些方法相比,这一方法的另一个好处是getconf已经存在很长时间了。我必须开发的一些旧的Linux机器没有可用的nproclscpu命令,但它们有getconf

编者按:虽然getconf实用程序是由posix授权的,但是特定的_NPROCESSORS_ONLN_NPROCESSORS_CONF值不是。如前所述,它们既适用于Linux平台,也适用于MacOS;在freebsd/pc-bsd上,必须省略前面的_


前言:

  • 基于/proc/cpuinfo的答案的问题在于,它们解析的信息是为人类消费的,因此缺乏一种为机器解析而设计的稳定格式:输出格式可以在不同的平台和运行时条件下有所不同;在Linux上使用lscpu -p,在MacOS上使用sysctl,可以绕过这个问题。

  • getconf _NPROCESSORS_ONLN/getconf NPROCESSORS_ONLN不区分逻辑和物理CPU。

这是一个sh的(posix兼容)代码片段,它在Linux和MacOS上工作,用于确定联机逻辑或物理CPU的数量;有关详细信息,请参阅注释。

Linux使用lscpu,MacOS使用sysctl

术语说明:CPU是指操作系统所看到的最小的处理单元。非超线程核心每个对应1个CPU,而超线程核心包含超过1个(通常为:2个)逻辑CPU。Linux使用以下分类法,从最小的单元开始:cpu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/sh

# macOS:           Use `sysctl -n hw.*cpu_max`, which returns the values of
#                  interest directly.
#                  CAVEAT: Using the"_max" key suffixes means that the *maximum*
#                          available number of CPUs is reported, whereas the
#                          current power-management mode could make *fewer* CPUs
#                          available; dropping the"_max" suffix would report the
#                          number of *currently* available ones; see [1] below.
#
# Linux:           Parse output from `lscpu -p`, where each output line represents
#                  a distinct (logical) CPU.
#                  Note: Newer versions of `lscpu` support more flexible output
#                        formats, but we stick with the parseable legacy format
#                        generated by `-p` to support older distros, too.
#                        `-p` reports *online* CPUs only - i.e., on hot-pluggable
#                        systems, currently disabled (offline) CPUs are NOT
#                        reported.

# Number of LOGICAL CPUs (includes those reported by hyper-threading cores)
  # Linux: Simply count the number of (non-comment) output lines from `lscpu -p`,
  # which tells us the number of *logical* CPUs.
logicalCpuCount=$([ $(uname) = 'Darwin' ] &&
                       sysctl -n hw.logicalcpu_max ||
                       lscpu -p | egrep -v '^#' | wc -l)

# Number of PHYSICAL CPUs (cores).
  # Linux: The 2nd column contains the core ID, with each core ID having 1 or
  #        - in the case of hyperthreading - more logical CPUs.
  #        Counting the *unique* cores across lines tells us the
  #        number of *physical* CPUs (cores).
physicalCpuCount=$([ $(uname) = 'Darwin' ] &&
                       sysctl -n hw.physicalcpu_max ||
                       lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l)

# Print the values.
cat <<EOF
# of logical CPUs:  $logicalCpuCount
# of physical CPUS: $physicalCpuCount
EOF

[1]MacOS sysctl (3)文件

请注意,除了MacOS之外,BSD派生的系统(例如FreeBSD)只支持sysctlhw.ncpu密钥,这在MacOS上是不赞成的;我不清楚新密钥hw.npu中哪一个对应于:hw.(logical|physical)cpu_[max]

向@teambob提供一点建议,帮助更正物理CPU计数lscpu命令。

注意:lscpu -p输出不包括"book"列(man页提到"books"是分类层次结构中套接字和节点之间的实体)。如果"书"在给定的Linux系统上运行(有人知道何时以及如何运行?),physical cpu count命令可能在report下(这是基于lscpu报告的ID在更高级别实体中是非唯一的假设;例如:来自两个不同套接字的2个不同内核可以具有相同的ID)。

如果将上述代码另存为shell脚本cpus,使用chmod +x cpus使其可执行,并将其放入$PATH的文件夹中,您将看到如下输出:

1
2
3
$ cpus
logical  4
physical 4


lscpu收集CPU架构信息表单/proc/cpinfon,格式为人可读格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# lscpu


Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    1
Core(s) per socket:    4
CPU socket(s):         2
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 15
Stepping:              7
CPU MHz:               1866.669
BogoMIPS:              3732.83
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
NUMA node0 CPU(s):     0-7

另请参阅https://unix.stackexchange.com/questions/468766/understanding-output-of-lscpu。


这对我有用。tail -nX只允许您抓取最后的x行。

1
cat /proc/cpuinfo | awk '/^processor/{print $3}' | tail -1

如果你有超线程,这应该可以用来抓取物理核心的数量。

1
grep"^core id" /proc/cpuinfo | sort -u | wc -l


对于物理核心的总数:

1
grep '^core id' /proc/cpuinfo |sort -u|wc -l

在多个套接字计算机上(或始终如此),将上述结果乘以套接字数:

1
echo $(($(grep"^physical id" /proc/cpuinfo | awk '{print $4}' | sort -un | tail -1)+1))

@mklement0下面使用lscpu有一个很好的答案。我在评论中写了一个更简洁的版本


使用getconf确实是最可移植的方法,但是在bsd和linux to getconf中变量的名称不同,因此您必须测试这两种方法,正如下面的要点所建议的:https://gist.github.com/jjj1bdx/5746298(还包括使用ksh的Solaris修复程序)

我个人使用:

1
$ getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null || echo 1

如果您希望在python中使用它,您可以通过导入OS模块来使用syscall getconf:

1
$ python -c 'import os; print os.sysconf(os.sysconf_names["SC_NPROCESSORS_ONLN"]);'

至于nproc,它是gnu coreutils的一部分,因此默认情况下在bsd中不可用。它在其他一些方法之后也使用sysconf()。


你也可以用Python!要获取物理核心的数量:

1
2
$ python -c"import psutil; print(psutil.cpu_count(logical=False))"
4

要获取多线程核心的数量,请执行以下操作:

1
2
$ python -c"import psutil; print(psutil.cpu_count(logical=True))"
8


针对Linux、MacOS、Windows的跨平台解决方案:

1
CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu || echo"$NUMBER_OF_PROCESSORS")

如果您想这样做,它可以在Linux和OS X上工作,您可以这样做:

1
CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)


您可以使用以下方法之一来确定物理CPU核心的数量。

  • 计算唯一核心ID的数量(大致相当于grep -P '^core id\t' /proc/cpuinfo | sort -u | wc -l)。

    awk '/^core id\t/ {cores[$NF]++} END {print length(cores)}' /proc/cpuinfo

  • 将"每个套接字的内核数"乘以套接字数。

    lscpu | awk '/^Core\(s\) per socket:/ {cores=$NF}; /^Socket\(s\):/ {sockets=$NF}; END{print cores*sockets}'

  • 计算Linux内核使用的唯一逻辑CPU的数量。-p选项生成输出以便于分析,并与早期版本的lscpu兼容。

    lscpu -p | awk -F, '$0 !~ /^#/ {cores[$1]++} END {print length(cores)}'

只是重申一下其他人所说的,有许多相关的属性。

要确定可用处理器的数量:

1
2
getconf _NPROCESSORS_ONLN
grep -cP '^processor\t' /proc/cpuinfo

确定可用的处理单元数量(不一定与核心数量相同)。这是超线程意识。

1
nproc

我不想走得太远,但是您也可以通过getconf _NPROCESSORS_CONF来确定配置的处理器(而不是简单的可用/在线处理器)的数量。要确定CPU的总数(脱机和联机),您需要分析EDOCX1的输出(15)。


下面将给出超线程和非超线程系统上"真实"核心的数量。至少在我所有的测试中都有效。

1
awk -F: '/^physical/ && !ID[$2] { P++; ID[$2]=1 }; /^cpu cores/ { CORES=$2 };  END { print CORES*P }' /proc/cpuinfo


以下是我计算Linux上联机物理内核数量的方法:

1
lscpu --online --parse=Core,Socket | grep --invert-match '^#' | sort --unique | wc --lines

或者简而言之:

1
lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l


我还以为cat /proc/cpuinfo会给我正确的答案,但是最近我发现我的手臂四核皮质A53系统只显示了一个单核。/proc/cpuinfo似乎只显示活动内核,而:

cat /sys/devices/system/cpu/present

是一个更好的衡量标准。你也可以

cat /sys/devices/system/cpu/online

查看哪些核心处于联机状态,以及

cat /sys/devices/system/cpu/offline

查看哪些核心脱机。onlineofflinepresentsysfs条目返回CPU的索引,因此0的返回值仅表示核心0,而1-3的返回值则表示核心1、2和3。

请参阅https://www.kernel.org/doc/documentation/abi/testing/sysfs-devices-system-cpu


1
cat /proc/cpuinfo | grep processor

这很管用。当我尝试第一个答案时,我得到3个CPU作为输出。我知道系统上有4个CPU,所以我刚为处理器做了一个grep,输出如下:

1
2
3
4
5
[root@theservername ~]# cat /proc/cpuinfo | grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3

更快,不用叉子

这与almsost all shell一起工作。

1
2
3
4
5
6
ncore=0
while read line ;do
    ["$line" ] && [ -z"${line%processor*}" ] && ncore=$((ncore+1))
  done </proc/cpuinfo
echo $ncore
4

为了与shell、dash、busybox等保持兼容,我使用了ncore=$((ncore+1)),而不是((ncore++))

抨击版本

1
2
3
4
5
6
ncore=0
while read -a line ;do
    ["$line" ="processor" ] && ((ncore++))
  done </proc/cpuinfo
echo $ncore
4


如果可以使用python,那么numexpr模块就具有以下功能:

1
2
3
4
In [5]: import numexpr as ne

In [6]: ne.detect_number_of_cores()
Out[6]: 8

此外:

1
2
In [7]: ne.ncores
Out[7]: 8

要从命令提示符查询此信息,请使用:

1
2
3
# runs whatever valid Python code given as a string with `-c` option
$ python -c"import numexpr as ne; print(ne.ncores)"
8

或者只是可以从multiprocessing.cpu_count()函数中获取此信息

1
$ python -c"import multiprocessing; print(multiprocessing.cpu_count())"

或者更简单地使用os.cpu_count()

1
$ python -c"import os; print(os.cpu_count())"


如果你只想计算物理核心,这个命令就为我做了。

1
lscpu -e | tail -n +2 | tr -s"" | cut -d"" -f 4 | sort | uniq | wc -w

非常基本,但似乎计算实际物理内核,忽略逻辑计数


如果"core id"不可用(如树莓),则使用awk对每个"physical id"方法计算"core id",并返回"processor"计数。

1
echo $(awk '{ if ($0~/^physical id/) { p=$NF }; if ($0~/^core id/) { cores[p$NF]=p$NF }; if ($0~/processor/) { cpu++ } } END { for (key in cores) { n++ } } END { if (n) {print n} else {print cpu} }' /proc/cpuinfo)

使用下面的查询获取核心详细信息

1
2
[oracle@orahost](TESTDB)$ grep -c ^processor /proc/cpuinfo
8

1
 dmidecode  | grep -i cpu | grep Version

给我

Version: Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz

Version: Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz

这是正确的套接字计数-查找E5-2667时,会告诉我每个套接字都有8 cores,因此乘以16 cores,最后在2 sockets上结束。

如果lscpu给我的是20 CPUs——这完全不正确——不知道为什么。(同样适用于cat /proc/cpu—最后是20


不是我的网页,而是来自http://www.ixbrian.com/blog/的命令?P=64&;cm_mc_uid=89402252817914508279022&cm_mc_sid_50200000=1450827902在CentOS上非常适合我。即使启用了超线程,它也会显示实际的CPU。

cat /proc/cpuinfo | egrep"core id|physical id" | tr -d"
" | sed s/physical/\
physical/g | grep -v ^$ | sort | uniq | wc -l


python 3还提供了一些简单的方法来获得它:

1
$ python3 -c"import os; print(os.cpu_count());"

1
$ python3 -c"import multiprocessing; print(multiprocessing.cpu_count())"