Docker容器内的Shell颜色设置

动力

当使用SSH连接到Docker容器时,基本上颜色设置是被禁用的。然而,由于无色会降低工作效率,我们希望能够进行颜色化。但每次登陆都要设置各种颜色,如提示符、ls和grep等,这很麻烦。而且在共享项目中,经常无法随意在Dockerfile中添加颜色设置。

只需执行 docker exec 并向每个容器发送颜色设置信息,这样就可以在连接到任何容器时以喜欢的颜色设置(+其他设置)进行容器内工作,肯定会事半功倍!

路线

    1. 在主机上准备一个包含颜色设置的.bashrc文件

 

    1. 将主机的.bashrc文件复制到容器内

 

    1. 在容器中设置环境变量TERM=xterm-256color

 

    定义一个shell函数来执行以上操作的一条命令

提示符的颜色设置

如果使用bash,则在$PS1中写入显示提示符信息和颜色的设置。如果使用zsh,则在$PROMPT中写入显示提示符信息和颜色的设置。

# 例
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac
if [ "$color_prompt" = yes ]; then
    # 色設定あり
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    # 端末の256色設定が無効なら色コードは入れない
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset

参考:
自定义Bash提示符【颜色变化·时间显示】
Mac: 自定义终端和提示符(zsh)-合并相关点

列出grep命令的颜色设置选项

我会将以下内容追加到.basrhc文件中。

if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

将主机的 .bashrc 复制到容器内

可以使用docker cp命令将主机内的文件复制到容器中。由于Docker基本上是以root用户登录的,因此将.bashrc复制到root用户的主目录/root/以下。

[格式] docker cp 主机文件路径 容器名:容器内路径

# 例:
# my_service イメージから my_service という名のコンテナを立ち上げる
docker run --rm -d -p 3000:3000 --name my_service my_service

# ホストの .basrc を コンテナの /root/ にコピーする
docker cp ~/.bashrc my_service:/root/

参考来源:

如何将文件从主机传输到运行中的Docker容器- Qiita

设定 TERM=xterm-256color 在容器中。

登录容器时,如果将环境变量 $TERM 设置为 xterm-256color,终端内可使用256种颜色。

docker exec -it my_service env TERM=xterm-256color /bin/bash

我們是使用shell的env,而不是docker引數中的–env進行設定。

一条指令立即登录到彩色Shell!

将上述设置合并为一个函数,以便一次性执行。
将以下函数写入~/.bashrc。
(【附注】→ 最好将路径~/bin/添加到环境变量,并创建名为docker-ssh的shell脚本(参考评论))

docker-ssh() {
    cmd1="docker cp ~/.bashrc $1:/root/"
    echo $cmd1 && eval $cmd1 && echo 'Copied! .bashrc'
    cmd2="docker exec -it $@ env TERM=xterm-256color /bin/bash"
    echo -e "\n" $cmd2 && eval $cmd2
}

只需要在启动容器名为my_service时执行以下操作。

$ docker-ssh my_service
docker cp ~/.bashrc web:/root/
Copied! .bashrc

docker exec -it web env TERM=xterm-256color /bin/bash
image.png

在使用Docker Compose的情况下

当使用Docker Compose启动容器并进行SSH连接时,基本上是相同的。唯一的区别是需要将”compose”这个词加在中间。

# .bashrc に以下追記
docker-compose-ssh() {
    cmd1="docker compose cp ~/.bashrc $1:/root/"
    echo $cmd1 && eval $cmd1 && echo 'Copied! .bashrc'
    cmd2="docker compose exec -it $@ env TERM=xterm-256color /bin/bash"
    echo -e "\n" $cmd2 && eval $cmd2
}
# composeでコンテナ起動
docker compose up -d
# コンテナの起動状況を確認
$ docker compose ps

NAME         IMAGE      COMMAND                 SERVICE  CREATED        STATUS       PORTS
myapp-db-1   myapp-db   "docker-entrypoint.s…"  db       5 months ago   Up 5 hours   0.0.0.0:15432->5432/tcp
myapp-web-1  myapp-web  "/app/docker/web/ent…"  web      4 days ago     Up 5 hours   0.0.0.0:13000->3000/tcp

#=> 「web」 がサービス名
# webコンテナにログイン
docker-compose-ssh web
image.png

(附言)将参数转变为变量

我认为在命令行选项参数中经常使用的内容最好先进行全局变量化,这样在使用时更加方便。一开始我是这样做的:

docker-ssh() {
    export DOCKER_EXEC_OPTIONS='-it --env TERM=xterm-256color'

    docker cp ~/.bashrc $1:/root/
    docker exec $DOCKER_EXEC_OPTIONS $@ /bin/bash
}

しかし、これだと以下のようなエラーになりダメだった。

$ docker-ssh web
unknown shorthand flag: ' ' in - --env TERM=xterm-256color

因为觉得解释字符串的顺序可能是shell的问题,尝试了很多方法感到很麻烦,所以换成了eval,结果很顺利。

docker-ssh() {
    export DOCKER_EXEC_OPTIONS='-it --env TERM=xterm-256color'

    docker cp ~/.bashrc $1:/root/
    eval "docker exec $DOCKER_EXEC_OPTIONS $@ /bin/bash"  # eval で文字列をコマンドとして解釈
}

我对eval并不是很了解,但听起来不太好,所以我宁愿不使用它,希望能做到…。

请懂的人告诉我!

【附注】请在评论中详细告诉我!

广告
将在 10 秒后关闭
bannerAds