.bash_profile函数在同一文件目录上运行操作

.bash_profile函数在同一文件目录上运行操作

我的 .bash_profile 中有以下函数:

function GIT_BRANCH() {

    STATUS="\$(git status 2> /dev/null)";

    if [[ ! ${STATUS} ]]; then
            if [[ ! ${STATUS} = *"working tree clean"* ]]; then
                    echo "not clean repo";
            else
                    echo "clean repo";
            fi
    else
            echo "not a repo";
    fi

}

如果我像这样运行命令:

echo $(git status 2> /dev/null);
echo $(pwd);

那么不幸的是,该命令没有在我当前在 shell 中的同一目录中执行。

我尝试按照以下示例解决该问题。

STATUS="\$(git status 2> /dev/null)";

只要我用 echo 输出变量,这就可以正常工作。如果我理解正确的话,只有字符串存储在变量中,并且在比较时不执行命令。如何获取存储在 STATUS 中的命令的返回值并在同一 shell 中运行该命令?

编辑:

我用的是PS1里的这个功能。如果我尝试:

function GIT_BRANCH() {
    STATUS="\$(git status 2> /dev/null)";
    echo ${STATUS};
    TEST="\$(pwd)";
    echo ${TEST};
}

export PS1="$(COLOR "199")\u$RESET_ALL$(COLOR "45") \h \w$RESET_ALL $(COLOR "199")$(GIT_BRANCH $DIRE)$RESET_ALL\n$(COLOR "199")$ >$RESET_ALL "

然后一切正常,我得到当前目录。但如果我尝试在函数本身中使用这些信息,那就行不通,就像我之前发布的示例一样。

谢谢你的帮助。

答案1

你的问题是引用。

您本质上是PS1像这样设置变量

PS1="$(myfunction)"

PS1不需要导出,因为只有当前 shell 正在使用它)。

这将myfunction在分配给 时调用PS1,并且该函数将永远不会再次被调用。

相反,你应该使用

PS1='$(myfunction)'

这将导致myfunction每次显示提示时被调用。

函数本身不需要特殊的引用。


你的职能:

function GIT_BRANCH() {

    STATUS="\$(git status 2> /dev/null)";

    if [[ ! ${STATUS} ]]; then
            if [[ ! ${STATUS} = *"working tree clean"* ]]; then
                    echo "not clean repo";
            else
                    echo "clean repo";
            fi
    else
            echo "not a repo";
    fi

}

这可以重写为

GIT_BRANCH () {
    local status="$( git status --porcelain 2>&1 )"

    case "$status" in
        *"fatal: not a git repository"*)
            echo 'Not a repo' ;;
        "")
            echo 'Clean repo' ;;
        *)
            echo 'Not clean repo' ;;
    esac
}

或者,使用if语句:

GIT_BRANCH () {
    local status="$( git status --porcelain 2>&1 )"

    if [[ "$status" == *"fatal: not a git repository"* ]]; then
        echo 'Not a repo'
    elif [[ -z "$status" ]]; then
        echo 'Clean repo'
    else
        echo 'Not clean repo'
    fi
}

答案2

使用 PROMPT_COMMAND 参数

alux@deb904:~$ PROMPT_COMMAND=pwd
/home/alux
alux@deb904:~$ cd /tmp
/tmp
alux@deb904:/tmp$

与你的功能:

$ PROMPT_COMMAND=GIT_BRANCH

答案3

参数 PS1 是一个静态字符串,可以通过插入多个反斜杠转义的特殊字符(\u、\d、\$、...)来自定义。只有这些标签是动态的。

alux@deb904:~$ echo $PS1
\u@\h:\w\$
alux@deb904:~$ ps1="$PS1"

当使用命令(PS1=$(pwd) 或 PS1=`pwd`)评估 PS1 时,通过该命令的返回来评估 PS1。

alux@deb904:~$ PS1="$(pwd) > "
/home/alux > echo $PS1
/home/alux >
/home/alux > cd /tmp
/home/alux > echo $PS1
/home/alux >
/home/alux > pwd
/tmp

可以验证 PROMPT_COMMAND 参数是否包含在显示 PS1 的值之前执行的命令行。我们用一个函数,比较合适。

/home/alux > PS1=$ps1
alux@deb904:~$ myprompt(){ pwd; echo " > "; }
alux@deb904:~$ COMMAND_PROMPT=myprompt
/home/alux
>
alux@deb904:~$

要避免返回到该行,请使用 echo -n。

/home/alux
>
alux@deb904:~$ myprompt(){ echo -n "$(pwd) > "; }
/home/alux > alux@deb904:~$ cd /tmp
/tmp > alux@deb904:/tmp$

我们可以删除PS1的值。

/tmp > alux@deb904:/tmp$PS1=
/tmp >

但我们没有从反斜杠中转义的特殊字符。

/tmp >  myprompt(){ echo -n "$(pwd) \u \h  > "; }
/tmp \u \h >

然后我们可以使用其他参数($USER,$HOSTNAME,...)

/tmp \u \h >  myprompt(){ echo -n "$(pwd) $USER $HOSTNAME  > "; }
/tmp alux deb906 >

PROMPT_COMMAND 的值在显示 PS1 值之前执行。所以我们可以使用PROMPT_COMMAND来修改PS1。

/tmp alux deb906  > myprompt(){ PS1=$(echo -n "$(pwd) (\h) > "); }
/tmp (deb904) > echo $PS1
/tmp (deb904) >
/tmp (deb904) > cd ~
/home/alux (deb904) > echo $PS1
/home/alux (deb904) >
/home/alux (deb904) > PROMPT_COMMAND=
/home/alux (deb904) > PS1=$ps1
alux@deb904:~$ 

现在在你的 .bash_profile 中:

function GIT_BRANCH() {
  local status="$(git status 2> /dev/null)"
  local msg
  if [ "${status}" ]; then
        if [ ! "${status}" = *"working tree clean"* ]; then
                msg="not clean repo"
        else
                msg="clean repo"
        fi
  else
        msg="not a repo"
  fi
  PS1="\u \h \w ${msg}\n\$ "
}
PROMPT_COMMAND=GIT_BRANCH

答案4

使用评估:

function GIT_BRANCH() {

  STATUS="\$(git status 2> /dev/null)";

  if [ "$(eval echo ${STATUS})" ]; then

        if [ ! $(eval echo ${STATUS}) = *"working tree clean"* ]; then
                echo "not clean repo";
        else
                echo "clean repo";
        fi
  else
        echo "not a repo";
  fi

}

或者另一个附加功能:

function STATUS(){
  git status 2> /dev/null
}
function GIT_BRANCH() {
  if [ "$(STATUS)" ]; then
  fi
}

相关内容