6

I have a bash alias loaded into a Docker container, in /etc/bash.bashrc. It functions as a shortcut to a commandline PHP script. This is convenient, since anyone can use that alias directly after one logs into the container, with:

$ docker exec -it my-container bash

However, I would also like to be able to use this alias in one-off commands without logging in, like:

$ docker exec -it my-container my-alias

I have tried different variations, such as defining the alias in other places than /etc/bash.bashrc, but I keep running into this error:

rpc error: code = 2 desc = oci runtime error: exec failed: exec: "my-alias": executable file not found in $PATH

Other suggestions I find on the web did not do the trick, so far. Anyone?

  • Make a script in the container, and call the script with full path name? – bgStack15 Jul 11 '16 at 14:05
  • That's definitely a fine idea for a workaround, thanks! However I do wonder why an alias by itself isn't picked up in this context. I thought it should, since it's in /etc/bash.bashrc, and not in f.i. a login based .profile. – David Spreekmeester Jul 11 '16 at 15:19
  • Have you tried exporting my-alias as an environment variable and then using the following? docker exec -it my-container $my-alias – joat Sep 9 '16 at 1:56
  • What you were attempting was somewhat limited. Bash aliases allow you to declare an alias for an entire command line. It may or may not work (yours doesn't) when you create aliases for portions of a command line. Exporting my-alias as an environment variable for the bash session may be a better approach. – joat Sep 9 '16 at 1:58
3

It doesn't due to limitations due to aliases being meant to be used interactively. You can probably hack around this but the easiest solution is by far to simply make your "alias" into a script and place it in /bin.

Dockerfile

RUN echo '#! /bin/sh'                >> /bin/mycommand
RUN echo 'echo "running mycommand!"' >> /bin/mycommand
RUN chmod u+x /bin/mycommand

Then it works as expected

docker exec -it f3a34 mycommand # => running mycommand!
| improve this answer | |
0

It took me a slightly different approach eventually, because I haven't managed to get it to work with the bash.bashrc strategy. @joat is right, an alias is probably an unfortunate combination with the partial execution of a command line (with docker exec).

In the end, I injected a script (in my case through PHP Composer) into the image. In my case by mounting my local directory, although that shouldn't matter. Then I add the path to this script in my Dockerfile through an environment variable:

ENV PATH $PATH:./vendor/bin

This makes the script globally available at runtime.

I do consider it a workaround, still, so interested to hear from anyone who actually got regular aliases to work at docker exec runtime.

| improve this answer | |
  • 1
    Please explain in specific detail what the workaround is. I read your answer 5 times and I still don't know what the workaround is. – Ramhound Dec 5 '16 at 18:33
  • @Ramhound: Sorry about that, you're right. Did some digging and I found that my eventual solution was in fact slightly different. Will update the answer now. – David Spreekmeester Dec 7 '16 at 13:01
0

I had this problem and I solved it by wrapping the command I wanted to execute inside a temporary shell, in the example you have it would be done like this:

$ docker exec -it my-container sh -l -c "my-alias"

(the -l flag is only needed if your aliases are only available in login shells, which is my case)

It does make it more verbose, but you can always create an alias or a function to wrap this.

| improve this answer | |
0

Aliases are mostly useful when you want to shorten part of a commonly used command which takes variable arguments. In a ruby dev context that might be creating an alias like

alias be="bundle exec"

because who wants to type out bundle exec all the time?

If what you really want is a shorter version of a longer command with static arguments then you should create a script anyway. With a script, it will always be available and not be dependent on sourcing particular profiles in particular contexts (which you can basically never rely on).

A more comman case (like that above) is when you use an alias because you want to effortless string arguments on to the end of the alias. For instance

$ be rails server

or

$ be rake db:migrate

In both cases, i don't want to have to type out more than I need to. With just a dash of bash, however, you can achieve the same thing in a more versatile solution.

Similar to some of the above answers, create a file - /usr/local/bin/be in this example. This assumes that /usr/local/bin is included in your PATH.

#!/usr/bin/env bash

bundle exec "$@"

followed up with (possibly with sudo)

$ chmod +x /usr/local/bin/be

This is a bit of a naive example, and requires that both ruby and the bundler gem have been installed, but the thing to notice is "$@" which let's you pass in a variable number of arguments into the script. Thus, you get the ergonomics of the alias, but with a command that is always available and not context dependent.

I find this approach particularly helpful when working with containers. Hope it helps.

| improve this answer | |
  • You should always put $@ (and other shell variables) in quotes:  i.e., bundle exec "$@". – Scott Nov 5 '18 at 4:13
  • Thanks for pointing that out. I went ahead and updated as it's a good habit to be in, but in this case, however, it's not strictly necessary. – jamesconant Nov 6 '18 at 10:25

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.