run command inside of ${ curly braces

2k views Asked by At

I want to alias cd so that it takes me to the root of my current git project, and if that can't be found it takes me to my normal home dir.

I am trying to set HOME to either the git root or, if that can't be found, my normal home variable.

alias cd='HOME="${$(git rev-parse --show-toplevel):-~}" cd'

It doesn't work though.

2

There are 2 answers

14
Charles Duffy On BEST ANSWER

You can't run a command inside ${}, except in the fallback clause for when a value is not set (in POSIX sh or bash; might be feasible in zsh, which allows all manner of oddball syntax).

Regardless, far fewer contortions are needed if using a function:

# yes, you can call this cd, if you *really* want to.
cdr() {
   if (( $# )); then
     command cd "$@"
   else
     local home
     home=$(git rev-parse --show-toplevel 2>/dev/null) || home=$HOME
     command cd "$home"
   fi
}

Note:

  • Using a function lets us test our argument list, use branching logic, have local variables, &c.
  • command cd is used to call through to the real cd implementation rather than recursing.
2
AudioBubble On

Of course, it is possible to execute commands inside parameter expansions.
Well, only on the failure side, that is:

$ unset var
$ echo ${var:-"$(echo "hello world!")"}

So, you may get the git command executed if you use the failure side. Assuming that var is empty:

unset var
var=${var:-"$(git rev-parse --show-toplevel 2>/dev/null)"}"

But that would be simpler with:

var="$(git rev-parse --show-toplevel 2>/dev/null)"

And, if var is still empty after that, use:

HOME=${var:-~} builtin cd

That yields:

var="$(git rev-parse --show-toplevel 2>/dev/null)"; HOME=${var:-~} builtin cd

Which may be used in an alias as :

alias cdr='var="$(git …)"; HOME=${var:-~} builtin cd'