Invoking bash aliases in Fabric scripts

2019-04-20 11:57发布

问题:

I have aliases in a ~/.bash_aliases file on a remote ubuntu server. The file is loaded in the standard way from a ~/.bashrc file, like so:

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

That ~/.bashrc file in turn is loaded (also in a standard way) from a ~/.profile file which looks like this:

if [ "$BASH" ]; then
  if [ -f ~/.bashrc ]; then
    source ~/.bashrc
    echo ".profile loaded .bashrc"
  fi
fi
mesg n

I've found that my aliases were unavailable in my fabric commands, e.g. when I do this in a fabric script:

run("aliased_command")

I get this output:

run: aliased_command
out: .profile loaded .bashrc
out: /bin/bash: aliased_command: command not found
Fatal error: run() encountered an error (return code 127) while executing 'aliased_command'

Now I managed to reproduce this outside of fabric by logging into the server with ssh, and running :

~# /bin/bash -l -c aliased_command 

from the shell (n.b. /bin/bash -l -c is fabric's default, see here) I get the same output:

.profile loaded .bashrc:
/bin/bash: aliased_command: command not found

After a fair bit of searching on related topics, I read somewhere that aliases aren't exported for non-interactive shells, and I then managed to fix this using /bin/bash -l -c -i (-i sets bash to interactive mode).

I then added the following to my fabfile.py:

env.shell = "/bin/bash -l -c -i" 

Now I can use aliases in my fabric commands... just great!


So my questions are:

  • Are there any problems with this solution? If so, what should I be doing?

  • Does anyone else have a problem running aliases in their fabfiles?

  • Is there any obvious reason why I might have this issue and others wouldn't?

  • Can anyone point me to links etc. that describe this problem and a resolution? And also explain how they found them... : )

回答1:

Here is the quick answer to the main issue, to save someone reading my long question, just add

env.shell = "/bin/bash -l -i -c" 

to your fabfile.py and you should be able use aliases in your fabric commands just great!



回答2:

Yes, you are perfectly correct that by default aliases are not expanded by the bash shell in non interactive session.

See section on alias in man page: http://linux.die.net/man/1/bash

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS below).

So to allow this to happen on an non-interactive session, include this in your .profile.

shopt -s expand_aliases

This will make aliases available in non-interactive session and your fabric scripts without resorting to interactive sessions.



回答3:

I suspect the reasoning behind bash's behavior of not exporting aliases is that aliases are designed primarily to provide a mechanism for interactive shell users to define quick shortcuts or abbreviations. In your scripts, you should be using the full commands (i.e. ls -l instead of ll) for readability. Don't make folks learn all your aliases in order to read your project's source. If your aliases are really so crucial, consider making them standalone shell scripts or at least shell functions. I think you will find it extremely uncommon to use aliases in non-interactive source code, and perhaps you should reconsider your implementation.