Skip to content

Latest commit

 

History

History
1479 lines (1233 loc) · 51.2 KB

02 环境准备.md

File metadata and controls

1479 lines (1233 loc) · 51.2 KB

第一步,用 Root 用户登录 Linux 系统,并创建普通用户。

一般来说,一个项目会由多个开发人员协作完成,为了节省企业成本,公司不会给每个开发人员都配备一台服务器,而是让所有开发人员共用一个开发机,通过普通用户登录开发机进行开发。因此,为了模拟真实的企业开发环境,我们也通过一个普通用户的身份来进行项目的开发,创建方法如下:


# useradd going # 创建 going 用户,通过 going 用户登录开发机进行开发
# passwd going # 设置密码
Changing password for user going.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

不仅如此,使用普通用户登录和操作开发机也可以保证系统的安全性,这是一个比较好的习惯,所以我们在日常开发中也要尽量避免使用 Root 用户。

第二步,添加 sudoers。 我们知道很多时候,普通用户也要用到 Root 的一些权限,但 Root 用户的密码一般是由系统管理员维护并定期更改的,每次都向管理员询问密码又很麻烦。因此,我建议你将普通用户加入到 sudoers 中,这样普通用户就可以通过 sudo 命令来暂时获取 Root 的权限。具体来说,你可以执行如下命令添加:

# sed -i '/^root.*ALL=(ALL).*ALL/a\going\tALL=(ALL) \tALL' /etc/sudoers
# or
# sudo sed -i '/^root.*ALL=(ALL:ALL).*ALL/a\going\tALL=(ALL:ALL) \tALL' /etc/sudoers

第三步,用新的用户名(going)和密码登录 Linux 服务器。这一步也可以验证普通用户是否创建成功。

第四步,配置 $HOME/.bashrc 文件。 我们登录新服务器后的第一步就是配置 $HOME/.bashrc 文件,以使 Linux 登录 shell 更加易用,例如配置 LANG 解决中文乱码,配置 PS1 可以避免整行都是文件路径,并将 $HOME/bin 加入到 PATH 路径中。配置后的内容如下:

# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific environment
# Basic envs
export LANG="en_US.UTF-8" # 设置系统语言为 en_US.UTF-8,避免终端出现中文乱码
export PS1='[\u@dev \W]\$ ' # 默认的 PS1 设置会展示全部的路径,为了防止过长,这里只展示:"用户名@dev 最后的目录名"
export WORKSPACE="$HOME/workspace" # 设置工作目录
export PATH=$HOME/bin:$PATH # 将 $HOME/bin 目录加入到 PATH 变量中

# Default entry folder
cd $WORKSPACE # 登录系统,默认进入 workspace 目录

# User specific environment
# Basic envs
export LANG="en_US.UTF-8" # 设置系统语言为 en_US.UTF-8,避免终端出现中文乱码
export PS1='[\u@dev \W]\$ ' # 默认的 PS1 设置会展示全部的路径,为了防止过长,这里只展示:"用户名@dev 最后的目录名"
export WORKSPACE="$HOME/workspace" # 设置工作目录
export PATH=$HOME/bin:$PATH # 将 $HOME/bin 目录加入到 PATH 变量中

# Default entry folder
cd $WORKSPACE # 登录系统,默认进入 workspace 目录

有一点需要我们注意,在 export PATH 时,最好把 $PATH 放到最后,因为我们添加到目录中的命令是期望被优先搜索并使用的。配置完 $HOME/.bashrc 后,我们还需要创建工作目录 workspace。将工作文件统一放在 $HOME/workspace 目录中,有几点好处。

  • 可以使我们的$HOME 目录保持整洁,便于以后的文件查找和分类。
  • 如果哪一天 /分区空间不足,可以将整个 workspace 目录 mv 到另一个分区中,并在 /分区中保留软连接,例如:/home/going/workspace -> /data/workspace/。
  • 如果哪天想备份所有的工作文件,可以直接备份 workspace。

具体的操作指令是$ mkdir -p $HOME/workspace。配置好 $HOME/.bashrc 文件后,我们就可以执行 bash 命令将配置加载到当前 shell 中了。

[Option] 安装 zsh set dev environment using zsh

WSL2 搭建 Windows 更好用的前端开发环境
🧑🏻‍💻 Windows 我一直认为并不适合一些方向的开发,尤其 frontend/server,没有 bash 和好用的终端。不过巨硬从 Win10 开始引入 WSL(Windows Linux 子系统),到后面的 Windows Terminal,都对开发者更加友好。我平常 Mac/Windows 会切着用,服务器是 CentOS/Ubuntu,之前经常做一些前端基础设施的搭建,目前 WSL 的这套配置:Ubuntu、zsh/oh-my/zsh、n/node/npm、Windows Terminal、VSCode...用着还是很舒服的,所以分享下最佳实践~

配置脚本:setup-wsl-for-frontend.sh


前提
Windows 10 2004 或 Windows 11 可以直接用wsl指令安装,如果是之前的系统就要手动安装,参考旧版 WSL 的手动安装步骤。

官方文档:https://learn.microsoft.com/zh-cn/windows/wsl/install
Ubuntu
右键开始菜单,以管理员身份打开命令行或 Powershell,然后输入:

wsl --install

安装完成后需要重启电脑。默认会安装 Ubuntu,如果想安装其他 Linux 系统的话,可以先wsl —list —online列出可用的系统,然后wsl —install -d <Distribution Name>安装对应系统。



用户名和密码
装好之后,在开始菜单找到 Ubuntu 并打开,第一次是需要设置用户名和密码的,这个用户名密码也是具备管理员sudo权限的。

zsh/oh-my-zsh
zsh 比 bash 更加强大也更好看,配合 oh-my-zsh 和相关插件,可以实现命令高亮、命令补全、git 快捷操作等等。

# 更新 package
sudo apt update && sudo apt upgrade

