启动新终端时会执行zshrc别名

时间:2016-03-09 15:04:42

标签: zshrc oh-my-zsh

我正在使用$csv = '\\test\d$\citrixservers\servers.csv' $skip = if (Test-Path -LiteralPath $csv) { 1 } else { 0 } $obj_list | ConvertTo-Csv -NoType | Select-Object -Skip $skip | ForEach-Object { $_.Replace('"','') } | Add-Content \\test\d$\citrixservers\test1.csv ,在我的配置中,我添加了另一个别名:

zsh

然而,这个别名似乎每次打开一个新终端时都会被执行(或者至少它会大大减慢启动新终端的速度)。

如果每次打开新终端时都没有启动别名,我怎么能添加这个别名?

2 个答案:

答案 0 :(得分:3)

您可以将其放在函数中而不是别名中:

$ cat zshFunction

function recursively_git_pull_all_repo () {
    echo "Executing code"
    for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done
}

$ recursively_git_pull_all_repo
zsh: command not found: recursively_git_pull_all_repo

$ source zshFunction                                                                                                                                                      
$

$ recursively_git_pull_all_repo
Executing code
$

答案 1 :(得分:3)

TL; DR (或者应该是TL; WR - "太久了,不会读"?)

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

至少部分正确,因为声明别名时会运行此命令的一部分。这有两个影响:

  1. 加载别名需要时间
  2. 别名不起作用
  3. 说明

    您在双引号中声明别名,允许参数扩展。这意味着部件$(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&gt; = 5.2),你可以使用:

    for d (**.git(/:h))git -C $d pull
    

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