Как установить псевдонимы bash для контейнеров докеров в Dockerfile?

87

Я новичок в докере. Я обнаружил, что мы можем установить переменные среды с помощью инструкции ENV в Dockerfile. Но как установить псевдонимы bash для длинных команд в Dockerfile?

np20
источник
псевдонимы были рассмотрены по существу устаревший для очень долгого времени. Используйте функцию. Существует больше нет никакой необходимости когда - либо использовать псевдоним. Как получается, что эти подходы конца 80-х сохраняются так долго?
Уильям Перселл
19
Потому что они, конечно, удобны и просты.
Arthur
13
@WilliamPursell Может быть, тогда вам стоит объяснить, как вместо этого использовать функции.
Эрик Дела Круз
2
Псевдонимы просты, удобны, ненадежны и подвержены ошибкам. Функции так же просты в использовании, но обеспечивают большую гибкость и надежность. Доступно множество ресурсов о том, как их использовать.
Уильям Перселл

Ответы:

144

В принципе, как и всегда, добавив его пользователю .bashrc:

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

Как обычно, это работает только для интерактивных оболочек:

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

Для неинтерактивных оболочек вы должны создать небольшой скрипт и поместить его в свой путь, то есть:

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

Если ваш псевдоним использует параметры (например, hi Jim-> hello Jim), просто добавьте "$@":

RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
    chmod +x /usr/bin/hi
Эрик Данненберг
источник
Спасибо за это, можете ли вы привести пример неинтерактивной оболочки? Я искал ENTRYPOINT и CMD, чтобы решить эту проблему
c24b
5
Псевдоним Bash работает только в интерактивных оболочках. Просто создайте небольшой сценарий оболочки и введите свой путь с таким же эффектом, как и псевдоним. Обновил ответ простым примером.
Эрик Данненберг
1
Примечание: из stackoverflow.com/a/8467449 вам лучше использовать printf вместо echo, чтобы обеспечить более последовательное поведение. Итак, printf '#! / Bin / bash \ necho hello'> / usr / bin / hi chmod + x / usr / bin / hi
barraq
2
Мне нравится идея сценария оболочки. Хотел добавить псевдонимы, но это намного лучше. Благодарю.
Blizz
3
Вы должны использовать «$ @» вместо $ * для экранирования нескольких аргументов. См unix.stackexchange.com/questions/248464/...
gnou
14

Чтобы создать псевдоним существующей команды, также можно использовать ln -s :

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

Лоран Маньен
источник
7
Я бы не назвал это псевдонимом .. это мягкая ссылка / символическая ссылка. Удобство псевдонимов заключается в том, что вы можете передавать команде параметры, подобные тому, alias ll='ls -lh'что невозможно с символическими ссылками.
qwertz
3

Если вы хотите использовать псевдонимы только в Dockerfile, но не внутри контейнера, то самый короткий способ - это ENVобъявление:

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

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

И для использования в контейнере, как уже описано:

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

В большинстве случаев я использую псевдонимы только на этапе сборки и не захожу внутрь контейнеров, поэтому первый пример быстрее, понятнее и проще для повседневного использования.

Sonique
источник
2

Я только что добавил это в свой файл app.dockerfile

# 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"

и внутри, initbash_profile.shкоторый просто добавляет мои пользовательские псевдонимы и нет необходимости исходить из файла .bashrc.

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

работал угощение!

Другой вариант - просто использовать команду docker exec -it извне контейнера и просто использовать свой собственный .bashrc или .bash_profile (что бы вы ни выбрали)

например. docker exec -it docker_app_1 bash

Микоп
источник
1

Вы можете использовать точку входа, но она не будет работать с псевдонимом в вашем Dockerfile:

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

Твой entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(Быстрое копирование / вставка, извините)

Томас Деко
источник
Обратите внимание, что некоторые образы Docker уже могут переопределять точку входа по умолчанию (например, базовый образ phusion).
Thomas Decaux
1

Я думаю, что самый простой способ - смонтировать файл в ваш контейнер, содержащий ваши псевдонимы, а затем указать, где bash должен его найти:

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

Пример использования:

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
Гиллеспи
источник
0

Использованы некоторые из вышеперечисленных решений, но псевдонимы до сих пор не распознаются.

Я пытаюсь установить псевдонимы и использовать их как в последующих шагах Dockerfile, так и в контейнере во время выполнения.

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;

Для меня решением было использовать переменные ENV, содержащие пути к папкам, а затем добавить точный исполняемый файл. Я мог бы также использовать ARG, но для большинства моих сценариев мне нужны псевдонимы как на этапе сборки, так и позже во время выполнения.

Используются переменные ENV в сочетании со сценарием bash, который запускается после того, как зависимости установлены, и устанавливает источник bash, устанавливает еще несколько переменных env и позволяет передавать дальнейшие команды.

аланионита
источник
Каждая RUNинструкция выполняется в новой оболочке, поэтому в вашем примере файл псевдонима больше не загружается, когда вы пытаетесь использовать псевдоним.
Эрик Данненберг
100% @ErikDannenberg, спасибо за комментарий, а также за напоминание мне, что мне нужно опубликовать обновление для этого - я нашел решение, и оно очень похоже на то, что вы предложили.
alanionita
0

Вот функция Bash, чтобы ваши псевдонимы были в каждом контейнере, который вы используете в интерактивном режиме.

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
}

Обязательный шаг до:

grep ^alias ~/.zshrc > ~/bin/alias.sh
Джалан
источник
-1
  1. отредактируйте этот файл ~ / .bash_aliases vi ~/.bash_aliases
  2. источник этого файла ~ / .bash_aliases source ~/.bash_aliases
  3. сделанный.
Эдди Феррейра
источник
Это нормально каждый раз, когда вы запускаете свой док-контейнер, но псевдонимы не сохранятся в следующий раз. если вы не против повторно добавлять их каждый раз, когда это решение подходит.
mikoop
Это не ответ, а насмешка над человеком, задающим вопрос.
bhuvin