すべてのコマンドを直接実行するのではなく、シェルスクリプトを介してルーティングする方法はありますか?

すべてのコマンドを直接実行するのではなく、シェルスクリプトを介してルーティングする方法はありますか?

私はすべてを実行できるようにしたいので、プログラムを実行するのではなく、実行可能ファイルを引数として使用するシェルスクリプトを実行したいと思います。システム内のすべての実行可能ファイルを個別に選択する必要なしにこれを行うことができれば良いでしょう。

答え1

パスを変更し、すべての実行可能ファイルをここにコピーします。ここで、各実行ファイルはスクリプトの別の名前にすぎません。それは次のとおりです。

$ mkdir ${HOME}/shell
$ OLDPATH=$PATH
$ PATH=${HOME}/shell:$PATH
$ echo $PATH | tr : \\n \
  | while read P; do (mkdir -p $(echo $P | sed s':/::'); ls $P/* ) \
  | while read F; do ln master_script $(echo $F | sed s':/::'); done \
    done

今書いてくださいmaster_script。 PATHから$ {HOME} / shellを削除し、command -v実際のパスにある名前を使用してexec$ @を引数として渡すようにします。

答え2

スクリプトに正確にコマンドを送信する方法はわかりませんが、bashまたはzshでは、各コマンドの前に呼び出されるDEBUGトラップを使用してフックを追加できます。

詳細については、次を参照してください。https://superuser.com/questions/175799/does-bash-have-a-hook-that-is-run-before-executing-a-command

編集:コマンドを停止するには、PATH変数を変更してコマンドを失敗させることができます。たとえば、

preexec() {
  if [ "$1" = "ls" ] ; then echo STOP; SAVEDPATH="$PATH"; export PATH=/DoesNotExist; 
  fi 
}

preexec_invoke_exec () {
  if [ "$SAVEDPATH" != "" ] ; then export PATH="$SAVEDPATH" ; unset SAVEDPATH ; fi;
  [ -n "$COMP_LINE" ] && return  # do nothing if completing
  [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
  local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
  preexec "$this_command"
}
trap 'preexec_invoke_exec' DEBUG

dateうまくいきますが、「コマンドが見つかりません」というメッセージで失敗する同様のコマンドを表示できますls。しかし、この方法はecho

関連情報