Docker запустить bash --init-файл - PullRequest
1 голос
/ 20 января 2020

Я пытаюсь создать псевдоним, чтобы помочь отлаживать мои docker контейнеры.

Я обнаружил bash принимает опцию --init-file, которая должна позволить нам запустить некоторые Команды перед переходом в интерактивный режим.

Поэтому я подумал, что смогу сделать

docker-bash() {
  docker run --rm -it "$1" bash --init-file <(echo "ls; pwd")
}

Но эти команды не работают:

 % docker-bash c7460dfcab50
root@9c6f64a9db8c:/#

Is это проблема с выходом или .. что происходит?

bash --init-file <(echo "ls; pwd")

Один в терминале на моей хост-машине работает как положено (запускает команду запускает новый bash экземпляр).

Ответы [ 2 ]

2 голосов
/ 20 января 2020

В точках:

  • <(...) представляет собой bash расширение подстановка процесса .
  • Из приведенного выше руководства: Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files..
  • Подстановка процесса работает следующим образом:
    • bash создает fifo в /tmp или создает новый файловый дескриптор в /dev/fd.
    • Имя файла, либо /tmp/.something или /dev/fd/<number> заменяется на <(...) при выполнении команды.
    • Так, например, echo <(echo 1) выводит /dev/fd/63.
  • Docker работает, создавая новую среду, которая отделена от хоста. Это означает, что:
    • Процессы внутри docker не наследуют файловые дескрипторы от хост-процесса:
      • Так что /dev/fd/* файлы не наследуются.
    • Процессы внутри docker обращаются к изолированному дереву файловой системы.
      • Таким образом, процессы не могут получить доступ к /tmp/* файлам с хоста.
  • Таким образом, суммирование docker run -ti --rm alpine cat <(echo 1) не будет работать, потому что имя файла замена на <(...) недоступна в среде docker.

Простой обходной путь - просто:

docker run -ti --rm alpine sh -c 'ls; pwd; exec sh'

Или использовать временный файл:

echo "ls; pwd" > /tmp/tempfile
docker run -v /tmp/tempfile:/tmp/tempfile bash bash --init-file /tmp/tempfile
1 голос
/ 20 января 2020

Для моего варианта использования я хотел установить alias, который не будет сохраняться, если мы повторно выполним c оболочку. Однако псевдонимы могут быть записаны в ~/.bashrc, который будет перезагружен в последующем exe c. Er go,

docker-bash() {
  docker run --rm -it "$1" bash -c $'set -o xtrace; echo "alias ll=\'ls -lAhtrF --color=always\'" >> ~/.bashrc; exec "$0"'
}

Работает. --rm должен очистить любые файлы, которые мы создаем, если я правильно понимаю, как работает docker.

Или, возможно, это лучший способ написать:

docker-bash() {
read -r -d '' BASHRC << EOM
alias ll='ls -lAhtrF --color=always'
EOM
docker run --rm -it "$1" bash -c "echo \"$BASHRC\" >> ~/.bashrc; exec \"\$0\""
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...