安装与配置WSL
安装WSL
-
移除WSL
# 查看已安装的WSL wsl -l -v
# 移除WSL
wsl --unregister Ubuntu-22.04
-
安装WSL ubuntu22.04
wsl --install -d Ubuntu-22.04
配置WSL
正常已经是可以免密直接登录的,只有在sudo时需要输入密码。
-
配置oh my zsh[^zsh]
# 安装oh my zsh sudo apt install zsh
# 配置oh my zsh
sh -c "$(curl -fsSL https://gitee.com/pocmon/ohmyzsh/raw/master/tools/install.sh)"
#载入配置
source ~/.zshrc
可以在win10中用ConEmu打开wsl,我不喜欢cmd命令行。
-
换源
更换为浙江大学的镜像源
# 查看系统信息 cat /etc/os-releasesudo sed -i 's@//.*archive.ubuntu.com@//mirrors.zju.edu.cn@g' /etc/apt/sources.list
配置git[^git]
-
安装git
sudo apt-get git -
配置git
git config --global user.name "XXXX" git config --global user.email XXX@XX.com -
git 的 ssh 设置[^ssh]
ssh-keygen -t ed25519 -C "xxxx@xxx.com" -
编辑 ssh 配置
# .ssh/config # GitHub.com Host github.com HostName github.com User git IdentityFile ~/.ssh/id_rsa -
测试 ssh
ssh -T git@github.com
配置代理
如果在win10主机上使用了科学上网来解决github等网站的联通性问题,则我会这样配置代理。
这是跟AI协作得到的。
-
建立 proxy.sh 配置文件
#!/bin/bash # .proxy/proxy.sh # --- 用户配置 --- # 请将这里的端口号修改为您在 Windows 上代理软件的实际端口 PROXY_PORT=10809 # --- 用户配置结束 --- # --- 自动检测 --- # 1. 从 /etc/resolv.conf 中自动获取 Windows 主机的 IP 地址 # 这是 WSL 与 Windows 网络互通的关键 WIN_IP=$(grep nameserver /etc/resolv.conf | awk '{print $2}') # 2. 拼接成完整的代理服务器 URL PROXY_URL="http://$WIN_IP:$PROXY_PORT" # 3. 检查 WIN_IP 是否为空,如果为空则无法继续 if [ -z "$WIN_IP" ]; then echo "? 无法获取 Windows 主机 IP 地址,请检查 /etc/resolv.conf 文件。" return 1 # 使用 return 可以在 source 时停止执行 fi # --- 核心逻辑 --- # 使用 nc (netcat) 工具来探测 Windows 主机上的代理端口是否开放 # -z: 表示 Zero-I/O 模式,只进行扫描,不发送任何数据 # -w1: 表示设置1秒的超时时间,如果1秒内连不上就放弃 # 2>/dev/null: 将错误输出重定向到 "黑洞",这样在端口关闭时我们就不会看到 "Connection refused" 的提示 if nc -z -w1 "$WIN_IP" "$PROXY_PORT" 2>/dev/null; then # 如果 nc 命令成功退出 (退出码为0),说明端口是开放的 echo "? 检测到代理服务开启 ( $WIN_IP:$PROXY_PORT ),正在为您设置全局代理..." # a. 设置终端环境变量 (大小写都设置以兼容不同程序) export http_proxy="$PROXY_URL" export https_proxy="$PROXY_URL" export HTTP_PROXY="$PROXY_URL" export HTTPS_PROXY="$PROXY_URL" export ALL_PROXY="$PROXY_URL" # 某些工具会使用这个变量 # b. 设置 Git 代理 git config --global http.proxy "$PROXY_URL" git config --global https.proxy "$PROXY_URL" # c. 设置 npm 代理 npm config set proxy "$PROXY_URL" npm config set https-proxy "$PROXY_URL" # d. 设置 apt 代理 (需要 sudo 权限) echo "Acquire::http::Proxy \"$PROXY_URL\";" | sudo tee /etc/apt/apt.conf.d/proxy.conf >/dev/null echo "Acquire::https::Proxy \"$PROXY_URL\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf >/dev/null echo "?? 所有代理已设置完毕! else # 如果 nc 命令失败退出 (退出码非0),说明端口是关闭的 echo "?? 未检测到代理服务,正在为您清除所有代理设置..." # a. 取消终端环境变量 unset http_proxy unset https_proxy unset HTTP_PROXY unset HTTPS_PROXY unset ALL_PROXY # b. 取消 Git 代理 git config --global --unset http.proxy git config --global --unset https.proxy # c. 取消 npm 代理 npm config delete proxy npm config delete https-proxy # d. 删除 apt 代理配置文件 (需要 sudo 权限) sudo rm -f /etc/apt/apt.conf.d/proxy.conf echo "?? 所有代理已清除,您现在将使用直接连接。" fi -
赋执行权限
chmod +x ~/.proxy/proxy.sh -
如何使用? 这一点至关重要!为了让 export 和 unset 对您当前的终端会话生效,不能直接像 sh proxy.sh 或 ./proxy.sh 这样执行它。必须使用 source 命令或者 . 命令。
-
创建别名 编辑 ~/.zshrc ,在文件的末尾添加下面这行:
# 设置网络代理的别名 alias setproxy="source ~/.proxy/proxy.sh"sudo 密码
我不想将系统密码设置得很简单,但是又不想记忆,所以我想的是设置加密保存,使用我的其他密码解密输出,实现在命令行中直接拿密码。
-
临时保存密码 先将你的真实密码保存在一个临时文件中,比如:
echo -n "MyP@ssw0rd!_123\n" > ~/.temp_pass.txt -
使用 openssl 加密 它会提示你输入并确认一个新的“主密码”。这个主密码是你用来保护真实密码的。
openssl enc -aes-256-cbc -salt -pbkdf2 -in ~/.temp_pass.txt -out ~/pathoffile
执行后,它会提示:
enter AES-256-CBC encryption password:
Verifying - enter AES-256-CBC encryption password:
在这里输入你的“主密码”(例如 MasterKey456)。
这里的密码末尾最好带上换行符,这样解密后才会有换行符。如果没有会有什么问题呢,zsh 为了防止字符不换行的时候与终端的引导符粘在一起,会在字符末尾自动添加换行,这本来是好事,但是并不多。因为 zsh 为了表示自己加了换行,提示用户注意,还会在原来字符的末尾加上一个百分号,这导致显示出来看上去密码是不对的,而且复制字面量容易出错。
-
删除临时的明文密码文件:
rm ~/.temp_pass.txt -
创建解密脚本 我们将脚本放在 ~/.local/bin/ 目录下,这是一个用于存放用户自定义命令的标准位置。
nano ~/.local/bin/pathoffile
这是 unlock 的内容
#!/bin/bash
# ~/.local/bin/unlock文件内容
# 检查用户是否提供了主密码作为参数
if [ -z "$1" ]; then
# 如果没有提供参数,就打印错误信息和用法到标准错误输出
echo "错误: 未提供主密码。" >&2
echo "用法: $(basename "$0") <主密码>" >&2
exit 1 # 以错误码退出
fi
# 从命令行第一个参数获取主密码
MASTER_PASS=$1
# 使用 openssl 解密文件
# -d 表示解密 (decrypt)
# 选项必须与加密时完全一致
# -pass pass:"$MASTER_PASS" 从变量中读取主密码
# 2>/dev/null 将任何错误信息 (如密码错误) 重定向到 "黑洞",这样错误时就不会有任何输出
# tee >(clip.exe)是将终端输出复制一份到剪贴板
openssl enc -d -aes-256-cbc -pbkdf2 -in ~/.pwd/.encrypted -pass pass:"$MASTER_PASS" 2>/dev/null | tee >(clip.exe)
自定义命令
通过给 ohmyzsh 加自定义插件的方式增加自定义命令。这的确会更有挑战性,但是更优雅。这个章节的用法有 AI 的协助。
-
建立插件目录
mkdir ~/.oh-my-zsh/custom/plugins/wsltools -
创建入口文件
# ~/.oh-my-zsh/custom/plugins/wsltools/wsltools.plugin.zsh # Get the directory where this script is located plugin_dir="${0:A:h}" # 1. Add the 'functions' subdirectory to the fpath array. # This tells Zsh WHERE to look for autoloadable functions. fpath=("$plugin_dir/functions" $fpath) # 2. Explicitly declare which functions are available for autoloading. # This tells Zsh WHAT to look for. It's a robust way to register # the function and avoids potential conflicts or environment issues. autoload -U np3 autoload -U touch -
创建函数文件
# =================================================================== # # ~/.oh-my-zsh/custom/plugins/wsltools/functions/np3 # # 函数名: np3 # # 功能: 从 WSL 内部调用 Windows 里的 Notepad3 程序来打开一个文件。 # # 特性: # - 参数检查: 确保用户提供了一个文件名作为参数。 # - 环境检查: 验证 Notepad3 的 .exe 文件是否存在且可以执行。 # - 自动创建: 如果目标文件不存在,会自动创建该文件。 # - 路径转换: 使用 wslpath 命令将 WSL 路径正确转换为 Windows 路径。 # - 后台运行: 将 Notepad3 进程在后台启动,不阻塞当前终端。 # # =================================================================== np3() { # --------------------------------------------------------------- # 1. 配置区域 # --------------------------------------------------------------- # !! 请根据你的实际情况修改此路径 !! # 这是 Notepad3.exe 在 WSL 中的访问路径 (C盘 -> /mnt/c, D盘 -> /mnt/d, 以此类推) local win_app_path="/mnt/d/Portable/WSLTools/Notepad3/Notepad3.exe" # --------------------------------------------------------------- # 2. 输入参数验证 # 检查用户是否提供了文件名。如果没有,则报错并退出。 # --------------------------------------------------------------- if [[ -z "$1" ]]; then echo "错误: 未指定文件名。" >&2 echo "用法: np3 <文件路径>" >&2 return 1 # 返回一个非零状态码,表示函数执行失败 fi # 将第一个参数赋值给 file_path 变量,使其更具可读性 local file_path="$1" # --------------------------------------------------------------- # 3. 运行环境验证 # 检查 Notepad3 的可执行文件是否存在。-x 标志检查文件是否存在且可执行。 # --------------------------------------------------------------- if [[ ! -x "$win_app_path" ]]; then echo "错误: Notepad3 可执行文件未找到或没有执行权限。" >&2 echo "请检查路径: '$win_app_path'" >&2 return 1 fi # --------------------------------------------------------------- # 4. 文件存在性检查 # 如果用户指定的文件不存在,则先创建它,避免 Notepad3 报错。 # --------------------------------------------------------------- if [[ ! -f "$file_path" ]]; then echo "文件 '$file_path' 不存在,正在为您创建..." # 使用 touch 命令安全地创建空文件 touch "$file_path" fi # --------------------------------------------------------------- # 5. 核心逻辑: 路径转换与执行 # --------------------------------------------------------------- # 使用 wslpath -w 将 WSL 路径 (例如 /home/user/test.txt) # 转换为 Windows 路径 (例如 C:\Users\user\test.txt) local win_file_path win_file_path=$(wslpath -w "$file_path") echo "正在使用 Notepad3 打开: $win_file_path" # 执行命令: # ( ... &) 将整个命令放入子 shell 并在后台运行,彻底与当前终端分离。 # nohup 确保在你关闭终端后,程序还能继续运行 (虽然对图形界面程序意义不大,但是个好习惯)。 # &> /dev/null 将标准输出和标准错误都重定向到“黑洞”,保持终端干净。 # "$win_app_path" 和 "$win_file_path" 使用双引号包裹,以处理路径中可能存在的空格。 (nohup "$win_app_path" "$win_file_path" &>/dev/null &) } -
下面是增强 touch 的函数文件
# ============================================================================== # 增强版 touch 命令 # 功能:在创建文件时,如果父目录不存在,则自动创建。 # ============================================================================== touch() { # 遍历所有传递给此函数的参数(例如 "path/to/file.txt", "-a", "-m" 等)。 # "$@" 是一个特殊的 shell 变量,代表所有传递进来的参数,并能正确处理带空格的参数。 for arg in "$@"; do # 判断参数是否为文件路径。一个简单的检查方法是看它是否以连字符(-)开头。 # 如果不是以 "-" 开头,我们就假定它是一个文件路径,而不是一个命令选项(如 -a, -m)。 if [[ "$arg" != -* ]]; then # 声明一个局部变量 dir,这样它就不会影响到函数外部的同名变量,这是一个好习惯。 local dir # 使用 'dirname' 命令来提取参数中的目录部分。 # 例如,如果参数是 "path/to/my/file.txt",那么 'dirname' 会返回 "path/to/my"。 dir=$(dirname "$arg") # 使用 'mkdir -p' 命令来创建目录。 # '-p' 选项是关键:它会创建所有必需的父目录,并且如果目录已经存在,它也不会报错。 # 这使得我们的脚本非常健壮。 mkdir -p "$dir" fi done # 在确保所有目录都创建完毕后,调用【真正】的 touch 命令。 # 这里的 'command' 是一个 shell 内置命令,它的作用是忽略任何同名的函数或别名, # 直接执行系统路径($PATH)中的原始命令。这可以防止函数无限次地调用自己(无限递归)。 # "$@" 会将【所有原始参数】(包括文件路径和命令选项)原封不动地传递给真正的 touch 命令。 command touch "$@" }
git
↩︎
zsh