Como definir o nproc para um único comando?

Como definir o nproc para um único comando?

Se você tiver um test.shcontendo

make -j$(nproc)

Como você poderia ajustar temporariamente o nproc, nos moldes de nproc=1 ./test.sh?

Responder1

Crie um wrapper que imprima $nproc:

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

Nomeie-o nproc, torne-o executável ( chmod +x nproc) e coloque-o em seus /special/directorywrappers personalizados. Agora você tem duas opções:

  1. Sob demanda:

    PATH="/special/directory:$PATH" nproc=1 ./test.sh
    
  2. Permanente. Modifique o seu PATHpara que /special/directoryesteja sempre lá como a primeira entrada. Então você pode simplesmente

    nproc=1 ./test.sh
    

Notas:

  • Se o script alterar (redefinir, higienizar) seu arquivo PATH, a solução poderá não funcionar.
  • Se a variável estiver vazia ou não definida, o wrapper usa o real nproc(pelo seu caminho completo para evitar chamar a si mesmo recursivamente). Dessa forma, nproco comportamento será exatamente como antes, a menos que você defina a variável com qualquer valor não vazio.
  • No seu exemplo $(nproc)não é citado. Isso significa que você pode injetar opções adicionais através da variável (por exemplo nproc="2 -i", o wrapper imprimirá esta string, no script ela será dividida em duas palavras e -iserá passada para make). Você pode

    • aproveite isso e use a variável para realmente injetar opções (hackeado, não recomendado);
    • sempre certifique-se de que a variável esteja correta;
    • implementar alguma lógica no wrapper, para que seja menos provável que sua saída seja dividida; exemplo:

      set -- $nproc
      printf '%s\n' "$1"
      # word splitting done in the wrapper, only the first word is printed
      
    • (solução adequada) corrija o script:

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

Responder2

Se test.shfor um script bash, outra maneira seria exportar uma função chamada nproc:

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

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

Criando e exportando uma função:

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

informação relacionada