単純なラッパースクリプトは100のbashプロセスを生成します。

単純なラッパースクリプトは100のbashプロセスを生成します。

このGCC multilibラッパーを設定しました。

#file: gcc
#!/usr/bin/env bash
gcc -m32 "$@"

これは本質的に64ビットmultilib gccをラップし、multilibではなく32ビットgccで動作します。 binutilsのようなものを構築すると、何百ものbashプロセスが作成され、さらにfork失敗することがあります。この問題をどのように解決できますか?

答え1

スクリプト名を gcc として指定し、パスに入れてから再帰的に呼び出すようです。スクリプトに別の名前を付けるか、実際に使用したいgcc実行可能ファイルへの明示的なパスを使用してください。

答え2

ケビンすでに重要な問題を発見しました。つまり、自分のスクリプトを再帰的に呼び出すということです。

これを防ぐ簡単な方法は、絶対パスを使用してラップされたプログラムを呼び出すことです。より良いアプローチは、$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 "$@"

いくつかの追加のヒント:

  • exec実際のコマンドを開始した後にシェルが不要になった場合は、このコマンドを使用してください。一部のシェルは最適化のためにこれを行うことを知っていますが、すべてではありません。
  • bash機能を使用しない限り、#!/bin/sh代わりに使用してください。#!/bin/bash多くのシステムでは、shこれはより少ない機能を備えたより簡潔で高速なシェルですが、bashラッパースクリプトにはこれらの高度な機能はほとんど必要ありません。

関連情報