启动新终端时执行zshrc别名

标签 zshrc oh-my-zsh

我正在使用zsh,并在我的配置中添加了另一个别名:

alias recursively_git_pull_all_repo="for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done"

但是,此别名似乎在每次打开新终端时都会执行(或者至少会大大减慢启动新终端的速度)。

每次打开新终端时,如何在不启动别名的情况下添加它?

最佳答案

TL; DR (或者应该是TL; WR-“太长,无法阅读”?)

alias recursively_git_pull_all_repo='for dir in **/.git(/:h); git -C $dir pull'

您至少部分正确的是,在声明别名时运行了此命令的一部分。这有两个效果:
  • 加载别名需要时间
  • 别名不起作用

  • 解释

    您在用双引号声明别名,这允许参数扩展。这意味着在声明别名时,部分$(find . -name ".git")${dir%/*}将被扩展并替换为它们当时所产生的值。

    对于$(find . -name ".git"),这意味着.最有可能是$HOME,并且该结构由换行分隔的列表替换,该列表以换行分隔的列表包含主目录中的所有.git目录(以及其他类似文件的对象)。
    ${dir%/*}可能会替换为空字符串,因为很可能未设置dir。请记住:别名本身当时未执行,因此dir循环不会设置for

    这意味着:
    alias recursively_git_pull_all_repo="for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done"
    

    将有效地保存为类似
    alias recursively_git_pull_all_repo="for dir in docs/repo1/.git
    docs/repo2/.git
    otherdocs/repo/.git
    whatever/.git; do
    cd ; git pull ; cd -; done"
    

    幸运的是,由于第一个存储库之后的换行符,此操作将失败并出现zsh: command not found: docs/repo2/.git错误。如果没有,它将反复进入您的主目录(不带参数的cd),然后尝试执行git pull

    解决方案

    快速的解决方案是在声明别名时仅使用单引号,这样在别名运行时(而不是在声明别名时)将替换命令和参数。

    但是仍然存在其他一些问题:
  • 如果任何目录名包含空格,则将失败,因为for会将其解释为两个值
  • 如果您无法切换到找到的目录之一,则git pull将从当前目录运行。如果未在路径中的目录上设置execute标志,则实际上会发生这种情况。
  • 没有附加参数的
  • find还将列出名为.git的非目录

  • 我建议使用zsh提供的内容来代替:
    alias recursively_git_pull_all_repo='for dir in **/.git(/:h); git -C $dir pull'
    
  • 您实际上不需要find即可获取目录列表。 ** glob将被递归扩展到所有目录。因此,**/.git将扩展到以.git作为最后一个元素的所有路径。
  • 您可以使用glob限定符将扩展限制为满足某些条件的元素。在这种情况下,**/.git(/)限定词/的意思是:“仅目录”。
  • ,您还可以将扩展修饰符历史记录为glob限定符。这是通过在:后面加上修饰符完成的-在本例中为h,它删除了最后一个路径组件(例如示例中的dirname${dir%/*}程序)。
  • 实际上不需要为了使用git而将目录更改为git存储库;您可以告诉git在哪里使用git -C <path>
  • ,因为您现在仅在循环内运行一个命令,因此可以对for使用简短语法,这意味着不使用do ...; done


  • 有趣的事实:如果您使用d而不是dir,则是另一种简短形式的for,并且启用了GLOB_STAR_SHORT选项(需要zsh> = 5.2),您可以使用:
    for d (**.git(/:h))git -C $d pull
    

    仅比您的别名长4个字符。是的,我知道完成。但是也有历史搜索😉。

    关于启动新终端时执行zshrc别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35895229/

    相关文章:

    macos - 哦,我的 OSX 上的 ZSH Docker 自动完成功能不起作用

    windows - 修改了以 Vagrant & ZSH 结尾的行

    linux - 从配置文件命令运行 tmux 时 iterm 损坏管道

    iterm2 - macOS Mojave 更新后 - iterm 和 zsh 损坏

    shell - iTerm2 Shell 集成和 Oh My Zsh 冲突

    Bash 补全在 ZSH/Oh-My-ZSH 中不起作用,因为 COMP_WORDS 不是数组

    zsh - $- 上的 .zshrc 无法识别的情况

    command-line - 终端错误 - 尝试任何命令时出现 "zsh: command not found"

    zsh - 如何使zsh前向字行为与bash/emacs中的相同

    bash - ZSH 脚本和提示分析?