106

An alias, such as ll is defined with the alias command.

I can check the command with things like type ll which prints

ll is aliased to `ls -l --color=auto'

or command -v ll which prints

alias ll='ls -l --color=auto'

or alias ll which also prints

alias ll='ls -l --color=auto'

but I can't seem to find where the alias was defined, i.e. a file such as .bashrc, or perhaps manually in the running shell. At this point I'm unsure if this is even possible.

Should I simply go through all files that are loaded by bash and check every one of them?

2

8 Answers 8

102

Manual definition will be hard to spot (the history logs, maybe) though asking the shell to show what it is doing and then grep should help find those set in a rc file:

bash -ixlc : 2>&1 | grep ...
zsh -ixc : 2>&1 | grep ...

If the shell isn't precisely capturing the necessary options with one of the above invocations (that interactively run the null command), then script:

script somethingtogrep thatstrangeshell -x
...
grep ... somethingtogrep

Another option would be to use something like strace or sysdig to find all the files the shell touches, then go grep those manually (handy if the shell or program does not have an -x flag); the standard RC files are not sufficient for a manual filename check if something like oh-my-zsh or site-specific configurations are pulling in code from who knows where (or also there may be environment variables, as sorontar points out in their answer).

4
  • Thanks! Even though the output is a bit hard to parse, but I found the file that defined the alias I was looking for. When the alias isn't present anywhere in that list, would it be safe to assume the alias was defined manually?
    – polemon
    Commented Nov 10, 2016 at 22:58
  • @polemon somewhat safe; it could be (or have been) defined in a file that isn't being read in because of who-knows-what-reason-or-was-deleted (especially if there's some sort of shell framework adding complexity that the user does not understand).
    – thrig
    Commented Nov 10, 2016 at 23:01
  • 2
    To make the point where the alias is defined a bit easier to find, you can use PS4, which is prepended to every line in a trace: PS4='+The ll alias is "${BASH_ALIASES["ll"]}" ' bash -ixlc : Commented Nov 11, 2016 at 9:08
  • This saved me! I accidentally wiped my .aliases file and was able to get it back with this! Commented Sep 17, 2020 at 12:44
20

First use the following commands

List all functions

functions 

List all aliases

alias 

If you aren't finding the alias or function consider a more aggressive searching method

Bash version

bash -ixlc : 2>&1 | grep thingToSearchHere

Zsh version

zsh -ixc : 2>&1 | grep thingToSearchHere

Brief Explanation of Options

-i     Force shell to be interactive.

-c     Take the first argument as a command to execute

-x      -- equivalent to --xtrace

-l      Make bash act as if invoked as a login shell
17

Here is where I find grep -rl very useful:

This command

grep -rl alias ~/.bash* ~/.profile /etc/profile /etc/bash.bashrc

will tell you in which file the word alias is used.

It is probably in ~/.bashrc and most certainly in ~/.bash_aliases if it exists.


It is, however, impossible to be absolutely sure that this search covers all options. Those files may also call or load files anywhere else in the filesystem. An environment variable like ENV or $BASH_ENV may direct bash to load some other files.

looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.

And aliases may even be defined by setting a variable (emphasis mine):

BASH_ALIASES
An associative array variable whose members correspond to the internal list of aliases as maintained by the alias builtin. Elements added to this array appear in the alias list

1
  • grep -rl alias ~/.bash* may falsely match history files, but +1 for pointing out the BASH_ALIASES array!
    – Jeff Schaller
    Commented Nov 10, 2016 at 23:59
3

I finally found the ll alias definition for our web server (CentOS) in two shell scripts in /etc/profile.d/:

  • /etc/profile.d/colorls.csh
  • /etc/profile.d/colorls.sh

I found it by first learning from the comments above where the system-wide profile was: /etc/profile. That file states that system-wide aliases are defined in /etc/bashrc, and in that file I saw that it loops through several shell scripts in /etc/profile.d/, and so I used grep in that directory and finally found the definitions. I also discovered there's an l. alias which lists all the dot files:

From colorls.sh:

alias ll='ls -l --color=auto' 2>/dev/null
alias l.='ls -d .* --color=auto' 2>/dev/null
alias ls='ls --color=auto' 2>/dev/null

(There are equivalent aliases in colorls.csh.)

1
  • This didn't deserve a downvote IMO. The directory /dev/profile.d/ is where system-wide run commands scripts can be be found now in some flavors of Linux. No one else here mentioned that.
    – Tails86
    Commented Apr 15, 2022 at 19:55
2

I don't know of a way to actually list the source of your aliases, but since it looks like you're using bash I think these are the possible source files:

/etc/profile
~/.profile
/etc/bash.bashrc
~/.bash_profile
~/.bashrc

You should be able to grep through those to find the alias, e.g. grep 'ls -l --color=auto' /etc/profile ~/.profile /etc/bash.bashrc ~/.bash_profile ~/.bashrc.

2
  • Or files included from there...
    – Jeff Schaller
    Commented Nov 10, 2016 at 22:56
  • @JeffSchaller - Right, you'd need something more complex for that like bash -x, as you mentioned. I figured the above was easy enough to run quickly and if it doesn't find the alias you can read through the execution steps.
    – edaemon
    Commented Nov 10, 2016 at 23:32
2

Combining thrig's answer with @MarkPlotnick's suggestion, you can test whether BASH_ALIASES[ll] is set to narrow it down. The BASH_SOURCE array and LINENO variables are particularly useful here. Unfortunately, the check whether BASH_ALIASES[ll] is set will only succeed after the alias has been set, and so the first such line could be in another file altogether.

PS4='${BASH_ALIASES["ll"]+"The ll alias has been defined before"} ${BASH_SOURCE}:$LINENO ' bash -lixc : |&
  grep 'll alias' -m1 -B1

Giving output like:

   /home/muru/.bash_aliases:1 alias 'll=ls -AlhF'
TThe ll alias has been defined before /home/muru/.bashrc:116 alias 'ping=ping -c5'

You can even terminate the shell using this check:

$ PS4='${BASH_ALIASES["ll"]+"$(kill -9 $$)"} ${BASH_SOURCE}:$LINENO ' bash -lixc : |& tail -n1
   /home/muru/.bash_aliases:1 alias 'll=ls -AlhF'
4
  • This is one of a hack but it works. Any idea why there are these repeated first characters in the printed PS4 string (TT in your example)?
    – weibeld
    Commented Feb 8 at 17:59
  • @weibeld bash repeats the first character of PS4 to indicate the nesting level. In the TT case, it's two (sourcing .bashrc - it would have been three Ts if the message came from within .bash_aliases, and one T for the line executing the original command). You can use some other character as the first one (the default PS4 is +, IIRC, but in other places I have used a plain space, which results in a nice indentation).
    – muru
    Commented Feb 9 at 1:14
  • That makes perfect sense, thanks! One caveat of this solution is that it detects the first definition of an alias. If the same alias is redefined later in the file (i.e. overwrites the first definition), this solution would still point to the first, overwritten definition and not to the actually valid definition (that e.g. type also refers to).
    – weibeld
    Commented Feb 11 at 19:30
  • @weibeld true, in which case you iterate by commenting out each definition as it's detected.
    – muru
    Commented Feb 12 at 2:12
0

I've had success simply using which.

[crclayton@pc scripts]$ which foo
foo:     aliased to python $HOME/projects/python/foo.py
2
  • 2
    which can handle aliases in tcsh (and maybe earlier csh) and zsh where it is a builtin, and in bash using default profile on RedHat-family which has a kludge to run the (external) GNU program but feed it shell alias data, otherwise not. More important it only tells what the alias is set to, not where it was set, which was the Q here. Commented Nov 22, 2018 at 7:48
  • I use zsh with debian and do not get the output from above but output as @dave explains. Which os?
    – Timo
    Commented Nov 4, 2020 at 11:51
-1

Check ~/.profile if it's not in ~/.bashrc

1
  • Or files included from there...
    – Jeff Schaller
    Commented Nov 10, 2016 at 22:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .