如何为单个命令设置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. 永久的。修改您的PATHso/special/directory始终作为第一个条目存在。然后您可以

    nproc=1 ./test.sh
    

笔记:

  • 如果脚本改变(重置、清理)其PATH,解决方案可能不起作用。
  • 如果变量为空或未设置,则包装器使用实数nproc(通过其完整路径来避免递归调用自身)。nproc除非您将变量设置为任何非空值,否则这种方式的行为与以前完全相同。
  • 在您的示例中,$(nproc)没有引用。这意味着您可以通过变量注入其他选项(例如nproc="2 -i",包装器将打印此字符串,在脚本中它将被拆分为两个单词并-i传递给make)。您可以

    • 利用这一点并使用变量来实际注入选项(很黑,不推荐);
    • 始终确保变量是合理的;
    • 在包装器中实现一些逻辑,这样它的输出就不太可能被分割;例如:

      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

相关内容