Zsh
실행 전에 Bash
모든 입력에 사용자 지정 명령(예: 이름 지정)을 자동으로 추가하기 위해 셸의 동작을 수정(또는)하려고 합니다. myapp
기본적으로 사용자의 입력을 가로채서 수정하고 사용자가 을 누르면 ENTER_KEY
수정된 명령이 실행되어야 합니다.
셸에 입력하는 모든 명령은 다음과 같습니다.
grep -rn hello
내가 입력한 것처럼 처리되어야 합니다.
$ myapp grep -rn hello
또 다른 예를 들어, 를 입력하면 ls
로 실행되어야 합니다 myapp ls
.
표적
일부 cli 도구의 뷰어로 vim을 자동으로 사용해 보고 싶습니다.
# myapp
vim -c "term $*"
답변1
목표를 고려할 때 가장 간단한 해결책은 아래와 같이 명령 결과를 vim으로 파이프하는 것입니다.
$ yourcommand | vim -
예를 들어,
$ grep -rn hello | vim -
답변2
나는 당신이 이 배열에 들어오고 나가기를 원한다고 가정하고 다음을 수행했습니다. zsh의 경우 DEBUG 트랩 핸들러는 ERR_EXIT 옵션을 설정하여 제출된 명령 실행을 건너뛰고 대신 사용자 정의 명령을 실행할 수 있습니다.
# this is run before every command
debug_trap() {
# get last submitted command
cmd="${history[$HISTCMD]}";
if [ "$cmd" ]; then
# catch the unwrap command and remove the trap
if [ "$cmd" = "unwrap" ]; then
print 'Unwrapping command-line';
trap - DEBUG;
return;
fi
# make sure multiple trap triggers only handle this once
if [ "$handled" != "$HISTCMD;$cmd" ]; then
# when either history index or command text
# changes, we can assume its a new command
handled="$HISTCMD;$cmd";
# do whatever with $cmd
myapp $cmd;
fi
# optionally skip the raw execution
setopt ERR_EXIT;
fi
}
# start the debug trap
wrap() {
print 'Wrapping command-line';
trap 'debug_trap' DEBUG;
}
# this is just defined in order to avoid errors
# the unwrapping happens in the trap handler
unwrap() {}
Bash와 동일:
# bash requires this option in order to skip execution
# inside the debug trap
shopt -s extdebug;
# this is run before every command
debug_trap() {
cmd="$BASH_COMMAND";
# catch the unwrap command and remove the trap
# notice how the alias is expanded here and
# the command is no longer 'unwrap'
if [[ "$cmd" == 'trap - DEBUG' ]]; then
echo 'Unwrapping command-line';
# the trap is unset by the submitted command
else
# do whatever with $cmd
myapp $cmd;
# optionally skip the raw execution
return 1;
fi
}
# start the debug trap
wrap() {
echo 'Wrapping command-line';
trap debug_trap DEBUG;
}
# we can't unset global traps inside a function
# so we use an alias instead
alias unwrap='trap - DEBUG';
사용 예:
> myapp() { echo "### $1"; }
> wrap
Wrapping command-line
> echo 123
### echo 123
> unwrap
Unwrapping command-line
> echo 123
123
vim 기능을 구현하려면 myapp 함수에서 "vim -c"를 사용하거나 트랩 함수에서 "myapp $cmd;" 줄을 변경하세요.
단, 사용 전 주의사항입니다. 디버깅 트랩은 매우 까다롭기 때문에 오류를 줄이기 위해 zsh 버전을 사용해 보았습니다. oh-my-*sh와 같은 플러그인을 사용하면 안정적인 구현을 달성하는 데 어려움을 크게 증가시키는 후크, 트랩 및 기타 메커니즘이 도입될 수 있습니다. zsh 버전은 oh-my-zsh에 대해 테스트되었으며 작동해야 합니다. bash 버전은 수정되지 않은 bash v4.2에서만 테스트되었습니다.
zsh의 다른 잠재적 구현: 텍스트 버퍼를 실행하기 전에 조작하는 반환 키에 바인딩된 기본 zle 위젯 "accept-line"을 재정의할 수 있으며 이는 더 깔끔한 솔루션일 수 있습니다. 유용할 수 있는 "preexec" 후크 기능도 있지만 자체적으로 명령을 변경하거나 건너뛸 수 있는 방법은 없는 것 같습니다.
기타 사용 아이디어: 하나 이상의 원격 시스템에 (ssh) 명령을 보내고, 스크립트 파일에 작성하고 실행을 연기하고, 실행 전에 정적 분석을 수행하고, 확인을 요청하거나 오타 수정을 요구하는 데 사용할 수 있습니다.