Search code examples
shellunixsh

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


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).


Solution

  • 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.