0
get_git_branch(){
        local branch__=

        git branch &> /dev/null

        if [ $? -eq 0 ]; then
                branch__=`git branch --no-color | sed -ne 's/^\* \(.*\)$/\1/1p' | tr a-z A-Z`
        else
                branch__="NORMAL"
        fi
        echo -n $branch__
}

exit_status(){
        local smile__=
        if [ $? -eq 0 ]; then
                smile__='(*´▽`*)'
        else
                smile__='(╥﹏╥)'
        fi
        echo -n $smile__
}

export PS1='[\w]\d\t\$\n\u->(`get_git_branch`)`exit_status`:'

This is PS1 setting in my bashrc,I want to check git branch and exit status in my terminal, get_git_branch works every time PS1 refreshed, but exit_status not, whey exit_status not executed?

ggaaooppeenngg
  • 1,323
  • 3
  • 17
  • 27
  • 1
    You shouldn't export `PS1` -- it's a local shell variable; there's no reason whatsoever to put its value in the environment for subprocesses. – Charles Duffy Jul 03 '15 at 03:56
  • BTW, why the `__`s? You're declaring these local, so you don't need to worry about namespace collisions. – Charles Duffy Jul 03 '15 at 04:05
  • Also, there's no point to `echo -n` -- the results of command substitution have trailing newlines stripped regardless. (Also, `echo` is deprecated in any nontrivial use case, including all use cases with flags; see http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html, particularly APPLICATION USAGE and RATIONALE sections). – Charles Duffy Jul 03 '15 at 04:08
  • Also, it's almost certainly possible to replace your `sed` and `tr` code with shell-builtin functionality which will be far more efficient; however, it's late, and I'm not much inclined to try to puzzle out what you were trying to do in writing it. – Charles Duffy Jul 03 '15 at 04:09
  • Frankly, if I were writing this myself, I'd also put more effort into avoiding subshells; using `$()` or backticks to perform command substitution everywhere is wildly inefficient, as it's creating subshells (`fork()` calls), reads and waits from those subshells, etc. The only place you really arguably need one is `git branch`, and even that you only need call once, not twice. – Charles Duffy Jul 03 '15 at 04:11
  • BTW, to avoid making bad assumptions about where your code is going wrong in the future, I'd suggest using `set -x` to show commands being executed. – Charles Duffy Jul 03 '15 at 04:16
  • @CharlesDuffy thx for that much replies, I am newbie in shell, really thx! BTW as for replacing sed and tr, what builtin functions do you refer to ? – ggaaooppeenngg Jul 03 '15 at 04:45
  • 1
    `${foo,,}` expands `"$foo"` in all-lowercase; `${foo^^}` expands `$foo` in all-uppercase. No shortage of other built-in string manipulation as well; see http://mywiki.wooledge.org/BashFAQ/100 – Charles Duffy Jul 03 '15 at 04:46

1 Answers1

2

It absolutely is executed. However, $? is changed by other code that's run before it -- like get_git_branch.

The best practice here is not to embed code where you want detailed flow control in PS1, but rather to use PROMPT_COMMAND.

get_git_branch(){
  local branch

  if branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null); then
    printf '%s\n' "${branch^^}" # if on bash 3.2, you may need to use tr instead
  else
    echo "NORMAL"
  fi
}

exit_status(){
  if (( ${1:-$?} == 0 )); then
    printf '%s' '(*´▽`*)'
  else
    printf '%s' '(╥﹏╥)'
  fi
}

build_prompt() {
  last_exit_status_=$?
  PS1='[\w]\d\t\$\n\u->($(get_git_branch))$(exit_status "$last_exit_status_"):'
}

PROMPT_COMMAND=build_prompt
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441