zsh 명령 행에서 모든 별명 해결


12

중첩 된 별칭이 있으며 명령을 실행하기 전에 모든 별칭을 확인하고 싶습니다. 어떻게해야합니까?

어떤 키에 바인딩되지 않은 기능이 있다면 M-x foobar나에게도 좋습니다. 심지어 외부 명령을 사용할 수 있습니다 ( type, command, which, 무엇이든). 스레드에서 모든 것을 시도했습니다 왜 "which"를 사용하지 않습니까? 그렇다면 무엇을 사용해야합니까? 그러나 아무것도 작동하지 않습니다.


2
C-x a커서 아래에 별칭을 확장합니다 (완료 시스템을 사용한다고 가정).
Stéphane Chazelas

맞습니다 _expand_alias (^Xa): expands the word the cursor is on if it is an alias. 그것은 도움이되지만 여전히 bash에서는 전체 라인을 확장 할 수 있지만 zsh에서는 확장 할 수 없다는 것이 유감입니다.
WeSenseASoulInSearchOfAnswers

_expand_alias편집 버퍼가 더 이상 변경되지 않을 때까지 호출하는 바인딩 가능한 명령을 작성할 수 있다고 가정합니다 .
vinc17

답변:


10

Ctrl-Alt-E 입력은 bash별명 만 확장하지는 않습니다. 또한 변수, 명령 대체 (!), 프로세스 대체 (!), 산술 확장을 확장하고 따옴표를 제거합니다 (파일 이름 생성 (글 로빙) 또는 물결표 확장을 수행하지 않음).

별명을 항상 확장하지는 않습니다. 따라서 사용법이 있지만 결과가 명령 행의 의미를 잠재적으로 변경하고 부작용이 있으며 잠재적으로 위험하다는 것을 인식하는 것이 중요합니다.

예를 들어

$ a=';w' b=1
$ alias foo=bar
$ b=2; echo $b $a; cd /tmp/dir && for i do foo $(pwd) <(ls); done

I를 누르면 M-C-E여기, 그 날을 제공합니다 :

$ b=2; echo 1 ;w; cd /tmp/dir && for i do foo / /dev/fd/63; done

이것은 완전히 다른 명령 줄을 제공하며 ( 위 rm -rf *대신 대신 했을 경우 무슨 일이 있었는지 상상해보십시오 pwd) foo별칭을 확장하지 않습니다 .

을 사용하면 zsh함수 내에서 확장 된 별칭에 대한 Gilles의 메모를 작성하기 위해 다음을 수행 할 수 있습니다.

