How to get CPU serial under Linux without root permissions - linux

How can I get CPU serial number under Linux (Ubuntu) without root permissions?
I tried cpuid command, it works without root permissions, but appears to return all zeros (I believe because something needs to be changed in BIOS).
Can you please suggest me another way to retrieve CPU serial from a program without root permissions and without having to modify BIOS?

Root permissions required. The answer is dmidecode.
If you need CPU ID:
dmidecode | grep -w ID | sed "s/^.ID\: //g"
This will get CPU ID, remove 'ID: ' from output
If you need to receive a computer ID:
dmidecode | grep -w UUID | sed "s/^.UUID\: //g"
If you wish to get kernel uuid without root permissions, then:
dmesg | grep UUID | grep "Kernel" | sed "s/.*UUID=//g" | sed "s/\ ro\ quiet.*//g"
It's because of recent comment. Happened long time ago, so can't explain now why these ID were taken as machine identifier. Got actual Processor ID fromn Processor Information section. Extracted on Debian OS.
pr=0; dmidecode | while read line; do [ "$line" == "Processor Information" ] && pr=1; [ $pr -eq 0 ] && continue; [ -n "$(echo $line | grep '^ID')" ] && echo $line | awk -F"ID: " '{print $2}' && break; done

Processor serial numbers were basically only in Pentium III processors. Intel removed it from later models due to the privacy concerns that were raised. As such, unless you're on a PIII AND your BIOS settings let you read the serial number, all you'll get are 0's.

Tie the license to the inode numbers that its executable files get when they are installed into the user's filesystem. If they are moved somewhere else, they will change.
The downside is that the numbers may not be preserved if the program has to be restored from a backup.
I've done this sort of thing before. You have to be very generous about letting genuine users activate the license on changing hardware.

cpuid returns the same serial number for me regardless of my use of sudo:
% cpuid | grep serial
Processor serial: 0002-0652-0000-0000-0000-0000
% sudo cpuid | grep serial
Processor serial: 0002-0652-0000-0000-0000-0000
Unless there's some other serial number that you're referring to...?

As suggested when this question was asked before, if you are trying to use this for licensing (since you used the licensing tag) you may want to try the MAC address:
CPU serial number

CPUs has no serial number; maybe that you want DMI basic info without root privilege (This will only show you a persistent id of your motherboard manufacturer and model, but no serial number):
dmesg | grep -i dmi: | cut -d ":" -f 2-
Otherwise you could "tell" dmidecode to run from unprivileged user:
sudo chmod +s /usr/sbin/dmidecode
Then you could run for instance:
dmidecode -s system-serial-number
In most cases "system-serial-number" is like either "chassis-serial-number" or "baseboard-serial-number". Remember that not all distros have this program installed, for instance, Debian based systems have a package named after it.
Otherwise you can find a unique and persistent, thro' installs, system ID via your system's disk; to do that you may run the following:
mount | grep "on / type" | awk '{print $1}'
The former will give you device's path where your system is mounted (for my OS it returned /dev/sda7), and then you can find an ID for it with the following:
find /dev/disk/by-id/ -lname "*sda" ! -name "wwn*"
So the complete command to find a unique ID from your system's hard disk could be:
find /dev/disk/by-id/ -lname "*`mount | grep " / " | awk '{print $1}' | cut -b 6-8`" ! -name "wwn*" -printf "%f\n"
I hope this may fit your needs or someone else's in here. Command cut -b 6-8 may not be portable, because I'm assuming block devices names to be three chars long; moreover, /dev/disk/by-id/ path is only filled by UDEV managed systems and not all Linux distros use it, but I ensure you the former will work in Ubuntu.

Have you checked dmesg? Its in /bin

Related

How to trace the list of PIDs running on a specific core?

