宿主机 vim 编辑 docker 容器内部文件

发布时间 2023-06-09 17:17:57作者: 心随所遇

容器所有文件,一定在宿主机某个位置。具体位置是:/proc/<container-pid>/root, 这个位置就是容器系统根目录所在的位置, 注意只有运行中的容器才有 pid,停止中的容器 pid 为 0。

查看一个容器 pid 可用命令

docker inspect -f '{{.State.Pid}}'  <container>
 
示例(注意:需要root 权限):

既然能找到文件,哪么就能用 sudo vim 或者 sudo gedit 去编辑文件了。

封装一下代码

####################################################################################
# 扩展 vim 能编辑容器中的文件
# 语法: vim <container>:/path/to/file
# 示例: vim nginx:/etc/nginx/nginx.conf
####################################################################################
function vim(){

    if [[ $# == 1 && "$1" =~ ":/"  ]];then

        local container="${1%:*}"
        local file=${1#*:/}
        local pid=$(docker inspect -f '{{.State.Pid}}' $container)
        [[ "$pid" == 0 ]] && {
            echo container $container is not running!
            return 0
        }
        sudo /usr/bin/vim /proc/$pid/root/$file

    else
        /usr/bin/vim "$@"
    fi

}


####################################################################################
# 扩展 exec 能实现 docker exec
# 语法: exec <container>:/path
# 示例: exec nginx:/etc/nginx
####################################################################################
function exec(){

    if [ $# == 1 -a -n "`echo $1 | grep -P '^\w+.*\:/'`" ]; then

        local work=(${1/:/' '}) #通过把替换成空格,从而转数组
        shift
        [ -n "$1" ] || set -- bash
        if [ -n "${work[1]}" ];then
            docker exec -it -w ${work[1]} ${work[0]} "$@"
        else
            docker exec -it ${work[0]} "$@"
        fi

    else

        builtin exec "$@"
    fi

}

####################################################################################
# 扩展 cd 能实现切换到 docker 容器中的目录
# 语法: cd <container>:/path
# 示例: cd nginx:/
# 示例: cd -down
####################################################################################
function cd(){
    # <container>:/
    if [[ $# == 1 && "$1" =~ ":/"  ]];then

        local container="${1%:*}"
        local path=${1#*:/}
        local pid=$(docker inspect -f '{{.State.Pid}}' $container)
        [[ "$pid" == 0 ]] && {
            echo container $container is not running!
            return 0
        }
        builtin cd /proc/$pid/root/$path
    else

        if [ $# == 1 -a ! -d "$1" -a "${1:0:1}" == '-' ];then

            set -- ${1:1}
            declare -A dest=(
                [src]='/d/src'
                [bin]='/d/bin'
                [desk]='/c/Users/admin/Desktop'
                [down]='/c/Users/admin/Downloads'
                [local]='/d/local'
                [xl]='/m/迅雷下载'
                [opt]='/d/opt'
                [nacos]='/d/opt/nacos'
                [keepalived]='/d/opt/keepalived'
            )

            [ -n "${dest[$1]}" ] && set -- ${dest[$1]}

        fi

        builtin cd "$@"

    fi

}