# 安装 zsh
sudo apt install zsh -y

# 安装 oh-my-zsh
wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true

# 安装命令补全和高亮插件
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.oh-my-zsh/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/plugins/zsh-autosuggestions
sed -i 's/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting)/g' ~/.zshrc

# 将 zsh 设置为默认的shell
chsh -s /bin/zsh


配置好之后下次打开默认就是 zsh 了,也可以输入zsh进入 zsh 环境。另外,我会在 zsh 的配置文件中设置一些常用的指令。编辑配置文件vim .zshrc,不习惯 vim 的话,可以用 VSCode 打开code .zshrc,在最后加入:

# 列表形式显示所有文件详情
alias ll="ls -alF"
# 删除文件前需确认
alias rm="rm -i"

Git
Git 默认会忽略大小写,很多人都遇到过这个坑,所以最好配环境的时候配好:

# 启用大小写敏感
git config --global core.ignorecase false

剩下的就是常规配置了,比如用户名和邮箱、生成 public key 等等:

# 配置用户名和密码
git config --global user.name "Your Name"
git config --global user.email "[email protected]"

# 生成 ssh key
# 用 Github 的话,可以拷贝生成的公钥到 https://github.com/settings/keys
ssh-keygen

n/node/npm
n 是一个 Node.js 的多版本管理工具,由于不同的项目可能用到不同的 Node 版本,所以用 n 的就可以很方便地切换。

# 安装 n
curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n | sudo bash -s lts
sudo npm install -g n

安装好之后输入n指令,就可以看到当前已安装的 Node.js 版本列表,需要哪个版本选择切换就行。接下来安装一些常用的 Node 工具,比如yarn、http-server(静态服务器)、figlet-cli(每次 zsh 启动的时候显示酷炫的 ASCII 字符):

sudo npm install -g yarn http-server figlet-cli

vim .zshrc
# 编辑zsh配置文件,在最后添加:figlet "Hi, arthur"
source .zshrc

Windows Terminal
Windows Terminal 是巨硬搞的一个好看又好用的终端,Windows 10 18362/11 自带,如果没有的话,可以在商店中安装。

Ubuntu 的 WSL 装好后,在 Windows Terminal 的新建选项卡里就已经有了。如果经常在 WSL 里开发的话,可以将 Ubuntu 设置为默认:



VSCode
在 VSCode 中安装Remote Development插件就能在 VSCode 中直接将 WSL 作为开发环境,非常方便:



另外如果目录是存储在 WSL 下面,那么在 Windows 下用 VSCode 打开这个目录的时候就会提示让你在 WSL 环境下打开:



文件系统
需要注意的是我们现在有了两套系统,两者的文件类型并不一致,跨系统访问和传输文件的话效率会下降很多,最好各存各的,以用户目录为例:

如果在 Windows 上开发,就将文件放在:C:\Users\<UserName>\
如果在 Ubuntu 上开发,就将文件放在:\\wsl$\ubuntu\home\<UserName>\
想在 WSL 里用资源管理器打开目录的话,可以输入explorer.exe .。另外,Windows 的文件路径在 Ubuntu 上会挂载到/mnt/,比如在 WSL 里访问 Windows C 盘的用户目录就是cd /mnt/c/Users/<UserName>/。

运行多个 Linux 发行版
WSL 理论上支持安装运行任意多个不同的 Linux 发行版,比如我再安装一个Debian:

wsl --install -d Debian

使用时可以在不同的发行版之间切换,可以用wsl --list来查看已安装的发行版,当然新的环境需要重新配置。



卸载
每个发行版可以理解为都是独立的系统,一旦卸载,所有数据/软件/设置都会删除,所以要提前将数据拷贝到 Windows 目录哦。卸载的话很简单:

# 比如卸载Ubuntu:wsl --unregister Ubuntu
wsl --unregister <DistributionName>

通常一台 Windows 电脑上配一个 WSL 环境足够,配置好之后基本不会去动它。现在我们就既能使用 Windows 的强大生态和兼容性,又能有性能不错的 Linux shell 环境。

.zshrc 完整配置

# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME="robbyrussell"

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"

# Uncomment one of the following lines to change the auto-update behavior
# zstyle ':omz:update' mode disabled  # disable automatic updates
# zstyle ':omz:update' mode auto      # update automatically without asking
# zstyle ':omz:update' mode reminder  # just remind me to update when it's time

# Uncomment the following line to change how often to auto-update (in days).
# zstyle ':omz:update' frequency 13

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS="true"

# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"

# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"

# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
# HIST_STAMPS="mm/dd/yyyy"

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder

# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)

source $ZSH/oh-my-zsh.sh

# User configuration

# export MANPATH="/usr/local/man:$MANPATH"

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
#   export EDITOR='vim'
# else
#   export EDITOR='mvim'
# fi

# Compilation flags
# export ARCHFLAGS="-arch x86_64"

# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"

# User specific environment
# Basic envs
export LANG="en_US.UTF-8" # 设置系统语言为 en_US.UTF-8,避免终端出现中文乱码
#export PS1='[\u@dev \W]\$ ' # 默认的 PS1 设置会展示全部的路径,为了防止过长,这里只展示:"用户名@dev 最后的目录名"
export WORKSPACE="$HOME/workspace" # 设置工作目录
export PATH=$HOME/bin:$PATH # 将 $HOME/bin 目录加入到 PATH 变量中

# Go envs
export GOVERSION=go1.22.0 #go1.18.3 #go1.20.6 # Go 版本设置
export GO_INSTALL_DIR=$HOME/go # Go 安装目录
export GOROOT=$GO_INSTALL_DIR/$GOVERSION # GOROOT 设置
export GOPATH=$WORKSPACE/golang # GOPATH 设置
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH # 将 Go 语言自带的和通过 go install 安装的二进制文件加入到 PATH 路径中
export GO111MODULE="on" # 开启 Go moudles 特性
export GOPROXY=https://goproxy.cn,direct # 安装 Go 模块时,代理服务器设置
export GOPRIVATE=
export GOSUMDB=off # 关闭校验 Go 依赖包的哈希值

# node
export PATH=/usr/bin/node:$PATH

# alias
## kubernetes
alias kctx=kubectx
alias kns=kubens
alias kubectl='kubecolor'
alias k=kubectl
alias kg='kubecolor get'
alias kd='kubecolor delete'
alias kdes='kubecolor describe'
alias ka='kubecolor apply'
alias kei='kubectl exec -it'
alias ktree='kubectl tree'
alias kl='kubectl logs'
alias klf='kubectl logs -f'

# docker
alias dp='docker ps'
alias dei='docker exec -it'
alias dia='docker iamges -a'
alias dlf='docker logs -f'

# git
alias gs='git status'
alias gd='git diff'
alias ga='git add .'
alias gc='git commit'
alias gagc='git add . && git commit'
alias gpo='git push origin'
alias gagcane='git add . && git commit --amend --no-edit'

git() {
  if [ $# -gt 0 ] && [[ "$1" == "commit" ]] ; then
     shift
     command git commit --signoff "$@"
  else
     command git "$@"
  fi
}

function kubectl_get_info() {
    cluster=$(kubectl config current-context)
    namespace=$(kubectl config view --minify --output 'jsonpath={..namespace}')
    echo -e "\e[33mCluster: $cluster"
    echo -e "Namespace: $namespace\e[0m"
    #kubectl get pod "$@"
}

alias kci="kubectl_get_info"
. "$HOME/.cargo/env"
export PATH=/usr/bin/zsh:$PATH

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
source <(kompose completion zsh)

依赖安装和配置 在 Linux 系统上安装 IAM 系统会依赖一些 RPM 包和工具,有些是直接依赖,有些是间接依赖。为了避免后续的操作出现依赖错误,例如,因为包不存在而导致的编译、命令执行错误等,我们先统一依赖安装和配置。安装和配置步骤如下。 第一步,安装依赖。 首先,我们在 CentOS 系统上通过 yum 命令来安装所需工具的依赖,安装命令如下:

$ sudo yum -y install make autoconf automake cmake perl-CPAN libcurl-devel libtool gcc gcc-c++ glibc-headers zlib-devel git-lfs telnet ctags lrzsz jq expat-devel openssl-devel

如果是ubuntu安装如下所需依赖:

sudo apt-get update
sudo apt-get install -y \
    make \
    autoconf \
    automake \
    cmake \
    perl \
    libcurl4-gnutls-dev \
    libtool \
    gcc \
    g++ \
    libssl-dev \
    git-lfs \
    telnet \
    ctags \
    lrzsz \
    jq \
    libexpat1-dev \
    zlib1g-dev
sudo apt-get install -y tcl-dev tk-dev
sudo apt-get install -y gettext

虽然有些 CentOS 8.2 系统已经默认安装这些依赖了,但是为了确保它们都能被安装,我仍然会尝试安装一遍。如果系统提示 Package xxx is already installed.,说明已经安装好了,你直接忽略即可。 第二步,安装 Git。 因为安装 IAM 系统、执行 go get 命令、安装 protobuf 工具等都是通过 Git 来操作的,所以接下来我们还需要安装 Git。由于低版本的 Git 不支持--unshallow 参数,而 go get 在安装 Go 包时会用到 git fetch --unshallow 命令,因此我们要确保安装一个高版本的 Git,具体的安装方法如下:


$ cd /tmp
$ wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.30.2.tar.gz
$ tar -xvzf git-2.30.2.tar.gz
$ cd git-2.30.2/
$ ./configure
$ make
$ sudo make install
$ git --version          # 输出 git 版本号,说明安装成功
git version 2.30.2

注意啦,按照上面的步骤安装好之后,我们要把 Git 的二进制目录添加到 PATH 路径中,不然 Git 可能会因为找不到一些命令而报错。你可以通过执行以下命令添加目录:

tee -a $HOME/.bashrc <<'EOF'
# Configure for git
export PATH=/usr/local/libexec/git-core:$PATH
EOF

第三步,配置 Git。我们直接执行如下命令配置 Git:

$ git config --global user.name "Lingfei Kong"    # 用户名改成自己的
$ git config --global user.email "[email protected]"    # 邮箱改成自己的
$ git config --global credential.helper store    # 设置 Git,保存用户名和密码
$ git config --global core.longpaths true # 解决 Git 中 'Filename too long' 的错误

除了按照上述步骤配置 Git 之外,我们还有几点需要注意。首先,在 Git 中,我们会把非 ASCII 字符叫做 Unusual 字符。这类字符在 Git 输出到终端的时候默认是用 8 进制转义字符输出的(以防乱码),但现在的终端多数都支持直接显示非 ASCII 字符,所以我们可以关闭掉这个特性,具体的命令如下:


$ git config --global core.quotepath off

其次,如果你觉得访问 github.com 太慢,可以通过国内 GitHub 镜像网站来访问,配置方法如下:


$ git config --global url."https://github.com.cnpmjs.org/".insteadOf "https://github.com/"

这里你要注意,通过镜像网站访问仅对 HTTPS 协议生效,对 SSH 协议不生效,并且 github.com.cnpmjs.org 的同步时间间隔为 1 天。最后,GitHub 限制最大只能克隆 100M 的单个文件,为了能够克隆大于 100M 的文件,我们还需要安装 Git Large File Storage,安装方式如下:


$ git lfs install --skip-repo

Go 编译环境安装和配置

我们知道,Go 是一门编译型语言,所以在部署 IAM 系统之前,我们需要将代码编译成可执行的二进制文件。因此我们需要安装 Go 编译环境。 除了 Go,我们也会用 gRPC 框架展示 RPC 通信协议的用法,所以我们也需要将 ProtoBuf 的.proto 文件编译成 Go 语言的接口。因此,我们也需要安装 ProtoBuf 的编译环境。

Go 编译环境安装和配置

安装 Go 语言相对来说比较简单,我们只需要下载源码包、设置相应的环境变量即可。首先,我们从 Go 语言官方网站下载对应的 Go 安装包以及源码包,这里我下载的是 go1.22.0 版本:


$ wget https://golang.google.cn/dl/go1.22.0.linux-amd64.tar.gz -O /tmp/go1.22.0.linux-amd64.tar.gz

接着,我们完成解压和安装,命令如下:


$ mkdir -p $HOME/go
$ tar -xvzf /tmp/go1.22.0.linux-amd64.tar.gz -C $HOME/go
$ mv $HOME/go/go $HOME/go/go1.22.0

最后,我们执行以下命令,将下列环境变量追加到$HOME/.bashrc 文件中。


tee -a $HOME/.bashrc <<'EOF'
# Go envs
export GOVERSION=go1.22.0 # Go 版本设置
export GO_INSTALL_DIR=$HOME/go # Go 安装目录
export GOROOT=$GO_INSTALL_DIR/$GOVERSION # GOROOT 设置
export GOPATH=$WORKSPACE/golang # GOPATH 设置
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH # 将 Go 语言自带的和通过 go install 安装的二进制文件加入到 PATH 路径中
export GO111MODULE="on" # 开启 Go moudles 特性
export GOPROXY=https://goproxy.cn,direct # 安装 Go 模块时,代理服务器设置
export GOPRIVATE=
export GOSUMDB=off # 关闭校验 Go 依赖包的哈希值
EOF

为什么要增加这么多环境变量呢?这是因为,Go 语言是通过一系列的环境变量来控制 Go 编译器行为的。因此,我们一定要理解每一个环境变量的含义。

因为 Go 以后会用 Go modules 来管理依赖,所以我建议你将 GO111MODULE 设置为 on。 在使用模块的时候,$GOPATH 是无意义的,不过它还是会把下载的依赖储存在 $GOPATH/pkg/mod 目录中,也会把 go install 的二进制文件存放在 $GOPATH/bin 目录中。

另外,我们还要将$GOPATH/bin、$GOROOT/bin 加入到 Linux 可执行文件搜索路径中。这样一来,我们就可以直接在 bash shell 中执行 go 自带的命令,以及通过 go install 安装的命令。

最后就是进行测试了,如果我们执行 go version 命令可以成功输出 Go 的版本,就说明 Go 编译环境安装成功。具体的命令如下:


$ bash
$ go version
go version go1.22.0 linu x/amd64

choosing-a-different-version-of-go-in-vscode

// Choosing a different version of Go
The extension chooses the go command using the PATH (or Path) environment variable by default. You can configure the extension to choose a different version of go with one of the following options.

(Preferred) Adjust your PATH or Path environment variable, and open VS Code with the adjusted environment variable, or
Use the Go extension's "Go: Choose Go Environment" command that opens a menu to change the go version, or
Use the "go.alternateTools" settings and specify the absolute path to the go command. "go.alternateTools": { "go": "/path/to/go/command" }

ProtoBuf 编译环境安装

接着,我们再来安装 protobuf 的编译器 protoc。protoc 需要 protoc-gen-go 来完成 Go 语言的代码转换,因此我们需要安装 protoc 和 protoc-gen-go 这 2 个工具。它们的安装方法比较简单,你直接看我下面给出的代码和操作注释就可以了。


# 第一步:安装 protobuf
$ cd /tmp/
$ git clone --depth=1 https://github.com/protocolbuffers/protobuf
$ cd protobuf
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ protoc --version # 查看 protoc 版本,成功输出版本号,说明安装成功
libprotoc 3.15.6

# 第二步:安装 protoc-gen-go
$ go get -u github.com/golang/protobuf/protoc-gen-go

当你第一次执行 go get 命令的时候,因为本地无缓存,所以需要下载所有的依赖模块。因此安装速度会比较慢,请你耐心等待。

笔记

安装protoc的其他方式
way2: install from web page#
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.1/protoc-21.1-linux-x86_64.zip

unzip protoc-21.1-linux-x86_64.zip

cd bin/

mv protoc /usr/bin

echo $PATH

mv protoc /usr/bin

$ protoc --version
libprotoc 3.14.0

install docker

// install.sh
- Log into your Linux machine.
- Download the required script with the command curl -fsSL https://get.docker.com -o install-docker.sh.
- Give the new script executable permissions with chmod u+x install-docker.sh.
- Run the script with the command sudo./install-docker.sh.

> Alternatively, you can download the Docker quick & easy install script using curl or wget2.
// install.sh


- Log into your Linux machine.
- Download the required script with the command curl -fsSL https://get.docker.com -o install-docker.sh.
- Give the new script executable permissions with chmod u+x install-docker.sh.
- Run the script with the command sudo./install-docker.sh.

> Alternatively, you can download the Docker quick & easy install script using curl or wget2.
#!/bin/sh
set -e
# Docker Engine for Linux installation script.
#
# This script is intended as a convenient way to configure docker's package
# repositories and to install Docker Engine, This script is not recommended
# for production environments. Before running this script, make yourself familiar
# with potential risks and limitations, and refer to the installation manual
# at https://docs.docker.com/engine/install/ for alternative installation methods.
#
# The script:
#
# - Requires `root` or `sudo` privileges to run.
# - Attempts to detect your Linux distribution and version and configure your
#   package management system for you.
# - Doesn't allow you to customize most installation parameters.
# - Installs dependencies and recommendations without asking for confirmation.
# - Installs the latest stable release (by default) of Docker CLI, Docker Engine,
#   Docker Buildx, Docker Compose, containerd, and runc. When using this script
#   to provision a machine, this may result in unexpected major version upgrades
#   of these packages. Always test upgrades in a test environment before
#   deploying to your production systems.
# - Isn't designed to upgrade an existing Docker installation. When using the
#   script to update an existing installation, dependencies may not be updated
#   to the expected version, resulting in outdated versions.
#
# Source code is available at https://github.com/docker/docker-install/
#
# Usage
# ==============================================================================
#
# To install the latest stable versions of Docker CLI, Docker Engine, and their
# dependencies:
#
# 1. download the script
#
#   $ curl -fsSL https://get.docker.com -o install-docker.sh
#
# 2. verify the script's content
#
#   $ cat install-docker.sh
#
# 3. run the script with --dry-run to verify the steps it executes
#
#   $ sh install-docker.sh --dry-run
#
# 4. run the script either as root, or using sudo to perform the installation.
#
#   $ sudo sh install-docker.sh
#
# Command-line options
# ==============================================================================
#
# --version <VERSION>
# Use the --version option to install a specific version, for example:
#
#   $ sudo sh install-docker.sh --version 23.0
#
# --channel <stable|test>
#
# Use the --channel option to install from an alternative installation channel.
# The following example installs the latest versions from the "test" channel,
# which includes pre-releases (alpha, beta, rc):
#
#   $ sudo sh install-docker.sh --channel test
#
# Alternatively, use the script at https://test.docker.com, which uses the test
# channel as default.
#
# --mirror <Aliyun|AzureChinaCloud>
#
# Use the --mirror option to install from a mirror supported by this script.
# Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and
# "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example:
#
#   $ sudo sh install-docker.sh --mirror AzureChinaCloud
#
# ==============================================================================


# Git commit from https://github.com/docker/docker-install when
# the script was uploaded (Should only be modified by upload job):
SCRIPT_COMMIT_SHA="6d9743e9656cc56f699a64800b098d5ea5a60020"

# strip "v" prefix if present
VERSION="${VERSION#v}"

# The channel to install from:
#   * stable
#   * test
#   * edge (deprecated)
#   * nightly (deprecated)
DEFAULT_CHANNEL_VALUE="stable"
if [ -z "$CHANNEL" ]; then
	CHANNEL=$DEFAULT_CHANNEL_VALUE
fi

DEFAULT_DOWNLOAD_URL="https://download.docker.com"
if [ -z "$DOWNLOAD_URL" ]; then
	DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL
fi

DEFAULT_REPO_FILE="docker-ce.repo"
if [ -z "$REPO_FILE" ]; then
	REPO_FILE="$DEFAULT_REPO_FILE"
fi

mirror=''
DRY_RUN=${DRY_RUN:-}
while [ $# -gt 0 ]; do
	case "$1" in
		--channel)
			CHANNEL="$2"
			shift
			;;
		--dry-run)
			DRY_RUN=1
			;;
		--mirror)
			mirror="$2"
			shift
			;;
		--version)
			VERSION="${2#v}"
			shift
			;;
		--*)
			echo "Illegal option $1"
			;;
	esac
	shift $(( $# > 0 ? 1 : 0 ))
done

case "$mirror" in
	Aliyun)
		DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce"
		;;
	AzureChinaCloud)
		DOWNLOAD_URL="https://mirror.azure.cn/docker-ce"
		;;
	"")
		;;
	*)
		>&2 echo "unknown mirror '$mirror': use either 'Aliyun', or 'AzureChinaCloud'."
		exit 1
		;;
