I'm trying to use alias command to switch between two definitions (trying to use Rust's cargo and Crystal's compiler crystal from command line). I have the following in my ~/.bash_profile:

   alias c=crystal
   alias cargo="unalias c; alias c=cargo"
   alias crystal="unalias c; alias c=crystal"

However, when I try to run something like

> c macro.rs

in macOS terminal I get

bash: alias: macro.rs: not found

What may be the problem here?


Let's see what's happening here:

$ set -x
$ c file
+ unalias c
+ alias c=crystal file
bash: alias: file: not found
$ set +x

So, c file is expanded to unalias c; alias c=crystal file (via an intermediate expansion to crystal file).

alias c=crystal file doesn't make sense. What I think you might have wanted is for crystal file to be executed.

You might want to rename the aliases that switches the meanings of c:

alias usecrystal="alias c=crystal"
alias usecargo="alias c=cargo"

Alternatively, you may protect the command from alias expansion:

alias c="\crystal"
alias crystal="alias c=\crystal"
alias cargo="alias c=\cargo"

Or use command (which IMHO looks better):

alias c="command crystal"
alias crystal='alias c="command crystal"'
alias cargo='alias c="command cargo"'

The command command also protects from alias expansion.

| improve this answer | |

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.