0

If you have a test.sh containing

make -j$(nproc)

How could you temporarily adjust nproc, along the lines of nproc=1 ./test.sh?

2
  • Why not change test.sh so that the number of processors is passed in the first parameter, and the make line becomes make -j$1? You can default to the current script action by preceding with [ $# == 0 ] && set $(nproc).
    – AFH
    May 30, 2019 at 11:42
  • Yeah really looking for a non-intrusive way though.
    – Trass3r
    May 30, 2019 at 11:52

2 Answers 2

3

Create a wrapper that prints $nproc:

#!/bin/sh
[ -z "$nproc" ] && exec /usr/bin/nproc "$@"
printf '%s\n' "$nproc"

Name it nproc, make it executable (chmod +x nproc) and place it in your /special/directory for custom wrappers. Now you have two options:

  1. On demand:

    PATH="/special/directory:$PATH" nproc=1 ./test.sh
    
  2. Permanent. Modify your PATH so /special/directory is always there as the first entry. Then you can just

    nproc=1 ./test.sh
    

Notes:

  • If the script alters (resets, sanitizes) its PATH, the solution may not work.
  • If the variable is empty or not set, the wrapper uses the real nproc (by its full path to avoid calling itself recursively). This way nproc will behave exactly as before, unless you set the variable to any non-empty value.
  • In your example $(nproc) is not quoted. This means you can inject additional options via the variable (e.g. nproc="2 -i", the wrapper will print this string, in the script it will be split into two words and -i will be passed to make). You may

    • take advantage of this and use the variable to actually inject options (hacky, not recommended);
    • always make sure the variable is sane;
    • implement some logic into the wrapper, so its output is less likely to be split; example:

      set -- $nproc
      printf '%s\n' "$1"
      # word splitting done in the wrapper, only the first word is printed
      
    • (proper solution) fix the script:

      make -j"$(nproc)"
      # if the wrapper prints unexpected string, make will comply
      
2
1

If test.sh is a bash script, another way could be to export a function named nproc:

bash-5.0$ cat foo.sh
#! /bin/bash

echo make -j $(nproc)
bash-5.0$ ./foo.sh
make -j 8

Creating and exporting a function:

bash-5.0$ nproc() { echo function 10; }
bash-5.0$ (export -f nproc; ./foo.sh)
make -j function 10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .