ZSH를 사용한 명령 유효성 검사

프로세스 이전에 일부 명령을 실행하고 프로세스 후에 다른 명령을 실행하는 것을 잊는 것에 지쳤습니다. 그래서 이 책임을 단말기에 맡기기로 했습니다. 왜 안 돼?

ZSH에는 이 작업을 수행하는 데 사용할 수 있는 두 개의 후크preexec(이후) 및 precmd(이전)가 있습니다.

검증



두 개의 변수가 필요합니다. 하나는 precmd (이전) 후크를 실행하지 않기 위해 프로세스가 상당히 이른 것인지를 알기 위한 것이고 다른 하나는 어떤 명령이 실제로 실행되고 있는지 알기 위한 것입니다.
~/.zshrc 파일을 열고 이러한 변수를 스크립트에 추가합니다.

local quit="y"
local cmd=""


나는 항상 npm run build 전에 npm publish 명령을 실행하는 것을 잊었습니다. 따라서 이전에 명령을 실행했는지 확인하는 메시지를 표시하는 함수before_validation를 생성할 것입니다.

cancel(){
  echo "\e[43m\e[30mALERT:\e[0m Did you run \e[1m'$1'\e[0m command before?"
  echo "\e[32m[ANY] = Continue \e[0m| \e[31m[Ctrl+c] = Cancel \e[0m"
  read -sk key
  quit="n"
}

before_validation(){
  local cmd_validation=""
  local cmd_previous=$(fc -ln -1 | xargs) # Get previous command from history
  local cmd_current=$(echo $1 | xargs)

  if [[ "$cmd_current" =~ ^"npm publish" ]]; then
    cmd_validation="npm run build"
  elif [[ "$cmd_current" =~ ^"git checkout" ]]; then
    cmd_validation="git pull"
  # ---
  # Add all elif (else if) that you need
  elif [[ "$cmd_current" =~ ^"your command" ]]; then
    cmd_validation="command to run before"
  # ---
  fi

  if [[ ! -z $cmd_validation ]]; then
    if [[ "${cmd_validation}" != "${cmd_previous}" ]]; then
      cancel $cmd_validation # show cancel alert if is not the previous
    fi
  else
    quit="n"
  fi
}


현재 위험한 명령에 대한 경고는 없습니다. 그래서 우리는 경고 메시지를 표시하고 우리에게 두 번째 기회를 주는 함수danger_validation를 만들 것입니다.

danger(){
  echo "\e[41m\e[97mDANGER:\e[0m Are you sure? really?"
  echo "\e[32m[ANY] = Continue \e[0m| \e[31m[Ctrl+c] = Cancel \e[0m"
  read -sk key
  quit="n"
}

danger_validation(){
  local cmd_current=$(echo $1 | xargs)

  if [[ "$cmd_current" =~ ^"rm -rf /" ]]; then
    danger
  elif [[ "$cmd_current" =~ ^"git reset --hard HEAD" ]]; then
    danger
  elif [[ "$cmd_current" =~ ^"git clean -f -d -x" ]]; then
    danger
  # Add all elif (else if) that you need
  elif [[ "$cmd_current" =~ ^"your command" ]]; then
    danger
  # ---
  fi
}


그리고 npm i 다음에 git pull origin ... 명령을 실행하는 것을 잊었습니다. 따라서 이후에 명령을 실행할 것인지 확인하는 메시지를 표시하는 함수after_validation를 생성할 것입니다.

run(){
  echo "\e[43m\e[30mALERT:\e[0m Do you want to run \e[1m'$1'\e[0m command after?"
  echo "\e[32m[Y] = Yes \e[0m| \e[31m[ANY] = Cancel \e[0m"
  read -sk key
  if [[ "$key" == "y" ]] || [[ "$key" == "Y" ]]; then
    echo "\e[32m❯ \e[33mRunning...\e[0m"
    eval $1
  fi
}

after_validation(){
  if [[ "$cmd" =~ ^"git pull origin" ]]; then
    run "npm i"
  elif [[ "$cmd" =~ ^"git checkout" ]]; then
    run "npm i"
  elif [[ "$cmd" =~ ^"npm run build" ]]; then
    run "obp" #open build folder alias
  # ---
  # Add all elif (else if) that you need
  elif [[ "$1" =~ ^"your command" ]]; then
    cancel "command to run after"
  # ---
  fi
}


이제 후크와 연결할 수 있는 "팩토리 함수"와 같은 것을 만들어야 합니다. 전이나 후에 둘 이상의 함수를 호출할 수 있기 때문에 이 방법을 선호했습니다.

pre_validation() {
  quit="y" && cmd=""
  [[ $# -eq 0 ]] && return # If there's no input, return. Else...
  cmd="$1" # Save global for after validation
  expand_command_line "$@"
  danger_validation "$@"
  before_validation "$@"
}

pos_validation() {
  [[ -z $cmd ]] && return # If there's no cmd, return. Else...
  if [[ "$quit" == "n" ]]; then
    after_validation
  fi
  quit="y"
}


그리고 여기에서 pre_validation 함수를 preexec (이전) 후크와 연결하고 pos_validationprecmd (이후) 후크와 연결합니다.

autoload -U add-zsh-hook                  # Load the zsh hook module
add-zsh-hook preexec pre_validation       # Adds the pre hook
add-zsh-hook precmd pos_validation        # Adds the pos hook


이 후크를 제거할 계획은 없지만 다음 명령을 사용하여 제거할 수 있습니다.

# add-zsh-hook -d preexec pre_validation  # Remove it for this hook
# add-zsh-hook -d precmd pos_validation   # Remove it for this hook


완료되면 모든 터미널을 다시 열거나 소스 실행source ~/.zshrc 명령을 업데이트하면 이제 유효성 검사를 사용할 준비가 된 것입니다.


예시










GitHub: ZSH Dev Toolkit 리포지토리에서 이 코드 및 기타 ZSH 유틸리티를 다운로드하거나 복제할 수 있습니다.


출처:
  • Bash Colors



  • 그게 다야!
    행복한 코딩 🖖

    좋은 웹페이지 즐겨찾기