esac

case "$CHANNEL" in
	stable|test)
		;;
	edge|nightly)
		>&2 echo "DEPRECATED: the $CHANNEL channel has been deprecated and is no longer supported by this script."
		exit 1
		;;
	*)
		>&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test."
		exit 1
		;;
esac

command_exists() {
	command -v "$@" > /dev/null 2>&1
}

# version_gte checks if the version specified in $VERSION is at least the given
# SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success)
# if $VERSION is either unset (=latest) or newer or equal than the specified
# version, or returns 1 (fail) otherwise.
#
# examples:
#
# VERSION=23.0
# version_gte 23.0  // 0 (success)
# version_gte 20.10 // 0 (success)
# version_gte 19.03 // 0 (success)
# version_gte 21.10 // 1 (fail)
version_gte() {
	if [ -z "$VERSION" ]; then
			return 0
	fi
	eval version_compare "$VERSION" "$1"
}

# version_compare compares two version strings (either SemVer (Major.Minor.Path),
# or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer
# or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release
# (-alpha/-beta) are not taken into account
#
# examples:
#
# version_compare 23.0.0 20.10 // 0 (success)
# version_compare 23.0 20.10   // 0 (success)
# version_compare 20.10 19.03  // 0 (success)
# version_compare 20.10 20.10  // 0 (success)
# version_compare 19.03 20.10  // 1 (fail)
version_compare() (
	set +x

	yy_a="$(echo "$1" | cut -d'.' -f1)"
	yy_b="$(echo "$2" | cut -d'.' -f1)"
	if [ "$yy_a" -lt "$yy_b" ]; then
		return 1
	fi
	if [ "$yy_a" -gt "$yy_b" ]; then
		return 0
	fi
	mm_a="$(echo "$1" | cut -d'.' -f2)"
	mm_b="$(echo "$2" | cut -d'.' -f2)"

	# trim leading zeros to accommodate CalVer
	mm_a="${mm_a#0}"
	mm_b="${mm_b#0}"

	if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; then
		return 1
	fi

	return 0
)