expand-aliases() {
  unset 'functions[_expand-aliases]'
  functions[_expand-aliases]=$BUFFER
  (($+functions[_expand-aliases])) &&
    BUFFER=${functions[_expand-aliases]#$'\t'} &&
    CURSOR=$#BUFFER
}

zle -N expand-aliases
bindkey '\e^E' expand-aliases

현재 명령 행이 구문 상 유효한 경우에만 별칭을 확장하므로 구문 검사기로 두 배가됩니다.

bash의 MCE 와 달리 별칭도 완전히 확인합니다. 예를 들어 다음과 같은 경우 :

$ alias ll='ls -l'; alias ls='ls --color'
$ ll

다음으로 확장됩니다 :

$ ls --color -l

구문을 정규화하여 다음과 같은 점에 유의하십시오.

$ for i (*) cmd $i; foo

로 변경됩니다 :

$ for i in *
        do
                cmd $i
        done
        foo

이것은 버그입니다. 내가 가지고있는 경우 alias ls='ls --color'와 입력 C-x a을 통해 ls, 내가 얻을 : \ls --color(새가 그래서 ls별칭으로 잘못 해석되지 않는다). 그러나 당신과 함께 expand-aliases, 나는 : ls --color결과를 모호하게 만듭니다.
vinc17

@ vinc17, 별명을 완전히 해석한다는 점에서 모호하지 않습니다 (그와 관련하여 버그가 적습니다 bash). 그러나 그 후에 명령을 실행하면 (와 같이 bash) 또 다른 별칭 확장이 발생하므로 별칭 확장을 일시적으로 사용하지 않도록 설정하는 것이 이상적 (){ setopt localoptions noexpandalias; ...; }입니다. 에서 _expand_alias버그가 발생했을 때 별칭을 확장 할뿐 아니라 버그가 있음을 알 수 \ls있습니다.
Stéphane Chazelas

@ vinc17, 백 슬래시 이스케이프 처리 _expand_aliasalias 'foo=repeat 3 foo'또는 처럼 쉽게 속 alias ls='ls --color'; alias '\ls=echo fooled'입니다. 완벽한 해결책은 없습니다.
Stéphane Chazelas

에 관한 _expand_alias위해 alias 'foo=repeat 3 foo', 나는 버그로 누락 된 백 슬래시 간주합니다. 그리고 alias '\ls=echo fooled'허용되어서는 안됩니다; 여기서 나는 bash를 선호한다 bash: alias: '\ls': invalid alias name.
vinc17

@ vinc17,에서 다른 방법으로 볼 수있는 방법을 볼 수 없습니다 bash. 백 슬래시가있는 별칭이 마음에 들지 않으면 사용하지 말고 왜 쉘이이를 거부하도록 하시겠습니까? 별칭은 csh (빈 코드)에서 빈약 한 사람의 함수 대체 기능이지만 Bourne과 같은 쉘에서는 함수로는 수행 할 수없는 트릭을 수행하는 데 사용됩니다. , 나는 그것이 할 수있는 것을 제한하는 요점을 보지 못했다.
Stéphane Chazelas

6

함수 정의에 명령 행을 채우고 함수를 인쇄하면 별명이 확장됩니다. 또한 정규화 된 공백이 생깁니다.

% alias foo='bar -1'
% alias bar='qux -2'
% f () foo -3
% which f
f () {
        qux -2 -1 -3
}

이 모든 것을 대화식 명령에 넣으려면 zle 위젯을 만들 수 있습니다. 코드를 functions배열 의 항목에 채워서 함수를 직접 정의 할 수 있습니다 . 다시 읽으면 정규화 효과가 나타납니다.

normalize-command-line () {
  functions[__normalize_command_line_tmp]=$BUFFER
  BUFFER=${${functions[__normalize_command_line_tmp]#$'\t'}//$'\n\t'/$'\n'}
  ((CURSOR == 0 || CURSOR = #BUFFER)
  unset 'functions[__normalize_command_line_tmp]'
}
zle -N normalize-command-line
bindkey  normalize-command-line

preexec후크 에서 동일한 정규화 효과를 얻습니다 . 별칭은 함수가 자동로드 될 때 확장됩니다 ( autoload -U일반적으로 별칭 확장을 피하기 위해 사용됨).

_expand_alias이 별명 인 경우 완성 기능이 커서 아래에있는 단어를 확장합니다. aliases배열을 사용합니다 . 재귀 적이 지 않습니다. 을 사용하여보다 일반적인 별칭 확장기를 구현할 수 aliases있지만 별칭이 확장되는 위치를 파악하는 것은 쉘 구문과 밀접하게 연결되어 있기 때문에 다소 어렵습니다.


2
autoload -Uzsh 문서가 권장하기 때문에 항상 간단하게 사용 했지만 -U이 글을 읽을 때까지 실제로 무엇을했는지 이해 하지 못했습니다. :) 사람이 관심을위한 또 하나는 호출 할 수 _expand_alias는 타격, 명령 줄로 별칭을 입력하여 직접 작동 <Esc>, x다음 입력의 미니 버퍼를 시작,_expand_alias<Enter>
the_velour_fog

2

중첩 된 고급 별칭이 많고 zsh가 실제로 수행 한 작업과 해당 옵션이 어떤 순서로 명령에 전달되는지 확실하지 않은 경우 언제든지 -x옵션으로 zsh를 시작할 수 있습니다 . 명령과 인수가 실행될 때이를 인쇄합니다.

그러나이 옵션은 디버깅 목적을위한 것이기 때문에 zsh -x호출 직후 (기본적으로 .zshrc의 모든 함수 / 위젯 / 플러그인) 많은 쓸모없는 것들을 인쇄하며 명령 실행 중에도 특히 장황 할 수 있습니다. 정의 preexec하고 precmd연결 한 경우

나는 또한 인쇄 것을 언급해야 에만 마지막으로 실행하는 명령 및 명령은 너무 후 별도로 인쇄되어 분리 된

alias a='echo a'
alias b='echo b'
alias c='echo c'
alias d='echo d'
a && b || c; d

당신은 볼 것이다

+zsh:1> echo a
a
+zsh:1> echo b
b
+zsh:1> echo d
d
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.