Як встановити псевдоніми bash для контейнерів Docker у Dockerfile?


85

Я новачок у докері. Я виявив, що ми можемо встановлювати змінні середовища, використовуючи інструкцію ENV у файлі Docker. Але як можна встановити псевдоніми bash для довгих команд у Dockerfile?


Псевдоніми вважаються по суті застарілими дуже давно. Використовуйте функцію. Більше не потрібно ніколи використовувати псевдонім. Як так, що ці підходи кінця 80-х зберігаються так довго?
Вільям Персел

19
Тому що вони, звичайно, зручні та прості.
Артур,

13
@WilliamPursell Можливо, тоді вам слід пояснити, як замість цього використовувати функції.
Ерік Дела Круз,

2
Псевдоніми - прості, зручні, крихкі та схильні до помилок. Функції так само прості у використанні, але забезпечують більшу гнучкість та надійність. Доступно безліч ресурсів про те, як ними користуватися.
Вільям Перселл,

Відповіді:


141

В основному, як і завжди, додаючи його до користувацького .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

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


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
  1. відредагувати цей файл ~ / .bash_aliases vi ~/.bash_aliases
  2. джерело цього файлу ~ / .bash_aliases source ~/.bash_aliases
  3. зроблено.

Це чудово кожного разу, коли ви закручуєте контейнер докера, але псевдоніми не залишаться наступного разу. якщо ви не проти повторно додавати їх щоразу, коли це рішення буде чудовим.
mikoop

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.