I'm trying to run a program on a dedicated core in Linux. (I know Jailhouse is a good way to do so, but I have to use off-the-shelf Linux. :-( )
Other processes, such as interrupt handlers, kernel threads, service progresses, may also run on the dedicated core occasionally. I want to disable as many such processes as possible. To do that, I need first pin down the list of processes that may run on the dedicated core.
My question is:
Is there any existing tools that I can use to trace the list of PIDs or processes that run on a specific core over a time interval?
Thank you very much for your time and help in this question!
TL;DR Dirty hacky solution.
DISCLAIMER: At some point stops working "column: line too long" :-/
Copy this to: core-pids.sh
#!/bin/bash
TARGET_CPU=0
touch lastPIDs
touch CPU_PIDs
while true; do
ps ax -o cpuid,pid | tail -n +2 | sort | xargs -n 2 | grep -E "^$TARGET_CPU" | awk '{print $2}' > lastPIDs
for i in {1..100}; do printf "#\n" >> lastPIDs; done
cp CPU_PIDs aux
paste lastPIDs aux > CPU_PIDs
column -t CPU_PIDs > CPU_PIDs.humanfriendly.tsv
sleep 1
done
Then
chmod +x core-pids.sh
./core-pids.sh
Then open CPU_PIDs.humanfriendly.tsv with your favorite editor, and ¡inspect!
The key is in the "ps -o cpuid,pid" bit, for more detailed info, please comment. :D
Explanation
Infinite loop with
ps -o cpuid,pid | tail -n +2 | sort | xargs -n 2 | grep -E "^$TARGET_CPU" | awk '{print $2}' > lastPIDs
ps ax -o cpuid,pid
Show pid's associated to CPU
tail -n +2
remove headers
sort
sort by cpuid
xargs -n 2
remove white spaces at begging
grep -E "^$TARGET_CPU"
filter by CPU id
awk '{print $2}'
get pid column
> lastPIDs
output to file those las pid's for the target CPU id
for i in {1..10}; do printf "#\n" >> lastPIDs; done
hack for pretty .tsv print with the "columns -t" command
cp CPU_PIDs aux
CPU_PIDs holds the whole timeline, we copy it to aux file to allow the next command to use it as input and output
paste lastPIDs aux > CPU_PIDs
Append lastPIDs columns to the whole timeline file CPU_PIDs
column -t CPU_PIDs > CPU_PIDs.humanfriendly.tsv
pretty print whole timeline CPU_PIDs file
Attribution
stackoverflow answer to: ps utility in linux (procps), how to check which CPU is used
by Mikel
stackoverflow answer to: Echo newline in Bash prints literal \n
by sth
stackoverflow answer to: shell variable in a grep regex
by David W.
superuser answer to: Aligning columns in output from a UNIX command
Janne Pikkarainen
nixCraft article: HowTo: Unix For Loop 1 to 100 Numbers
The best way to obtain what you want is to operate as follows:
Use the isolcpus= Linux kernel boot parameter to "free" one core from the Linux scheduler
Disable the irqbalance daemon (in case it is executing)
Set the IRQs affinities to the other cores by manually writing the CPU mask on /proc/irq/<irq_number>/smp_affinity
Finally, run your program setting the affinity to the dedicated core through the taskset command.
In this case, such core will only execute your program. For checking, you can type ps -eLF and look at the PSR column (which specifies the CPU number).
Not a direct answer to the question, but I am usually using perf context-switches software event to identify the perturbation of the system or other processes on my benchmarks

Is it possible to find which process is using OPENSSL in linux?

Suppose, one process is running and accessing OPENSSL shared library to perform some operation. Is there any way to find the pid of this process ?
Is there any way to find on which core this process is running ?
If possible, does it require any special privilege like sudo etc?
OS- Debian/Ubuntu
Depending on what exactly you want, something like this might do:
lsof | grep /usr/lib64/libcrypto.so | awk '{print $1, $2}' | sort -u
This essentially:
uses lsof to list all open files on the system
searches for the OpenSSL library path (which also catches versioned names like libcrypto.so.1.0)
selects the process name and PID
removes any duplicate entries
Note that this will also output processes using previous instances of the shared library file that were e.g. updated to a new version and then deleted. It also has the minor issue of outputting duplicates when a process has multiple threads with different names.
And yes, this may indeed require elevated privileges, depending on the permissions on your /proc directory.
If you really do need the processor core(s), you could try something like this (credit to dkaz):
lsof | grep /usr/lib64/libcrypto.so | awk '{print $2}' |
xargs -r ps -L --no-headers -o pid,psr,comm -p | sort -u
Adding the lwp variable to the ps command would also show the thread IDs:
lsof | grep /usr/lib64/libcrypto.so | awk '{print $2}' |
xargs -r ps -L --no-headers -o pid,lwp,psr,comm -p
PS: The what-core-are-the-users-of-this-library-on requirement still sounds a bit unusual. It might be more useful if you mentioned the problem that you are trying to solve in broader terms.
thkala is almost right. The problem is that the answer is half, since it doesn't give the core.
I would run that:
$ lsof | grep /usr/lib64/libcrypto.so |awk '{print $2}' | xargs ps -o pid,psr,comm -p

