Wie setze ich Bash-Aliase für Docker-Container in Dockerfile?

85

Ich bin neu bei Docker. Ich fand heraus, dass wir Umgebungsvariablen mithilfe der ENV-Anweisung in der Docker-Datei festlegen können. Aber wie setzt man Bash-Aliase für lange Befehle in Dockerfile?

np20
quelle
Aliase wurde für eine im Wesentlichen als veraltet betrachtet sehr lange Zeit. Verwenden Sie eine Funktion. Es ist nicht mehr erforderlich, jemals einen Alias ​​zu verwenden. Wie kommt es, dass diese Ansätze aus den späten 80ern so lange bestehen bleiben?
William Pursell
19
Weil sie natürlich bequem und einfach sind.
Arthur
13
@WilliamPursell Vielleicht solltest du dann erklären, wie man stattdessen Funktionen verwendet.
Eric Dela Cruz
2
Aliase sind einfach, bequem, zerbrechlich und fehleranfällig. Funktionen sind ebenso einfach zu bedienen, bieten jedoch mehr Flexibilität und Robustheit. Es stehen zahlreiche Ressourcen zur Verwendung zur Verfügung.
William Pursell

Antworten:

141

Grundsätzlich wie immer, indem Sie es dem Benutzer hinzufügen .bashrc:

FROM foo
RUN echo 'alias hi="echo hello"' >> ~/.bashrc

Wie üblich funktioniert dies nur für interaktive Shells:

docker build -t test .
docker run -it --rm --entrypoint /bin/bash test hi
/bin/bash: hi: No such file or directory
docker run -it --rm test bash
$ hi
hello

Für nicht interaktive Shells sollten Sie ein kleines Skript erstellen und es in Ihren Pfad einfügen, dh:

RUN echo -e '#!/bin/bash\necho hello' > /usr/bin/hi && \
    chmod +x /usr/bin/hi

Wenn Ihr Alias ​​Parameter verwendet (z. B. hi Jim-> hello Jim), fügen Sie einfach Folgendes hinzu "$@":

RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
    chmod +x /usr/bin/hi
Erik Dannenberg
quelle
Vielen Dank dafür. Können Sie ein Beispiel für eine nicht interaktive Shell bereitstellen? Ich suchte nach ENTRYPOINT und CMD, um dies zu lösen
c24b
5
Der Bash-Alias ​​funktioniert nur in interaktiven Shells. Erstellen Sie einfach ein kleines Shell-Skript und fügen Sie Ihren Pfad ein, den gleichen Effekt wie ein Alias. Die Antwort wurde anhand eines einfachen Beispiels aktualisiert.
Erik Dannenberg
1
Hinweis: Unter stackoverflow.com/a/8467449 sollten Sie lieber printf anstelle von echo verwenden , um ein konsistenteres Verhalten sicherzustellen. Also printf '#! / Bin / bash \ necho hallo'> / usr / bin / hi chmod + x / usr / bin / hi
barraq
2
Ich liebe die Shell-Skript-Idee. Ich wollte Aliase hinzufügen, aber das ist viel viel besser. Vielen Dank.
Blizz
3
Sie sollten "$ @" anstelle von $ * für mehrere Argumente verwenden, die entkommen. Siehe unix.stackexchange.com/questions/248464/…
gnou
14

Verwenden Sie zum Erstellen eines Alias ​​eines vorhandenen Befehls möglicherweise auch Folgendes ln -s:

ln -s $(which <existing_command>) /usr/bin/<my_command>

Laurent Magnin
quelle
6
Ich würde dies nicht als Alias ​​bezeichnen. Es ist ein Softlink / Symlink. Der Vorteil von Aliasen besteht darin, dass Sie Parameter an den Befehl übergeben können, wie alias ll='ls -lh'dies mit Symlinks nicht möglich ist.
QWERZZ
3

Wenn Sie Aliase nur in Dockerfile verwenden möchten, jedoch nicht im Container, ist der kürzeste Weg die ENVDeklaration:

ENV update='apt-get update -qq'
ENV install='apt-get install -qq'

RUN $update && $install apt-utils \
    curl \
    gnupg \
    python3.6

Und zur Verwendung in Containern wie bereits beschrieben:

 RUN printf '#!/bin/bash \n $(which apt-get) install -qq $@' > /usr/bin/install
 RUN chmod +x /usr/bin/install

Die meiste Zeit verwende ich Aliase nur auf der Bauphase und gehe nicht in Container, daher ist das erste Beispiel für den täglichen Gebrauch schneller, klarer und einfacher.

Sonique
quelle
2

Ich habe dies gerade zu meiner app.dockerfile hinzugefügt

# setup aliases
ADD ./bashrc_alias.sh /usr/sbin/bashrc_alias.sh
ADD ./initbash_profile.sh /usr/sbin/initbash_profile
RUN chmod +x /usr/sbin/initbash_profile
RUN /bin/bash -C "/usr/sbin/initbash_profile"