is_dry_run() {
	if [ -z "$DRY_RUN" ]; then
		return 1
	else
		return 0
	fi
}

is_wsl() {
	case "$(uname -r)" in
	*microsoft* ) true ;; # WSL 2
	*Microsoft* ) true ;; # WSL 1
	* ) false;;
	esac
}

is_darwin() {
	case "$(uname -s)" in
	*darwin* ) true ;;
	*Darwin* ) true ;;
	* ) false;;
	esac
}

deprecation_notice() {
	distro=$1
	distro_version=$2
	echo
	printf "\033[91;1mDEPRECATION WARNING\033[0m\n"
	printf "    This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version"
	echo   "    No updates or security fixes will be released for this distribution, and users are recommended"
	echo   "    to upgrade to a currently maintained version of $distro."
	echo
	printf   "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue."
	echo
	sleep 10
}

get_distribution() {
	lsb_dist=""
	# Every system that we officially support has /etc/os-release
	if [ -r /etc/os-release ]; then
		lsb_dist="$(. /etc/os-release && echo "$ID")"
	fi
	# Returning an empty string here should be alright since the
	# case statements don't act unless you provide an actual value
	echo "$lsb_dist"
}

echo_docker_as_nonroot() {
	if is_dry_run; then
		return
	fi
	if command_exists docker && [ -e /var/run/docker.sock ]; then
		(
			set -x
			$sh_c 'docker version'
		) || true
	fi

	# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output
	echo
	echo "================================================================================"
	echo
	if version_gte "20.10"; then
		echo "To run Docker as a non-privileged user, consider setting up the"
		echo "Docker daemon in rootless mode for your user:"
		echo
		echo "    dockerd-rootless-setuptool.sh install"
		echo
		echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode."
		echo
	fi
	echo
	echo "To run the Docker daemon as a fully privileged service, but granting non-root"
	echo "users access, refer to https://docs.docker.com/go/daemon-access/"
	echo
	echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent"
	echo "         to root access on the host. Refer to the 'Docker daemon attack surface'"
	echo "         documentation for details: https://docs.docker.com/go/attack-surface/"
	echo
	echo "================================================================================"
	echo
}

