生成 100 个 bash 进程的简单包装脚本

rub*_*nvb 2 linux bash shell-script

我设置了这种 GCC multilib 包装器:

#file: gcc
#!/usr/bin/env bash
gcc -m32 "$@"
Run Code Online (Sandbox Code Playgroud)

它本质上只是包装了一个 64 位 multilib gcc 以充当非 multilib 32 位 gcc。当我构建一些东西(例如 binutils)时,这会产生数百个bash进程,直到甚至fork失败。我该如何解决这个问题?

Kev*_*vin 8

看来您将脚本命名为 gcc,将其放在路径中,然后递归调用它。要么为您的脚本命名不同的名称,要么使用您实际想要使用的 gcc 可执行文件的显式路径。


Gil*_*il' 5

Kevin已经找到了核心问题,即您递归调用自己的脚本。

避免这种情况的一种简单方法是使用绝对路径调用包装的程序。一种更好的方法是$PATH手动检查并跳过您自己的脚本(以 标识$0)。

find_command () {
  script_dir={1%/*}; command_name=${1##*/}
  real_command=
  IFS=':'; set +f
  for d in $PATH; do
    if [ "$d" = "$script_dir" ]; then continue; fi
    if [ -x "$d/$command_name" ]; then real_command="$d/command_name" break; fi
  done
  set -f; unset IFS
  [ -n "$real_command" ]
}
find_command "$0" || {
  echo 1>&2 "$0: cannot find underlying command in \$PATH=$PATH"
  exit 2
}
exec "$0" -m32 "$@"
Run Code Online (Sandbox Code Playgroud)

一些额外的提示:

  • exec如果您在启动真正的命令后不再需要 shell,请使用。一些 shell 知道这样做是为了优化,但不是全部。
  • 除非您使用 bash 功能,否则请使用#!/bin/sh而不是#!/bin/bash。在许多系统上,它sh是一个比 更精简、更快的 shell bash,具有更少的功能,但包装脚本很少需要这些高级功能。