为什么我必须使用该命令两次才能执行它?

为什么我必须使用该命令两次才能执行它?

我创建了一个别名alias goto="cd $@ && source ~/.zshrc"并且它可以工作,但前提是我执行它两次。即使我在一个 shell 中执行了两次,如果我想移动到另一个目录,我也必须再次执行两次。这是为什么?我该如何改变?

我需要输入两次goto <dir>。第一次,我仍然在正常的方向,第二次,我到达了目的地。我需要获取 .zshrc 的源代码,因为我检查了路径:

CURRENT=$PWD
AT_HOME=0
AT_ROOT=0

if [ $PWD = $HOME ]; then
    AT_HOME=1
elif [ $PWD = / ]; then
    AT_ROOT=1
else
    cd ../

    if [ $PWD = $HOME ]; then
        AT_HOME=1
    elif [ $PWD = / ]; then
        AT_ROOT=1
    else
        cd ../

        if [ $PWD = $HOME ]; then
            AT_HOME=1
        elif [ $PWD = / ]; then
            AT_ROOT=1
        fi
    fi
fi

cd $CURRENT

if [ $AT_HOME = 0 ]; then
    if [ $AT_ROOT = 0 ]; then
        ZSH_THEME="prompt-basename"
    else
        ZSH_THEME="prompt-normal"
    fi
else
    ZSH_THEME="prompt-normal"
fi

它为我提供了完整路径(甚至在 /usr/lib/jvm/java-13/bin ),当我获取 ~/.zshrc 时,它为我提供了我想要的路径(.../java-13/bin)。顺便说一句,替换&&;也不起作用。

谢谢!

*这是我在 stackxchange.com 上提出的第一个问题,所以请不要太粗暴。

答案1

首先,别名不是函数,也不接受参数。相反,别名是简单的替换:当您goto foo在命令行上键入并按 Enter 键时,shellgoto在执行命令行之前只需替换为别名的值。

因此,$@不会扩展到传递给别名的参数。事实上,在这种情况下,它扩展到传递给 shell 或您正在获取的脚本的参数。这就是为什么goto第二次可以正常工作的原因:您现在在获取文件时已将目录作为参数传递.zshrc,并且$@在再次声明别名时将扩展到该参数。

此外,由于您使用"双引号"$@因此展开当您声明别名时立即。要查看这种情况,请在 shell 启动后立即键入alias不带参数的内容以查看别名。

如果您希望goto能够处理参数,则应该将其声明为函数:goto() { cd $@ && ... }

然而,一般来说,⚠️你应该不是 source ~/.zshrc。根据点文件中的内容,这可能会导致各种问题。

相反,如果您对文件进行了更改.zshrc并且想要应用它们,则应该重新启动终端(通过关闭当前选项卡/窗口并打开一个新选项卡/窗口)或重新启动 shell(通过键入exec $SHELL)。

答案2

马龙的回答有效。我没有创建别名,而是执行了以下函数:

function goto {
    cd $@ && exec $SHELL
}

而且效果很好。我还指出,每次调用 .zshrc 后,获取 ~/.zshrc 的时间会越来越长goto

相关内容