# Check if this is a forked Linux distro
check_forked() {

	# Check for lsb_release command existence, it usually exists in forked distros
	if command_exists lsb_release; then
		# Check if the `-u` option is supported
		set +e
		lsb_release -a -u > /dev/null 2>&1
		lsb_release_exit_code=$?
		set -e

		# Check if the command has exited successfully, it means we're in a forked distro
		if [ "$lsb_release_exit_code" = "0" ]; then
			# Print info about current distro
			cat <<-EOF
			You're using '$lsb_dist' version '$dist_version'.
			EOF

			# Get the upstream release info
			lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]')
			dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]')

			# Print info about upstream distro
			cat <<-EOF
			Upstream release is '$lsb_dist' version '$dist_version'.
			EOF
		else
			if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then
				if [ "$lsb_dist" = "osmc" ]; then
					# OSMC runs Raspbian
					lsb_dist=raspbian
				else
					# We're Debian and don't even know it!
					lsb_dist=debian
				fi
				dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
				case "$dist_version" in
					12)
						dist_version="bookworm"
					;;
					11)
						dist_version="bullseye"
					;;
					10)
						dist_version="buster"
					;;
					9)
						dist_version="stretch"
					;;
					8)
						dist_version="jessie"
					;;
				esac
			fi
		fi
	fi
}