how to write a bash script that would get minor and major device numbers of /dev/random

I am trying to run a program in a chrooted environment, and it needs /dev/random as a resource.
Manually I can do ls -l on it and then create the file again with mknod c xx yy, but I need to make it automatic and I don't think these version numbers are constant from a linux version to another so that is why I have the following question :
How could I write a bash script that would extract the minor and major numbers of /dev/random and use it with mknod? I can use ls -l but I don't know how to extract a substring of it...
The exact return of ls -l /dev/random is :
crw-rw-rw- 1 root root MINOR, MAJOR mars 30 19:15 /dev/random
and the two numbers I want to extract are MINOR and MAJOR. However if there is an easier way to create the node without ls and mknod I would appreciate it.
You can get the major and minor device numbers with stat:
MINOR=`stat -c %T /dev/random`
MAJOR=`stat -c %t /dev/random`
You can then create a device node with:
mknod mydevice c "$MAJOR" "$MINOR"
Another approach (which doesn't require the parsing of device numbers) is to use tar to create an archive with the details of the device files in:
cd /dev
tar cf /somewhere/devicefiles.tar random null [any other needed devices]
then
cd /somewhere/chroot-location
tar xf /somewhere/devicefiles.tar
This latter method has the advantage that it doesn't rely on the -c option to stat, which is a GNU extension.
A minor improvement to efficiency would be to do only one call (and to use lower-case variable names, as is conventional for all variables other than builtins and environment variables in shell):
read minor major < <(stat -c '%T %t' /dev/random)
On a GNU system, by the way, I'd suggest using cp -a to copy your explicitly whitelisted device files into the chroot during setup:
cp -a /dev/random /your/chroot/dev/random
Try this.
MAJOR=ls -l /dev/random | awk '{ print $5}'
MINOR=ls -l /dev/random | awk '{ print $6}'

How to get grep -m1 to work in OSX

I have a script which I used perfectly fine in Linux, but now that I've switched over to Mac, the script still runs but has slightly different behavior.
This is a script for tallying student attendance at departmental functions. We use a portable barcode scanner to scan their ID's, and then save all scans in one csv file per date.
I used grep -m1 $ID csvfolder/* | wc -l in the past to get a count of how many files their ID shows up in. The -m1 is necessary to make sure they don't get "extra credit" for repeatedly scanning in at the same event.
However, when I use this same command in Mac, it exits grep when it has found the first match in the first file. So if the student shows up in 4 files, wc -l still returns 1
How can I (without installing the GNU versions) emulate this feature?
I don't have Mac OS X handy to test it with, but the following is Posix-standard afaik:
grep -l "$ID" csvfolder/* | wc -l
The grep will print the name of each file which contains a match. That should work with Gnu grep equally.
You could alternatively use awk for this task:
awk -v id="$ID" '$0 ~ id{print 1; exit}' csvfolder/* | wc -l

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

I have this script, but I do not know how to get the last element in the printout:
cat /proc/cpuinfo | awk '/^processor/{print $3}'
The last element should be the number of CPUs, minus 1.
grep -c ^processor /proc/cpuinfo
will count the number of lines starting with "processor" in /proc/cpuinfo
For systems with hyper-threading, you can use
grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}'
which should return (for example) 8 (whereas the command above would return 16)
Processing the contents of /proc/cpuinfo is needlessly baroque. Use nproc which is part of coreutils, so it should be available on most Linux installs.
Command nproc prints the number of processing units available to the current process, which may be less than the number of online processors.
To find the number of all installed cores/processors use nproc --all
On my 8-core machine:
$ nproc --all
8
The most portable solution I have found is the getconf command:
getconf _NPROCESSORS_ONLN
This works on both Linux and Mac OS X. Another benefit of this over some of the other approaches is that getconf has been around for a long time. Some of the older Linux machines I have to do development on don't have the nproc or lscpu commands available, but they have getconf.
Editor's note: While the getconf utility is POSIX-mandated, the specific _NPROCESSORS_ONLN and _NPROCESSORS_CONF values are not.
That said, as stated, they work on Linux platforms as well as on macOS; on FreeBSD/PC-BSD, you must omit the leading _.
Preface:
The problem with the /proc/cpuinfo-based answers is that they parse information that was meant for human consumption and thus lacks a stable format designed for machine parsing: the output format can differ across platforms and runtime conditions; using lscpu -p on Linux (and sysctl on macOS) bypasses that problem.
getconf _NPROCESSORS_ONLN / getconf NPROCESSORS_ONLN doesn't distinguish between logical and physical CPUs.
Here's a sh (POSIX-compliant) snippet that works on Linux and macOS for determining the number of - online - logical or physical CPUs; see the comments for details.
Uses lscpu for Linux, and sysctl for macOS.
Terminology note: CPU refers to the smallest processing unit as seen by the OS. Non-hyper-threading cores each correspond to 1 CPU, whereas hyper-threading cores contain more than 1 (typically: 2) - logical - CPU.
Linux uses the following taxonomy[1], starting with the smallest unit:
CPU < core < socket < book < node
with each level comprising 1 or more instances of the next lower level.
#!/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) documentation
Note that BSD-derived systems other than macOS - e.g., FreeBSD - only support the hw.ncpu key for sysctl, which are deprecated on macOS; I'm unclear on which of the new keys hw.npu corresponds to: hw.(logical|physical)cpu_[max].
Tip of the hat to #teambob for helping to correct the physical-CPU-count lscpu command.
Caveat: lscpu -p output does NOT include a "book" column (the man page mentions "books" as an entity between socket and node in the taxonomic hierarchy). If "books" are in play on a given Linux system (does anybody know when and how?), the physical-CPU-count command may under-report (this is based on the assumption that lscpu reports IDs that are non-unique across higher-level entities; e.g.: 2 different cores from 2 different sockets could have the same ID).
If you save the code above as, say, shell script cpus, make it executable with chmod +x cpus and place it in folder in your $PATH, you'll see output such as the following:
$ cpus
logical 4
physical 4
[1] Xaekai sheds light on what a book is: "a book is a module that houses a circuit board with CPU sockets, RAM sockets, IO connections along the edge, and a hook for cooling system integration. They are used in IBM mainframes. Further info: http://ewh.ieee.org/soc/cpmt/presentations/cpmt0810a.pdf"
lscpu gathers CPU architecture information form /proc/cpuinfon in human-read-able format:
# 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
See also https://unix.stackexchange.com/questions/468766/understanding-output-of-lscpu.
You can also use Python! To get the number of physical cores:
$ python -c "import psutil; print(psutil.cpu_count(logical=False))"
4
To get the number of hyperthreaded cores:
$ python -c "import psutil; print(psutil.cpu_count(logical=True))"
8
Here's the way I use for counting the number of physical cores that are online on Linux:
lscpu --online --parse=Core,Socket | grep --invert-match '^#' | sort --unique | wc --lines
or in short:
lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
Example (1 socket):
> lscpu
...
CPU(s): 28
Thread(s) per core: 2
Core(s) per socket: 14
Socket(s): 1
....
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
14
Example (2 sockets):
> lscpu
...
CPU(s): 56
Thread(s) per core: 2
Core(s) per socket: 14
Socket(s): 2
...
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
28
Example (4 sockets):
> lscpu
...
CPU(s): 64
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 4
...
> lscpu -b -p=Core,Socket | grep -v '^#' | sort -u | wc -l
32
For the total number of physical cores:
grep '^core id' /proc/cpuinfo |sort -u|wc -l
On multiple-socket machines (or always), multiply the above result by the number of sockets:
echo $(($(grep "^physical id" /proc/cpuinfo | awk '{print $4}' | sort -un | tail -1)+1))
#mklement0 has quite a nice answer below using lscpu. I have written a more succinct version in the comments
Using getconf is indeed the most portable way, however the variable has different names in BSD and Linux to getconf, so you have to test both, as this gist suggests:
https://gist.github.com/jj1bdx/5746298
(also includes a Solaris fix using ksh)
I personally use:
$ getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null || echo 1
And if you want this in python you can just use the syscall getconf uses by importing the os module:
$ python -c 'import os; print os.sysconf(os.sysconf_names["SC_NPROCESSORS_ONLN"]);'
As for nproc, it's part of GNU Coreutils, so not available in BSD by default. It uses sysconf() as well after some other methods.
Crossplatform solution for Linux, MacOS, Windows:
CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu || echo "$NUMBER_OF_PROCESSORS")
If you want to do this so it works on linux and OS X, you can do:
CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
It is very simple. Just use this command:
lscpu
You can use one of the following methods to determine the number of physical CPU cores.
Count the number of unique core ids (roughly equivalent to grep -P '^core id\t' /proc/cpuinfo | sort -u | wc -l).
awk '/^core id\t/ {cores[$NF]++} END {print length(cores)}' /proc/cpuinfo
Multiply the number of 'cores per socket' by the number of sockets.
lscpu | awk '/^Core\(s\) per socket:/ {cores=$NF}; /^Socket\(s\):/ {sockets=$NF}; END{print cores*sockets}'
Count the number of unique logical CPU's as used by the Linux kernel. The -p option generates output for easy parsing and is compatible with earlier versions of lscpu.
lscpu -p | awk -F, '$0 !~ /^#/ {cores[$1]++} END {print length(cores)}'
Just to reiterate what others have said, there are a number of related properties.
To determine the number of processors available:
getconf _NPROCESSORS_ONLN
grep -cP '^processor\t' /proc/cpuinfo
To determine the number of processing units available (not necessarily the same as the number of cores). This is hyperthreading-aware.
nproc
I don't want to go too far down the rabbit-hole, but you can also determine the number of configured processors (as opposed to simply available/online processors) via getconf _NPROCESSORS_CONF. To determine total number of CPU's (offline and online) you'd want to parse the output of lscpu -ap.
The above answers are applicable to most situations, but if you are in a docker container environment and your container is limited by CpusetCpus, then you can't actually get the real cpu cores through the above method.
In this case, you need do this to get the real cpu cores:
grep -c 'cpu[0-9]' /proc/stat
I also thought cat /proc/cpuinfo would give me the correct answer, however I recently saw that my ARM quad core Cortex A53 system only showed a single core. It seems that /proc/cpuinfo only shows the active cores, whereas:
cat /sys/devices/system/cpu/present
is a better measure of what's there. You can also
cat /sys/devices/system/cpu/online
to see which cores are online, and
cat /sys/devices/system/cpu/offline
to see which cores are offline. The online, offline, and present sysfs entries return the index of the CPUS, so a return value of 0 just means core 0, whereas a return value of 1-3 means cores 1,2, and 3.
See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu
In case anybody was wondering, here is what the Python psutil.cpu_count(logical=False) call does on Linux in equivalent shell script:
cat /sys/devices/system/cpu/cpu[0-9]*/topology/core_cpus_list | sort -u | wc -l
And here’s a slightly longer version that falls back to the information from the deprecated thread_siblings_list file if core_cpus_list isn’t available (psutil has this fallback):
cat /sys/devices/system/cpu/cpu[0-9]*/topology/{core_cpus_list,thread_siblings_list} | sort -u | wc -l
The following should give you the number of "real" cores on both a hyperthreaded and non-hyperthreaded system. At least it worked in all my tests.
awk -F: '/^physical/ && !ID[$2] { P++; ID[$2]=1 }; /^cpu cores/ { CORES=$2 }; END { print CORES*P }' /proc/cpuinfo
Not my web page, but this command from http://www.ixbrian.com/blog/?p=64&cm_mc_uid=89402252817914508279022&cm_mc_sid_50200000=1450827902 works nicely for me on centos. It will show actual cpus even when hyperthreading is enabled.
cat /proc/cpuinfo | egrep "core id|physical id" | tr -d "\n" | sed s/physical/\\nphysical/g | grep -v ^$ | sort | uniq | wc -l
Count "core id" per "physical id" method using awk with fall-back on "processor" count if "core id" are not available (like raspberry)
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)
cat /proc/cpuinfo | grep processor
This worked fine. When I tried the first answer I got 3 CPU's as the output. I know that I have 4 CPUs on the system so I just did a grep for processor and the output looked like this:
[root#theservername ~]# cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
processor : 2
processor : 3
If it's okay that you can use Python, then numexpr module has a function for this:
In [5]: import numexpr as ne
In [6]: ne.detect_number_of_cores()
Out[6]: 8
also this:
In [7]: ne.ncores
Out[7]: 8
To query this information from the command prompt use:
# runs whatever valid Python code given as a string with `-c` option
$ python -c "import numexpr as ne; print(ne.ncores)"
8
Or simply it is possible to get this info from multiprocessing.cpu_count() function
$ python -c "import multiprocessing; print(multiprocessing.cpu_count())"
Or even more simply use os.cpu_count()
$ python -c "import os; print(os.cpu_count())"
Use below query to get core details
[oracle#orahost](TESTDB)$ grep -c ^processor /proc/cpuinfo
8
If you just want to count physical cores, this command did it for me.
lscpu -e | tail -n +2 | tr -s " " | cut -d " " -f 4 | sort | uniq | wc -w
Pretty basic, but seems to count actual physical cores, ignoring the logical count
Fravadona's answer is awesome and correct, but it requires the presence of lscpu. Since it is not present on the system where I need the number of physical cores, I tried to come up with one that relies only on proc/cpuinfo
cat /proc/cpuinfo | grep -B2 'core id' | sed 's/siblings.*/'/ | tr -d '[:space:]' | sed 's/--/\n/'g | sort -u | wc -l
It works perfectly, but unfortunately it isn't as robust as Fravadona's, since it will break if
the name or order of the fields inside /proc/cpuinfo changes
grep replaces the line separator it inserts (currently --) by some other string.
BUT, other than that, it works flawlessly :)
Here is a quick explanation of everything that is happening
grep -B2 'core id'
get only the lines we are interested (i.e "core id" and the 2 preceding lines)
sed 's/siblings.*/'/
remove the "siblings..." line
tr -d '[:space:]'
replace spacing chars
sed 's/--/\n/'g
replace the '--' char, which was inserted by grep, by a line break
sort -u
group by "physical id,core id"
wc -l
count the number of lines
Being a total noobie, I was very pleased with myself when this worked. I never thought I would be able to join the required lines together to group by "physical id" and "core id". It is kind of hacky, but works.
If any guru knows a way to simplify this mess, please let me know.
Most answers in this thread pertain to logical cores.
Using BaSH on Ubuntu 18.x, I find this works well to determine number of physical CPUs:
numcpu="$(lscpu | grep -i 'socket(s)' | awk '{print $(2)}')"
It should work on most Linux distros.
One more answer among the numerous previous ones. It is possible to use the cgroups when they are available. The cpuset sub-system provides the list of actives cpus. This can be listed in the top most cgroup of the hierarchy in /sys/fs/cgroup. For example:
$ cat /sys/fs/cgroup/cpuset/cpuset.effective_cpus
0-3
Then, a parsing of the latter would be necessary to get the number of active CPUs. The content of this file is a comma separated list of CPU sets.
Here is an example using tr to break the list into single expressions and using sed to translate the intervals into arithmetic operations passed to expr:
#!/bin/sh
# For test purposes, the CPU sets are passed as parameters
#cpuset=`cat /sys/fs/cgroup/cpuset/cpuset.effective_cpus`
cpuset=$1
ncpu=0
for e in `echo $cpuset | tr ',' ' '`
do
case $e in
# CPU interval ==> Make an arithmetic operation
*-*) op=`echo $e | sed -E 's/([0-9]+)-([0-9]+)/\2 - \1 + 1/'`;;
# Single CPU number
*) op=1;;
esac
ncpu=`expr $ncpu + $op`
done
echo $ncpu
Here are some examples of executions with several flavors of CPU sets:
$ for cpuset in "0" "0,3" "0-3" "0-3,67" "0-3,67,70-75" "0,1-3,67,70-75"
> do
> ncpu.sh $cpuset
> done
1
2
4
5
11
11
dmidecode | grep -i cpu | grep Version
gives me
Version: Intel(R) Xeon(R) CPU E5-2667 v4 # 3.20GHz
Version: Intel(R) Xeon(R) CPU E5-2667 v4 # 3.20GHz
Which is correct socket count - looking up the E5-2667 tells me each socket has 8 cores, so multiply and end up with 16 cores across 2 sockets.
Where lscpu give me 20 CPUs - which is totally incorrect - not sure why. (same goes for cat /proc/cpu - ends up with 20.
Python 3 also provide a few simple ways to get it:
$ python3 -c "import os; print(os.cpu_count());"
4
$ python3 -c "import multiprocessing; print(multiprocessing.cpu_count())"
4
Summary:
to get physical CPUs do this:
grep 'core id' /proc/cpuinfo | sort -u
to get physical and logical CPUs do this:
grep -c ^processor /proc/cpuinfo
/proc << this is the golden source of any info you need about processes and
/proc/cpuinfo << is the golden source of any CPU information.
Quicker, without fork
This works with almost all shell.
ncore=0
while read line ;do
[ "$line" ] && [ -z "${line%processor*}" ] && ncore=$((ncore+1))
done </proc/cpuinfo
echo $ncore
4
In order to stay compatible with shell, dash, busybox and others, I've used ncore=$((ncore+1)) instead of ((ncore++)).
bash version
ncore=0
while read -a line ;do
[ "$line" = "processor" ] && ((ncore++))
done </proc/cpuinfo
echo $ncore
4

Resources