Mike D
Mike D

Reputation: 6195

Elegant solution to show bash alias value

Like everyone who uses *nix shells, I have a significant number of aliases and I frequently forget the details of an alias I'm using.

Possibly this is laziness, but reducing keystrokes and command executions increases my productivity. So I'm looking for a clean solution that does the below, for every alias I have defined in my bash4 environment.


Alias defined as:
alias l='ls -laH'

Desired additional alias to be created before entering in the shell:
alias l?='alias l'

Desired results:
$ l? alias l='ls -laH'


The format is always "{alias_name}?"

The goal is not to have to create an individual "help" alias for every alias. I could iterate, but that seems clunky to me.

Upvotes: 1

Views: 375

Answers (4)

Mark Reed
Mark Reed

Reputation: 95242

EDIT: If you're using Bash 4, you can use the command_not_found_handle to do this, as suggested by chepner below. I would accept that answer in lieu of mine.

If you're stuck with Bash <=3, though, I fear the best you can do is iterate, with something like this:

 for a in $(alias | sed 's/alias \([^=]*\)=.*/\1/'); do alias "${a}?"="alias '$a'"; done

(Pick your favorite way of extracting the alias names out of the alias output..)

To avoid that, the closest thing I can think of would be to make ? itself an alias (or some other character; as chepner also notes, ? is a single-character wildcard, which can make the contents of your current working directory randomly blow up your alias). You could make it an alias for alias itself, so you could do e.g. ? l instead of l?, with simply alias \?=alias. As you said, autocomplete might make that nicer, which you could do with complete -a \?.

Upvotes: 1

chepner
chepner

Reputation: 530823

Since you are using bash 4, you can take advantage of the command_not_found_handle hook:

command_not_found_handle () {
    if [[ $1 =~ .*\? ]]; then
        alias ${1%?}
    else
        printf "Command not found: $1\n"
        return 127
    fi
}

However, ? is a poor choice for the suffix to use, since it is the shell pattern metacharacter that matches any single character. For example, if there is a file in the current directory that matches l? (say, la), then the shell will attempt to run la rather than l?, and your custom alias hook will not run. You could disable globbing with set -f, but invoking your alias hook with l\? would probably be better.

Another option would be to use @—for "@lias" :)—instead of ? as the suffix to trigger the hook, as @ is unlikely to occur in any command name and is not a shell metacharacter.

Upvotes: 3

Etan Reisner
Etan Reisner

Reputation: 80921

I think MarkReed's ? as alias/function solution is a fairly elegant one.

Something like:

alias ?=alias
complete -a ?

or:

?() {
    for arg; do
        if [ "$(type -t "$arg")" = alias ]; then
            alias "$arg"
        else
            echo "No such alias: $arg"
        fi
    done
}
complete -a ?

With the function (and bash 4) you could even then keep an aliasinfo associative array with more usage/help/etc. information about each alias and then echo that out too.

?() {
    for arg; do
        printf %s "${aliasinfo[$arg]:+"$aliasinfo[$arg]"$'\n'}"
        if [ "$(type -t "$arg")" = alias ]; then
            alias "$arg"
        else
            echo "No such alias: $arg"
        fi
    done
}

And then when you define an alias you do something like this:

aliasinfo[l]="Full long directory listing"
alias l='ls -laH'

Upvotes: 0

csiu
csiu

Reputation: 3269

You can just type alias in the command prompt

$ alias l
alias l='ls -laH'

Note: invoking alias without argument will display every alias that is currently defined

Upvotes: 0

Related Questions