do_install() {
	echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA"

	if command_exists docker; then
		cat >&2 <<-'EOF'
			Warning: the "docker" command appears to already exist on this system.

			If you already have Docker installed, this script can cause trouble, which is
			why we're displaying this warning and provide the opportunity to cancel the
			installation.

			If you installed the current Docker package using this script and are using it
			again to update Docker, you can safely ignore this message.

			You may press Ctrl+C now to abort this script.
		EOF
		( set -x; sleep 20 )
	fi

	user="$(id -un 2>/dev/null || true)"

	sh_c='sh -c'
	if [ "$user" != 'root' ]; then
		if command_exists sudo; then
			sh_c='sudo -E sh -c'
		elif command_exists su; then
			sh_c='su -c'
		else
			cat >&2 <<-'EOF'
			Error: this installer needs the ability to run commands as root.
			We are unable to find either "sudo" or "su" available to make this happen.
			EOF
			exit 1
		fi
	fi

	if is_dry_run; then
		sh_c="echo"
	fi

	# perform some very rudimentary platform detection
	lsb_dist=$( get_distribution )
	lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"

	if is_wsl; then
		echo
		echo "WSL DETECTED: We recommend using Docker Desktop for Windows."
		echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/"
		echo
		cat >&2 <<-'EOF'

			You may press Ctrl+C now to abort this script.
		EOF
		( set -x; sleep 20 )
	fi

	case "$lsb_dist" in

		ubuntu)
			if command_exists lsb_release; then
				dist_version="$(lsb_release --codename | cut -f2)"
			fi
			if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
				dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
			fi
		;;

		debian|raspbian)
			dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
			case "$dist_version" in
				12)
					dist_version="bookworm"
				;;
				11)
					dist_version="bullseye"
				;;
				10)
					dist_version="buster"
				;;
				9)
					dist_version="stretch"
				;;
				8)
					dist_version="jessie"
				;;
			esac
		;;

		centos|rhel)
			if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
				dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
			fi
		;;

		*)
			if command_exists lsb_release; then
				dist_version="$(lsb_release --release | cut -f2)"
			fi
			if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
				dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
			fi
		;;

	esac

	# Check if this is a forked Linux distro
	check_forked

	# Print deprecation warnings for distro versions that recently reached EOL,
	# but may still be commonly used (especially LTS versions).
	case "$lsb_dist.$dist_version" in
		debian.stretch|debian.jessie)
			deprecation_notice "$lsb_dist" "$dist_version"
			;;
		raspbian.stretch|raspbian.jessie)
			deprecation_notice "$lsb_dist" "$dist_version"
			;;
		ubuntu.xenial|ubuntu.trusty)
			deprecation_notice "$lsb_dist" "$dist_version"
			;;
		ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic)
			deprecation_notice "$lsb_dist" "$dist_version"
			;;
		fedora.*)
			if [ "$dist_version" -lt 36 ]; then
				deprecation_notice "$lsb_dist" "$dist_version"
			fi
			;;
	esac

	# Run setup for each distro accordingly
	case "$lsb_dist" in
		ubuntu|debian|raspbian)
			pre_reqs="apt-transport-https ca-certificates curl"
			apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL"
			(
				if ! is_dry_run; then
					set -x
				fi
				$sh_c 'apt-get update -qq >/dev/null'
				$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null"
				$sh_c 'install -m 0755 -d /etc/apt/keyrings'
				$sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc"
				$sh_c "chmod a+r /etc/apt/keyrings/docker.asc"
				$sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list"
				$sh_c 'apt-get update -qq >/dev/null'
			)
			pkg_version=""
			if [ -n "$VERSION" ]; then
				if is_dry_run; then
					echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
				else
					# Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel
					pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')"
					search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"
					pkg_version="$($sh_c "$search_command")"
					echo "INFO: Searching repository for VERSION '$VERSION'"
					echo "INFO: $search_command"
					if [ -z "$pkg_version" ]; then
						echo
						echo "ERROR: '$VERSION' not found amongst apt-cache madison results"
						echo
						exit 1
					fi
					if version_gte "18.09"; then
							search_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"
							echo "INFO: $search_command"
							cli_pkg_version="=$($sh_c "$search_command")"
					fi
					pkg_version="=$pkg_version"
				fi
			fi
			(
				pkgs="docker-ce${pkg_version%=}"
				if version_gte "18.09"; then
						# older versions didn't ship the cli and containerd as separate packages
						pkgs="$pkgs docker-ce-cli${cli_pkg_version%=} containerd.io"
				fi
				if version_gte "20.10"; then
						pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
				fi
				if version_gte "23.0"; then
						pkgs="$pkgs docker-buildx-plugin"
				fi
				if ! is_dry_run; then
					set -x
				fi
				$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pkgs >/dev/null"
			)
			echo_docker_as_nonroot
			exit 0
			;;
		centos|fedora|rhel)
			if [ "$(uname -m)" != "s390x" ] && [ "$lsb_dist" = "rhel" ]; then
				echo "Packages for RHEL are currently only available for s390x."
				exit 1
			fi

			if command_exists dnf; then
				pkg_manager="dnf"
				pkg_manager_flags="--best"
				config_manager="dnf config-manager"
				enable_channel_flag="--set-enabled"
				disable_channel_flag="--set-disabled"
				pre_reqs="dnf-plugins-core"
			else
				pkg_manager="yum"
				pkg_manager_flags=""
				config_manager="yum-config-manager"
				enable_channel_flag="--enable"
				disable_channel_flag="--disable"
				pre_reqs="yum-utils"
			fi

			if [ "$lsb_dist" = "fedora" ]; then
				pkg_suffix="fc$dist_version"
			else
				pkg_suffix="el"
			fi
			repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"
			(
				if ! is_dry_run; then
					set -x
				fi
				$sh_c "$pkg_manager $pkg_manager_flags install -y -q $pre_reqs"
				$sh_c "$config_manager --add-repo $repo_file_url"

				if [ "$CHANNEL" != "stable" ]; then
					$sh_c "$config_manager $disable_channel_flag 'docker-ce-*'"
					$sh_c "$config_manager $enable_channel_flag 'docker-ce-$CHANNEL'"
				fi
				$sh_c "$pkg_manager makecache"
			)
			pkg_version=""
			if [ -n "$VERSION" ]; then
				if is_dry_run; then
					echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
				else
					pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix"
					search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"
					pkg_version="$($sh_c "$search_command")"
					echo "INFO: Searching repository for VERSION '$VERSION'"
					echo "INFO: $search_command"
					if [ -z "$pkg_version" ]; then
						echo
						echo "ERROR: '$VERSION' not found amongst $pkg_manager list results"
						echo
						exit 1
					fi
					if version_gte "18.09"; then
						# older versions don't support a cli package
						search_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"
						cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)"
					fi
					# Cut out the epoch and prefix with a '-'
					pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)"
				fi
			fi
			(
				pkgs="docker-ce$pkg_version"
				if version_gte "18.09"; then
					# older versions didn't ship the cli and containerd as separate packages
					if [ -n "$cli_pkg_version" ]; then
						pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"
					else
						pkgs="$pkgs docker-ce-cli containerd.io"
					fi
				fi
				if version_gte "20.10"; then
					pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
				fi
				if version_gte "23.0"; then
						pkgs="$pkgs docker-buildx-plugin"
				fi
				if ! is_dry_run; then
					set -x
				fi
				$sh_c "$pkg_manager $pkg_manager_flags install -y -q $pkgs"
			)
			echo_docker_as_nonroot
			exit 0
			;;
		sles)
			if [ "$(uname -m)" != "s390x" ]; then
				echo "Packages for SLES are currently only available for s390x"
				exit 1
			fi
			repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"
			pre_reqs="ca-certificates curl libseccomp2 awk"
			(
				if ! is_dry_run; then
					set -x
				fi
				$sh_c "zypper install -y $pre_reqs"
				$sh_c "zypper addrepo $repo_file_url"
				if ! is_dry_run; then
						cat >&2 <<-'EOF'
						WARNING!!
						openSUSE repository (https://download.opensuse.org/repositories/security:/SELinux) will be enabled now.
						Do you wish to continue?
						You may press Ctrl+C now to abort this script.
						EOF
						( set -x; sleep 30 )
				fi
				opensuse_repo="https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/security:SELinux.repo"
				$sh_c "zypper addrepo $opensuse_repo"
				$sh_c "zypper --gpg-auto-import-keys refresh"
				$sh_c "zypper lr -d"
			)
			pkg_version=""
			if [ -n "$VERSION" ]; then
				if is_dry_run; then
					echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
				else
					pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g')"
					search_command="zypper search -s --match-exact 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'"
					pkg_version="$($sh_c "$search_command")"
					echo "INFO: Searching repository for VERSION '$VERSION'"
					echo "INFO: $search_command"
					if [ -z "$pkg_version" ]; then
						echo
						echo "ERROR: '$VERSION' not found amongst zypper list results"
						echo
						exit 1
					fi
					search_command="zypper search -s --match-exact 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'"
					# It's okay for cli_pkg_version to be blank, since older versions don't support a cli package
					cli_pkg_version="$($sh_c "$search_command")"
					pkg_version="-$pkg_version"
				fi
			fi
			(
				pkgs="docker-ce$pkg_version"
				if version_gte "18.09"; then
					if [ -n "$cli_pkg_version" ]; then
						# older versions didn't ship the cli and containerd as separate packages
						pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"
					else
						pkgs="$pkgs docker-ce-cli containerd.io"
					fi
				fi
				if version_gte "20.10"; then
					pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
				fi
				if version_gte "23.0"; then
						pkgs="$pkgs docker-buildx-plugin"
				fi
				if ! is_dry_run; then
					set -x
				fi
				$sh_c "zypper -q install -y $pkgs"
			)
			echo_docker_as_nonroot
			exit 0
			;;
		*)
			if [ -z "$lsb_dist" ]; then
				if is_darwin; then
					echo
					echo "ERROR: Unsupported operating system 'macOS'"
					echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop"
					echo
					exit 1
				fi
			fi
			echo
			echo "ERROR: Unsupported distribution '$lsb_dist'"
			echo
			exit 1
			;;
	esac
	exit 1
}

