我正在使用zsh并在我的配置中添加另一个别名:
alias recursively_git_pull_all_repo="for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done"
Run Code Online (Sandbox Code Playgroud)
但是,每次我打开一个新终端时,这个别名似乎都会被执行(或者至少它会大大减慢启动新终端的速度)。
如何在每次打开新终端时添加此别名而不启动它?
TL;DR (或者应该是 TL;WR - “太长,不会读”?)
alias recursively_git_pull_all_repo='for dir in **/.git(/:h); git -C $dir pull'
Run Code Online (Sandbox Code Playgroud)
您至少部分正确,因为在声明别名时会运行此命令的一部分。这有两个影响:
您在双引号中声明别名,这允许参数扩展。这意味着部分$(find . -name ".git")和${dir%/*}将在声明别名时使用它们当时产生的值进行扩展和替换。
对于$(find . -name ".git")这意味着.最有可能$HOME与结构替换用换行分隔所有的清单.git目录,在你的home目录(和其他类似文件的对象)。
${dir%/*}可能会被替换为一个空字符串,因为dir很可能没有设置。记住:别名本身在那个时候并没有被执行,所以dir不会被for循环设置。
这意味着:
alias recursively_git_pull_all_repo="for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done"
Run Code Online (Sandbox Code Playgroud)
将有效地保存为类似
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"
Run Code Online (Sandbox Code Playgroud)
这将 - 幸运的是 -zsh: command not found: docs/repo2/.git由于第一个存储库之后的换行符而失败并出现错误。如果没有,它会反复切换到您的主目录(cd不带参数)并尝试执行git pull.
快速的解决方案是在声明别名时只使用单引号,这样命令和参数将在别名运行时替换,而不是在声明时替换。
但是还有一些其他的问题:
git pull将从当前目录运行。如果未在路径中的目录上设置执行标志,则实际上可能会发生这种情况。find也会列出命名的非目录.git相反,我建议使用zsh必须提供的内容:
alias recursively_git_pull_all_repo='for dir in **/.git(/:h); git -C $dir pull'
Run Code Online (Sandbox Code Playgroud)
find获取目录列表。该**水珠将递归扩展到所有目录。So**/.git将扩展到所有路径.git为最后一个元素。**/.git(/),限定词的/意思是:“仅目录”。:后跟修饰符来完成的 - 在这种情况下h,它删除了最后一个路径组件(如程序dirname,或${dir%/*}从您的示例中)。git;你可以告诉git在哪里工作git -C <path>for,即 no do ...; done。有趣的事实:如果您使用d替代dir,另一种简短形式for并GLOB_STAR_SHORT启用该选项(需要 zsh >= 5.2),您可以使用:
for d (**.git(/:h))git -C $d pull
Run Code Online (Sandbox Code Playgroud)
仅比您的别名长 4 个字符。是的,我知道完成。但也有历史搜索。