21

In my copy of the conda.sh script, I see the following lines:

if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
    SYSP=$(\dirname "${CONDA_EXE}")
else
    SYSP=$(\dirname "${CONDA_EXE}")
    SYSP=$(\dirname "${SYSP}")
fi

I am curious as to why there is a backslash in front the the d in dirname. I do not believe it is necessary. This use of backslashes also appears in other places in the source file. Is there a reason for doing this that I am missing?

30

Backslash will suppress alias expansion, ie it executes the original command and makes sure that alias version does not run. Scripts can unknowingly run with alias expansion when the system has set shopt -s expand_aliases (BASH only) or if it is executed using source.

./conda.sh          # usually no alias expansion (unless `shopt -s expand_aliases` in BASH)
source ./conda.sh   # alias expansion
. ./conda.sh        # alias expansion

Some sysadmins like to put backslash in everything as a preventive measure against side-effects of aliases, just in case it was aliased unintentionally somewhere else and the alias gets expanded as explained previously. For example, if the system has set this alias dirname='dirname -z' somewhere and the condition allows the alias to be expanded, then a script that tries to call dirname will unfortunately call dirname -z instead, which was not the script intended.

If there's certainty that such alias do not exist, we can remove all the backslash and it should work fine.

Alternatively, one can use command instead of backslash version to suppress alias. Thus, instead of \dirname, one can use command dirname, which might look more readable. (For built-in commands like cd, one should use builtin instead). I prefer this instead, as it also bypasses function with same name as well as any aliases.

  • 1
    Also worth noting is unalias -a, which removes all aliases. – Centimane Jun 12 at 12:19
  • 19
    @Centimane Yes but make sure to do \unalias -a to suppress alias expansion – Ben C Jun 12 at 15:09
  • Could the sysadmin also have written /usr/bin/dirname? – RonJohn Jun 13 at 15:37
  • @RonJohn Yes he could have in this particular case. However, for some programs different distributions put them in different directories. One instance that comes to mind is /bin/ed on Ubuntu vs /usr/bin/ed on CentOS. Putting in a full path makes the script less portable. – doneal24 Jun 13 at 16:57
  • @doneal24 what about something like DIRNAME=$(which dirname), since which doesn't see aliases? – RonJohn Jun 13 at 17:02
20

If conda.sh is a file meant to be sourced, then the backslashes are for bypassing aliases. Bash typically disables alias expansion for script execution, but for sourced files, which may run in interactive shells, that's not the case. So just dirname may run an alias named dirname, but \dirname will skip alias expansion and run a function or command named dirname. (Not just backslashes, though, any quoting will do.)

  • 5
    Or command dirname. – Kusalananda Jun 11 at 17:32
  • 7
    (\command dirname, just in case somebody made an alias for command as well.) :| – muru Jun 12 at 2:48
  • Why does it bypass aliases? Is this functionality a special case of something, or did it have to be hardcoded into bash (i.e a hack)? – extremeaxe5 Jun 12 at 9:34
  • @extremeaxe5 bash doesn't do alias expansion if (any part of) the word is quoted. – muru Jun 12 at 9:39
  • 1
    @extremeaxe5 if you're asking why the feature exists at all, I don't know. It is in the POSIX standard however: "the command name word [...] shall be examined to determine whether it is an unquoted, valid alias name" – muru Jun 12 at 10:12

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.