如何 intercept/evaluate shell 命令,运行 命令逻辑并可能终止命令

How to intercept/evaluate a shell command, run logic on the command and potentially kill the command

我公司有一个很多人都会用到的命令行工具,但是我们需要根据用户所处的环境对该工具的使用进行一些限制。

例如,如果用户登录到我们的生产环境并且他们运行 dbt run <some more flags>,我需要闪一个警告并提示他们继续或退出。

我自己使用 zsh 并找到了 preexec() 钩子,但不幸的是,由于实现方式的原因,调用 exit 会杀死整个 shell 并关闭终点站。这似乎不适合此选项。

我正在寻找一个纯粹的 bash 替代方案(我的许多同事可能不会使用 zsh),它允许我在命令执行之前对其进行评估,运行通过一些逻辑命令,并允许我终止命令或 运行 它。

这里是我写的zsh函数供参考:

preexec() {
  command=
  first_seven_chars=${command:0:7}

  if [[ "$first_seven_chars" != "dbt run" ]]; then return; fi

  if [[ "$AWS_ENVIRONMENT" != "production" ]]; then return; fi

  if [[ "$AWS_ENVIRONMENT" = "production" ]]; then 
    read -k1 -s "key?WARNING: You are in Production. Do you want to continue? Enter y to continue or any key to exit"
    
    if [[ "$key" = "y" ]]; then
      echo "Continuing in Production..."
      
      BRANCH=$(git rev-parse --abbrev-ref HEAD)
      if [[ "$BRANCH" != "master" ]]; then
        echo 'You are currently not on the master branch. To prevent models and data deviating, please merge your changes into master and rerun';
        exit;
      fi
    else
      echo "\n"
      echo "\nStopping command from running in production..."
      exit;
    fi
    exit;
  fi 
}

注意:我知道 https://github.com/rcaloras/bash-preexec 存在,但由于它反映了 zsh 功能,因此可能不是最好的使用方式。

您需要做的是围绕原始命令创建一个包装器,而不是混淆 preexec 和其他 shell 特定的挂钩。当然,您可以将此包装器本身编写为 zsh 脚本。因此,您将创建,例如 dbt_safe.zsh,它会在内部调用 dbt,而您的同事将只使用 dbt_safe.zsh.