有没有办法通过 shell 脚本路由所有命令而不是直接运行?

有没有办法通过 shell 脚本路由所有命令而不是直接运行?

我希望能够执行所有内容,而不是运行程序,而是运行一个以可执行文件作为参数的 shell 脚本。如果能够做到这一点而无需单独选择系统上的所有可执行文件,那就太好了。

答案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失败并显示“找不到命令”。但这种方式不适用于 shell 内置命令,如echo.

相关内容