# wrapped up in a function so that we have some protection against only getting
# half the file during "curl | sh"
do_install
Memo
Highlight

Get started using Visual Studio Code with Windows Subsystem for Linux

https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode
Install VS Code and the WSL extension
Visit the VS Code install page and select the 32 or 64 bit installer. Install Visual Studio Code on Windows (not in your WSL file system).

When prompted to Select Additional Tasks during installation, be sure to check the Add to PATH option so you can easily open a folder in WSL using the code command.

Install the Remote Development extension pack. This extension pack includes the WSL extension, in addition to the Remote - SSH, and Dev Containers extensions, enabling you to open any folder in a container, on a remote machine, or in WSL.

 Important

In order to install the WSL extension, you will need the 1.35 May release version or later of VS Code. We do not recommend using WSL in VS Code without the WSL extension as you will lose support for auto-complete, debugging, linting, etc. Fun fact: this WSL extension is installed in $HOME/.vscode/extensions (enter the command ls $HOME\.vscode\extensions\ in PowerShell).

Update your Linux distribution
Some WSL Linux distributions are lacking libraries that are required by the VS Code server to start up. You can add additional libraries into your Linux distribution by using its package manager.

For example, to update Debian or Ubuntu, use:

Bash

Copy
sudo apt-get update
To add wget (to retrieve content from web servers) and ca-certificates (to allow SSL-based applications to check for the authenticity of SSL connections), enter:

Bash

Copy
sudo apt-get install wget ca-certificates
Open a WSL project in Visual Studio Code
From the command-line
To open a project from your WSL distribution, open the distribution's command line and enter: code .

install wsl with non-root user account, install code for opening project in wsl cli

https://code.visualstudio.com/docs/remote/wsl-tutorial

install wsl and vscode

PS C:\Users\shen> wsl --list --online
以下是可安装的有效分发的列表。
请使用wsl --install -d <分发>安装。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
Ubuntu-24.04                           Ubuntu 24.04 LTS
OracleLinux_7_9                        Oracle Linux 7.9
OracleLinux_8_7                        Oracle Linux 8.7
OracleLinux_9_1                        Oracle Linux 9.1
openSUSE-Leap-15.5                     openSUSE Leap 15.5
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
SUSE-Linux-Enterprise-15-SP5           SUSE Linux Enterprise 15 SP5
openSUSE-Tumbleweed                    openSUSE Tumbleweed
PS C:\Users\shen> wsl --install -d Ubuntu-20.04
Ubuntu 20.04 LTS 已安装。
正在启动 Ubuntu 20.04 LTS…
PS C:\Users\shen>

set a non-root:

Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: going
New password:
Retype new password:
passwd: password updated successfully
Installation successful!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.10.102.1-microsoft-standard-WSL2 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue May 21 18:13:47 CST 2024

  System load:  0.25               Processes:             8
  Usage of /:   0.5% of 250.98GB   Users logged in:       0
  Memory usage: 1%                 IPv4 address for eth0: 192.168.17.176
  Swap usage:   0%

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update


This message is shown once a day. To disable it please create the
/home/going/.hushlogin file.
going@DESKTOP-NR5O5ND:~$ whoami
going

install vscode plugin:

  • WSL
  • Go

Open vscode: ctrl+shift+P >connect to WSL, choose the installed distro, it will automatically install vscode server in the current user home dir

going@DESKTOP-NR5O5ND:~$ ls -al
total 32
drwxr-xr-x 5 going going 4096 May 21 18:15 .
drwxr-xr-x 3 root  root  4096 May 21 18:13 ..
-rw-r--r-- 1 going going  220 May 21 18:13 .bash_logout
-rw-r--r-- 1 going going 3771 May 21 18:13 .bashrc
drwxr-xr-x 2 going going 4096 May 21 18:13 .landscape
-rw-r--r-- 1 going going    0 May 21 18:13 .motd_shown
-rw-r--r-- 1 going going  807 May 21 18:13 .profile
drwxr-xr-x 3 going going 4096 May 21 18:15 .vscode-remote-containers
drwxr-xr-x 5 going going 4096 May 21 18:15 .vscode-server