Should I put an alias in .bashrc or .profile?

5,845

TL;DR: Based on the description you've given, it can all go in ~/.bashrc, even though you would usually not want to put environment variables there. There are some other changes you may want to make: exporting the variables is probably unnecessary, and their expansions are best quoted.

As with Bash aliases in general, you can put your gc alias in ~/.bashrc or in ~/.bash_aliases but it should not go in .profile. If the variables are only ever needed in shells where the aliases (which expand to commands that use them) are available, then it is actually fine to put them in the same place as the aliases.

In that case, I'd suggest putting the aliases and variables in ~/.bashrc, since while it is possible to put any commands in ~/.bash_aliases, it's unusual to put anything other than alias definitions there, and doing so may confuse future readers of your code (perhaps including yourself) and motivate them to wonder if they are looking at a mistake. Of course, you could put the aliases in ~/.bash_aliases and the associated variables in ~/.bashrc, but I think that would be much more confusing.

Normally one should not put environment variables in ~/.bashrc. Most of the time, a user-specific environment variable should either go in ~/.pam_environment, which uses its own special syntax, or ~/.profile, which contains shell commands as ~/.bashrc does. (See also these comments.) One of the reasons for this is that those methods cause the environment variable to be available in most of the situations where it may be needed, which putting it in ~/.bashrc fails to achieve; one of the reasons for that is that ~/.bashrc is only used by bash, and when you log in graphically, that's not bash. But when you only need your variables when the aliases that use them are also available, this doesn't apply.

Nonetheless, I suspect that this is actually not an exception. But instead of needing to go elsewhere than .bashrc, it looks like those variables don't need to be environment variables. This is to say that it looks like you don't have to export them, but could instead simply write:

ZONE="us-eastern1-c"
INSTANCE_NAME="myInstance"

This is about the distinction between a shell variable and an environment variable. In Bourne-style shells like Bash, all environment variables are shell variables, but the only shell variables that are environment variables are those that the shell inherited from its parent process's environment or that have been exported with the export builtin.

If programs you run need to inherit ZONE and INSTANCE_NAME into their environments, they you do indeed need to export them as environment variables. And if you need that even in contexts where ~/.bashrc is not sourced (e.g., running scripts), then it is not sufficient to put those environment variables in ~/.bashrc.

Otherwise, they can just be shell variables, as shown above. The shell will still find them and perform parameter expansion on them, in commands generated by expanding the gc alias.


Whatever you do, I recommend that you modify your alias definition to double-quote those variables when it performs parameter expansion. One way to do that is to define the alias like this:

alias gc='gcloud compute ssh --zone="$ZONE" "jupyter@$INSTANCE_NAME" -- -L 8080:localhost:8080'

Given the their initial values you've shown, that only makes a difference when $IFS has an unusual value, since they contain neither whitespace nor any globbing characters like *. But it is bad practice to perform unquoted parameter expansion unless you actually intend for word splitting or globbing to occur.

More importantly, if those variables are reassigned, the new values are used when the command the alias expands to is run. The alias will still expand to the same command (the command it expands to doesn't depend on those variables' values), but the subsequent parameter expansions carried out on $ZONE and $INSTANCE_NAME will expand them to the new values. Quoting those expansions with double quotes guards against wrong behavior when variables deliberately contain whitespace (or anything in $IFS) or any of *, ? and [. But you should do it even if you believe or know they should never take on such values, so if they are given such a value by accident, you get comprehensible error messages rather than bizarre and unexpected behavior.

If you don't actually want those variables to exist at all, and you are only using them to make the definition of gc more self-documenting, then you can define gc as a function (in ~/.bashrc) instead of an alias and make them local variables:

gc() {
    local ZONE="us-eastern1-c"
    local INSTANCE_NAME="myInstance"
    gcloud compute ssh --zone="$ZONE" "jupyter@$INSTANCE_NAME" -- -L 8080:localhost:8080
}
Share:
5,845

Related videos on Youtube

DeltaIV
Author by

DeltaIV

Updated on September 18, 2022

Comments

  • DeltaIV
    DeltaIV over 1 year

    I want the following alias to be available each time I open a shell:

    export ZONE="us-eastern1-c"
    export INSTANCE_NAME="myInstance"
    alias gc='gcloud compute ssh --zone=$ZONE jupyter@$INSTANCE_NAME -- -L 8080:localhost:8080'
    

    Should I put it in .bashrc or .profile? Also, scanning through .bashrc I found:

    # Alias definitions.
    # You may want to put all your additions into a separate file like
    # ~/.bash_aliases, instead of adding them here directly.
    # See /usr/share/doc/bash-doc/examples in the bash-doc package.
    
    if [ -f ~/.bash_aliases ]; then
        . ~/.bash_aliases
    fi
    

    So, what's the best practice here? Should I put the alias (and the required enviroment variables) in a third file, .bash_aliases? I'm not a big fan of config file proliferation, but if using this .bash_aliases is a best practice, I'll do it.

    • vanadium
      vanadium over 4 years
      The answer is in the observations you posted in your question. Put aliases in .bashrc as the Ubuntu developpers do.
    • Robert Riedl
      Robert Riedl over 4 years
      an alternative would be, to write it into a small script and put it into /usr/local/bin/, name it gc.
  • DeltaIV
    DeltaIV over 4 years
    Impressive answer, well worth of a bounty - in 23 hours you'll get one.