I want to get the expansion of an alias.

For example, if I have:

alias g=hub
alias cdh='cd $HOME'

I want to have:

expand_alias g == hub

expand_alias cdh == cd $HOME

The tricky thing is that the two shells have different output: bash:

$ alias g cdh
alias g='git'
alias cdh='cd $HOME'


% alias g cdh
cdh='cd $HOME'

Note no alias prefix and no quotes around hub.

  • So what exactly are you missing? – RudiC Aug 18 '18 at 10:16
  • 2
    Note that the zsh output is the standard one. bash will give you that one as well when in POSIX mode. – Stéphane Chazelas Aug 18 '18 at 18:06
  • why are the single quotes a problem? – Henno Brandsma Aug 19 '18 at 6:04
  • @HennoBrandsma I want to define an alias based on the contents of an existing one. – Tom Hale Aug 19 '18 at 7:03
  • why define aliases that way? aliases are meant for interactive use, and usually only set once in a config file. I don't see a use case for generating aliases from other aliases. I'm just trying to understand the problem.. – Henno Brandsma Aug 19 '18 at 7:11

In zsh, you can just use

get_alias() {
  printf '%s\n' $aliases[$1]

With bash (assuming it's not in POSIX mode in which case its alias would give an output similar to zsh's), you could do:

get_alias() (
  eval '
    alias() { printf "%s\n" "${1#*=}"; }'"
    $(alias -- "$1")"

Basically, we evaluate the output of alias after having redefined alias as a function that prints what's on the right of the first = in its first argument.

You could use a similar approach for something compatible with most POSIX shells, zsh and bash:

get_alias() {
  eval "set -- $(alias -- "$1")"
  eval 'printf "%s\n" "${'"$#"'#*=}"'
| improve this answer | |
  • I wondered why parentheses are used instead of the usual braces... a function body can be a single statement, and in this case that's a subshell. – Tom Hale Aug 19 '18 at 5:50
  • 1
    @TomHale, that's to limit the scope of that alias function we declare. – Stéphane Chazelas Aug 19 '18 at 6:35

Based on Stéphane Chazelas' answer, I came up with:

function alias_expand {
  if [[ $ZSH_VERSION ]]; then
    # shellcheck disable=2154  # aliases referenced but not assigned
    [ ${aliases[$1]+x} ] && printf '%s\n' "${aliases[$1]}" && return
  else  # bash
    [ "${BASH_ALIASES[$1]+x}" ] && printf '%s\n' "${BASH_ALIASES[$1]}" && return
  false  # Error: alias not defined

(with bash 4.0 or newer).

| improve this answer | |
  • 1
    function force-expand { local e="$(expand_alias "$1")" ; test -z "$e" && e="$1" ; echo "$e" } – HappyFace Jun 19 '19 at 13:28
  • @HappyFace Cheers for pointing out the issue with the return value. Answer updated. – Tom Hale Aug 10 at 11:07

How about defining a shell function:

EXA() { alias $@ | sed 's/^/expand_/; s/=/ == /; s/\o047//g; '; }
| improve this answer | |
  • Syntax error when I copy and paste – Tom Hale Aug 19 '18 at 5:12
  • show the syntax error. – RudiC Aug 19 '18 at 6:48
  • unmatched '. How will this remove single quotes? – Tom Hale Aug 19 '18 at 8:34
  • Rats! Corrected typo... – RudiC Aug 19 '18 at 10:57
  • Breaks with: alias ls='colourify ls -CF --block-size=\'\''1 --color=always --quoting-style=shell-escape' – Tom Hale Aug 22 '18 at 8:23

In my zsh environment, when I type alias with no command I get on stdout a list of all aliases. The same happens in bash (on MacOS both). These are in a form alias=expansion

So you could filter further with sed: alias | sed -ne 's/cdh=\(.*\)$/\1/p' if "cdh" is the alias you want to know. You could make a shell function in your profile for this, if this is a common task for you: like

expand_alias() { alias $@ | sed -ne 's/.*=\(.*\)$/\1/p' }

| improve this answer | |
  • This leaves the single quotes in. Please re-read the question. – Tom Hale Aug 19 '18 at 5:10
  • @TomHale Inthe OP's example, it's not quite clear to me why the single quotes are a problem. They don't hurt for single commands, or one word substitutions; they are needed for commands with spaces. So that's why I left in the spaces, as I don't want to complicate things by adding logic to remove unnecessary single quotes. If they always have to go, just add ` | tr -d \' ` to the pipe. – Henno Brandsma Aug 19 '18 at 6:04
  • Fair enough assumption. I can't upvote you again now. The | tr wouldn't allow for a ' in the middle of an alias though. – Tom Hale Aug 19 '18 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.