Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portable way to find the number of processors/CPU's in a shell script?

Tags:

shell

unix

sh

Since it's common to write shell scripts which pass the number of jobs to a command, I'm interested to know what a good, portable way is to get the number of processors on mainstream * Unix systems.

Something like this but not depending on Python.


* By mainstream, I mean that will work on popular Unix system used in production today (Linux/BSD's/Darwin? But the more portable the better).

like image 951
ideasman42 Avatar asked Jul 19 '17 04:07

ideasman42


People also ask

What command would you use to count the number of logical CPUs?

You can use the lscpu command or nproc command to display the number of processing units available to the current process, which may be less than the number of online processors.

How do you check for number of CPUs present on the OS?

The lscpu command displays information about the CPU architecture, which is collected from the sysfs and the /proc/cpuinfo file. The information includes, number of CPUs, threads, cores, sockets, NUMA nodes, CPU caches, CPU family and model, which print infomration in human readable format.

How many CPUs do I have Ubuntu?

Method 1: Finding the number of cores in Ubuntu using the “lscpu” command. The 'lscpu' command provides all the information related to the CPU Architecture. The above command will show all the information related to the CPU, like CPU Architecture, the number of CPU cores, threads per core, etc.


2 Answers

Here is a fairly portable function to get the number of processors that works in sh, bash and compatible shells:

  • Uses nproc on Linux.
  • Use getconf as a fallback, it's and part of coreutils.
  • Tested to work on:
  • Linux
  • Darwin (macOS)
  • FreeBSD, NetBSD, OpenBSD

... probably others, feel free to test :)

Feel free to suggest additions:

#!/bin/sh
portable_nproc() {
    OS="$(uname -s)"
    if [ "$OS" = "Linux" ]; then
        NPROCS="$(nproc --all)"
    elif [ "$OS" = "Darwin" ] || \
         [ "$(echo "$OS" | grep -q BSD)" = "BSD" ]; then
        NPROCS="$(sysctl -n hw.ncpu)"
    else
        NPROCS="$(getconf _NPROCESSORS_ONLN)"  # glibc/coreutils fallback
    fi
    echo "$NPROCS"
}

# test
portable_nproc

A more terse command that covers many systems is to check getconf for glibc, then sysctl for BSD family of Unixes: eg:

getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu

I have a slight preference for checking each platform since it allows others to be added more easily, but in practice the single line works in many cases.

like image 77
ideasman42 Avatar answered Sep 23 '22 06:09

ideasman42


I'll throw in my one-liner heavily influenced by ideasman42's answer above:

nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null
like image 26
stefanct Avatar answered Sep 24 '22 06:09

stefanct