3

我有几个我在做的项目。我宁愿在导航到该特定目录时设置它,而不是为每个项目的位置设置别名。每个项目都是一个 git repo,当我导航到它时,我已经有一种机制可以将当前分支名称附加到 $PS1。

在我的 .bashrc 中,我调用了一个函数: parse_git_branch 以附加到命令提示符:

case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h:\w\a\]$PS1\$(parse_git_branch) "
    ;;  
*)
;;  
esac

parse_git_branch 在我的 .basrhc 末尾定义:

function parse_git_branch {
    GIT_BRANCH=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \[\1\]/')
    if [[ -n $GIT_BRANCH ]];then
            source $HOME/bin/cur
    fi
    echo $GIT_BRANCH
}

如果 GIT_BRANCH 不为空,我会获取一个简单的脚本 ~/bin/cur,它为 pwd 设置别名:

#!/bin/bash
echo "got here!"
shopt -s expand_aliases
alias current="cd $(pwd)"

获取 cur 时,未设置别名。但是,调试消息确实显示正确。

我相信这是因为 shell 脚本在我当前环境的“外部”运行。当从命令行调用 source cur 时设置别名。

那么,为什么从我的 .bashrc 中的“parse_git_branch”调用时没有设置别名?

谢谢!

4

2 回答 2

2

这里的问题是使用 $() 在子外壳中运行 parse_git_branch 。结果,在打开的终端中找不到别名当前,因为父进程看不到别名。

case "$TERM" in
  xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h:\w\a\]$PS1\$(parse_git_branch) "
    source $HOME/bin/cur
    ;;  
*)
;;

应该管用。

于 2014-09-11T19:39:15.220 回答
0

好的,我想通了。这里的问题不是我为什么要这样做。问题在于我试图从一个子shell环境中影响父shell环境(bart谈到的$()命令语法。)所以解决方法是允许来自两个环境的通信。为此,我只是使用了文件系统。这是我所做的:

.bashrc 不需要改变太多,但它也不需要任何来源:

parse_git_branch {
  GIT_BRANCH=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \[\1\]/')
  if [[ -n $GIT_BRANCH ]];then
        $HOME/bin/cur -p
  fi
  echo $GIT_BRANCH
}

我修改 ~/bin/cur 以简单地写入或读取 fs,而不是尝试修改任何环境:

#!/bin/bash
put() {
  echo $(pwd) > $HOME/.tmpalias
}
get() {
  cat $HOME/.tmpalias
}

case "$1" in
 *p) 
   put
   ;;
 *g) 
   get 
   ;;  
esac

cur 脚本将在调用时从文件 .tmpalias 写入或读取(我没有打扰参数和文件等,因为它只在两个地方调用。

然后我将以下内容添加到我的 .bash_aliases 文件中:

alias current='cd $(cur -g)'

瞧!所以我可以将它扩展为一个事件捕获机制,可以为我运行的任何命令调用。

于 2014-09-11T21:59:07.147 回答