zsh 함수의 $* 변수로 인해 예상치 못한 결과가 발생함

zsh 함수의 $* 변수로 인해 예상치 못한 결과가 발생함

나는 이 함수를 가지고 있습니다 (내 ~/.zshrc에 정의되어 있습니다):

function graliases
{
    if [[ "$#*" -lt 1 ]]
    then
        echo "Usage: graliases <regex>"
    else
        echo "$*"
        grep -E '*"$*"*' ~/.dotfiles/zsh/aliases.zsh
    fi
}

~/.dotfiles/zsh/aliases.zsh이 함수의 역할은 인수로 제공된 정규식을 사용하여 파일을 검색하는 것입니다. 정규식의 경우 두 개의 별표를 추가하고 앞에 추가하면 찾기 결과가 줄의 위치와 무관하게 됩니다. 일반 grep을 사용하면 내 아이디어가 작동합니다.

$ grep -E '*git rebase*' ~/.dotfiles/zsh/aliases.zsh
    alias gr='git rebase'
    alias gra='git rebase --abort'
    alias grc='git rebase --continue'
    alias gri='git rebase --interactive'
    alias grs='git rebase --skip'


$ grep -E '*ls -la*' ~/.dotfiles/zsh/aliases.zsh
alias lnew='ls -ld *(/om[1,3])'     # Show three newest directories. "om" orders by modification. "[1,3]" works like Python slice.
alias lsize='ls -l */**(Lk+100)'    # List all files larger than 100kb in this tree
alias lvd='ls -ld **/*(/^F)'        # recursively list any empty sub-directories
alias l='ls -lph'                   # size,show type,human readable
alias la='ls -lAph'                 # long list,show almost all,show type,human readable
alias lt='ls -lAtph'                # long list,sorted by date,show type,human readable

이 grep 예제의 들여쓰기는 원래대로이며 오류가 아닙니다. 내 함수는 기본적으로 동일한 작업을 수행해야 합니다. 두 개의 별표(이 경우 git rebasels -la) 사이에 있는 항목을 매개 변수로 사용하면 됩니다.

그러나 그것은 같은 일을 하지 않으며 왜 그런지 모르겠습니다.

$ graliases git branch
git branch
alias lnew='ls -ld *(/om[1,3])'     # Show three newest directories. "om" orders by modification. "[1,3]" works like Python slice.
    alias findAllIPs="nmap -sP 192.168.1.* | grep -oE '192.168.1.[0-9]*'"
    alias findLocalIP="ifconfig | grep -oE 'inet 192.168.1.[0-9]*'"
    alias apls="apt list"
    alias gcR='git reset "HEAD^"'
    alias gdi='git status --porcelain --short --ignored | sed -n "s/^!! //p"'
    alias ggf="git ls-files | grep -i"
    alias gCl='git status | sed -n "s/^.*both [a-z]*ed: *//p"'
    alias gpc='git push --set-upstream origin "$(git-branch-current 2> /dev/null)"'
    alias gpp='git pull origin "$(git-branch-current 2> /dev/null)" 
          && git push origin "$(git-branch-current 2> /dev/null)"'
    alias gwig="git update-index --assume-unchanged"
    alias gwuig="git update-index --no-assume-unchanged"



% graliases ls -la
ls -la
alias lnew='ls -ld *(/om[1,3])'     # Show three newest directories. "om" orders by modification. "[1,3]" works like Python slice.
    alias findAllIPs="nmap -sP 192.168.1.* | grep -oE '192.168.1.[0-9]*'"
    alias findLocalIP="ifconfig | grep -oE 'inet 192.168.1.[0-9]*'"
    alias apls="apt list"
    alias gcR='git reset "HEAD^"'
    alias gdi='git status --porcelain --short --ignored | sed -n "s/^!! //p"'
    alias ggf="git ls-files | grep -i"
    alias gCl='git status | sed -n "s/^.*both [a-z]*ed: *//p"'
    alias gpc='git push --set-upstream origin "$(git-branch-current 2> /dev/null)"'
    alias gpp='git pull origin "$(git-branch-current 2> /dev/null)" 
          && git push origin "$(git-branch-current 2> /dev/null)"'
    alias gwig="git update-index --assume-unchanged"
    alias gwuig="git update-index --no-assume-unchanged"

~에 따르면1,2$*이 사용 사례에 대한 올바른 변수입니다. 해당 줄도 echo "$*"예상된 결과를 인쇄합니다. 불행히도 $*zsh 매뉴얼 페이지에서 명확한 설명을 찾지 못했습니다 .

내 기능이 제대로 작동하지 않는 이유는 무엇입니까?

답변1

패턴이 grep올바르지 않은 것 같습니다. 명령줄에 대한 경험적 규칙은 작은 따옴표 안의 모든 내용이 문자 그대로 처리되고, 따옴표가 없거나 큰 따옴표 안에 있는 경우 쉘은 해당 규칙(전역화, 분할, 매개변수 확장 등)에 따라 해당 문자열을 확장한다는 것입니다. 귀하의 경우 명령

grep -E '*"$*"*' ~/.dotfiles/zsh/aliases.zsh

grep문자 그대로 문자열 에 전달되는 것을 의미합니다 *"$*"*. 따라서 grep은 패턴을 별표, 큰따옴표, *0회 이상 반복되는 달러 기호( ), 0회 이상 반복되는 큰따옴표( ) 로 해석합니다 *. 이것은 당신이 기대하는 것이 아닙니다.

$*이를 변수(이 경우 큰따옴표)로 처리하려고 하므로 앞에 있는 작은따옴표 문자열을 닫고 다시 엽니다.

grep -E '*'"$*"'*' ~/.dotfiles/zsh/aliases.zsh

하지만 나는 이 별들의 이유를 전혀 이해하지 못합니다(당신은 별을 찾고 싶지 않습니까?). 그것을 단순화할 수 있는 것 같습니다.

grep -E "$*" ~/.dotfiles/zsh/aliases.zsh

관련 정보