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看起来不对。命令行的经验法则是,单引号内的所有内容均按字面意思处理,而当未加引号或双引号内时,shell 根据其规则(通配、分割、参数扩展等)扩展此类字符串。在你的情况下命令

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

表示按字面意思传递给grep字符串*"$*"*,以便 grep 将此模式解释为星号,后跟双引号,后跟重复零次或多次的美元符号 ( *),后跟重复零次或多次的双引号 ( *)。这不是你所期望的。

您想将$*其视为变量(在本例中为双引号),因此请关闭它前面的单引号字符串,然后再打开:

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

但我根本不明白这些星星的原因(你不想 grep 星星,是吗?),在我看来,你可以将其简化为

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

相关内容