23

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?

extremeaxe5
  • 1,183

2 Answers2

32

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.

otter.pro
  • 707
  • 2
    Also worth noting is unalias -a, which removes all aliases. – Centimane Jun 12 '19 at 12:19
  • 21
    @Centimane Yes but make sure to do \unalias -a to suppress alias expansion – Ben C Jun 12 '19 at 15:09
  • Could the sysadmin also have written /usr/bin/dirname? – RonJohn Jun 13 '19 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 '19 at 16:57
  • @doneal24 what about something like DIRNAME=$(which dirname), since which doesn't see aliases? – RonJohn Jun 13 '19 at 17:02
  • @RonJohn You could use which to figure it out but is this any more convenient or transparent than using command dirname or \dirname? – doneal24 Jun 13 '19 at 17:09
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.)

muru
  • 72,889