如何為單一命令設定nproc?

如何為單一命令設定nproc?

如果你有一個test.sh包含

make -j$(nproc)

您如何按照以下方式暫時調整 nproc nproc=1 ./test.sh

答案1

建立一個列印的包裝器$nproc

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

為其命名nproc,使其可執行 ( chmod +x nproc) 並將其放入您的/special/directory自訂包裝器中。現在你有兩個選擇:

  1. 一經請求:

    PATH="/special/directory:$PATH" nproc=1 ./test.sh
    
  2. 永恆的。修改你的PATH所以/special/directory總是作為第一個條目。然後你就可以

    nproc=1 ./test.sh
    

筆記:

  • 如果腳本更改(重置、清理)其PATH,則解決方案可能不起作用。
  • 如果變數為空或未設置,則包裝器使用實數nproc(透過其完整路徑以避免遞歸呼叫自身)。這種方式的nproc行為與以前完全相同,除非您將變數設為任何非空值。
  • 在你的例子中$(nproc)沒有引用。這意味著您可以透過變數注入其他選項(例如nproc="2 -i",包裝器將列印此字串,在腳本中它將拆分為兩個單字並-i傳遞給make)。您可以

    • 利用這一點並使用變數來實際注入選項(hacky,不建議);
    • 始終確保變數是正常的;
    • 在包裝器中實現一些邏輯,因此其輸出不太可能被拆分;例子:

      set -- $nproc
      printf '%s\n' "$1"
      # word splitting done in the wrapper, only the first word is printed
      
    • (正確的解決方案)修復腳本:

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

答案2

如果test.sh是 bash 腳本,另一種方法可能是匯出名為 的函數nproc

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

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

建立並導出函數:

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

相關內容