und innerhalb der, initbash_profile.shdie nur meine benutzerdefinierten Aliase anfügt und keine Notwendigkeit, die .bashrc-Datei zu quellen.

# add the bash aliases
cat /usr/sbin/bashrc_alias.sh >> ~/.bashrc

hat ein Vergnügen gemacht!

Eine andere Möglichkeit besteht darin, einfach den Befehl "docker exec -it" von außerhalb des Containers zu verwenden und einfach Ihre eigene .bashrc oder das .bash_profile zu verwenden (was auch immer Sie bevorzugen).

z.B. docker exec -it docker_app_1 bash

mikoop
quelle
1

Sie können den Einstiegspunkt in Ihrer Docker-Datei verwenden, dies funktioniert jedoch nicht für Alias:

ADD dev/entrypoint.sh /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]

Ihre entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(Schnelles Kopieren / Einfügen, sorry)

Thomas Decaux
quelle
Beachten Sie, dass einige Docker-Images möglicherweise bereits den Standardeinstiegspunkt überschreiben (z. B. das Phusionsbasis-Image).
Thomas Decaux
1

Ich denke, der einfachste Weg wäre, eine Datei in Ihren Container zu mounten, die Ihre Aliase enthält, und dann anzugeben, wo bash sie finden soll:

docker run \
    -it \
    --rm \
    -v ~/.bash_aliases:/tmp/.bash_aliases \
    [image] \
    /bin/bash --init-file /tmp/.bash_aliases

Beispielnutzung:

user@cobalt:~$ echo 'alias what="echo it works"' > my_aliases
user@cobalt:~$ docker run -it --rm -v ~/my_aliases:/tmp/my_aliases ubuntu:18.04 /bin/bash --init-file /tmp/my_aliases
root@565e4a1bdcc0:/# alias
alias what='echo it works'
root@565e4a1bdcc0:/# what
it works
Gillespie
quelle
0
  1. Bearbeiten Sie diese Datei ~ / .bash_aliases vi ~/.bash_aliases
  2. Quelle dieser Datei ~ / .bash_aliases source ~/.bash_aliases
  3. erledigt.
Eddy Ferreira
quelle
Dies ist jedes Mal in Ordnung, wenn Sie Ihren Docker-Container hochfahren, aber die Aliase bleiben beim nächsten Mal nicht erhalten. Wenn es Ihnen nichts ausmacht, sie jedes Mal neu hinzuzufügen, ist diese Lösung in Ordnung.
Mikoop
0

Einige der oben genannten Lösungen wurden verwendet, aber die Aliase werden noch nicht erkannt.

Ich versuche, Aliase festzulegen und sie sowohl in späteren Dockerfile-Schritten als auch zur Laufzeit im Container zu verwenden.

RUN echo "alias model-downloader='python3 ${MODEL_DL_PATH}/downloader.py'" >> ~/.bash_aliases && \
    echo "alias model-converter='python3 ${MODEL_DL_PATH}/converter.py'" >> ~/.bash_aliases && \
    source ~/.bash_aliases

# Download the model
RUN model-downloader --name $MODEL_NAME -o $MODEL_DIR --precisions $MODEL_PRECISION;

Die Lösung für mich bestand darin, ENV-Variablen zu verwenden, die Ordnerpfade enthielten, und dann die genaue ausführbare Datei hinzuzufügen. Ich hätte auch ARG verwenden können, aber für mehr meiner Szenarien benötigte ich die Aliase sowohl in der Erstellungsphase als auch später in der Laufzeit.

Verwendet die ENV-Variablen in Verbindung mit einem Bash-Skript, das ausgeführt wird, sobald Abhängigkeiten verschoben wurden, und legt die Bash-Quelle fest, legt einige weitere env-Variablen fest und ermöglicht das Durchleiten weiterer Befehle.

Alanionita
quelle
Jede RUNAnweisung wird in einer neuen Shell ausgeführt, sodass in Ihrem Beispiel die Aliasdatei nicht mehr geladen wird, wenn Sie versuchen, den Alias ​​zu verwenden.
Erik Dannenberg
100% @ErikDannenberg Vielen Dank für den Kommentar und auch dafür, dass Sie mich daran erinnert haben, dass ich ein Update dazu veröffentlichen muss. Ich habe eine Lösung gefunden und es ist sehr ähnlich, wie Sie es vorgeschlagen haben.
Alanionita
0

Hier ist eine Bash-Funktion, mit der Sie Ihre Aliase in jedem Container haben, den Sie interaktiv verwenden.

ducker_it() {
    docker cp ~/bin/alias.sh "$1":/tmp
    docker exec -it "$1" /bin/bash -c "[[ ! -f /tmp/alias.sh.done ]] \
        && [[ -w /root/.bashrc ]] \
        && cat /tmp/alias.sh >> /root/.bashrc \
        && touch /tmp/alias.sh.done"
    docker exec -it "$1" /bin/bash
}

Erforderlicher Schritt vor:

grep ^alias ~/.zshrc > ~/bin/alias.sh
DjAlan
quelle