通过域名实现 Windows 和 WSL2.0 的相互访问

问题

当 wsl 版本切换到 2 后,内部是使用虚拟机来实现,所以无法使用 localhost 访问 windows 的资源,想要通过 url 相互访问就必须先去查双方的局域网 ip(觉得无所谓请跳过接下来的表演)

解决思路

向 windows 的 hosts 文件写入 wsl 的 ip,向 wsl 的 hosts 文件写入 windows 的 ip,然后双方就能通过域名访问彼此

遇到的坑

  1. 操作 windows 和 wsl 的 hosts 文件都需要各自的管理员权限(windows 的管理员权限无法操作 wsl 的 hosts 文件,反之亦然)
  2. wsl 和 windows 都无法获取到对方的 ip
  3. windows 的脚本使用 CRLF 格式保存,wsl 脚本使用 LF 格式保存
  4. wsl 解析 windows 文件时
    1. 因为 windows 文件是 gbk 格式,有几率乱码,使用 grep 时会报错,需要加上 -a 选项
    2. 解析 windows 保存的文件时要过滤掉 \r(windows 的换行符是 \r\n)
  5. wsl 无法 ping 通 windows 的 ip,所以也无法通过域名 ping 通,但不影响 curl 等工具使用

解决步骤

需要使用两个脚本,一个 bat 和一个 shell 来解决上述问题

  1. 使用 windows 的管理员权限执行 bat 脚本,然后 bat 脚本内部使用 wsl 的管理员权限执行 shell 脚本
  2. bat 脚本
    1. 进入到脚本所在目录(windows 管理员权限打开终端路径在 C 盘)
    2. 将 ipconfig 的响应写入一个临时文件(供后面 wsl 读取)
    3. 使用管理员权限执行 wsl 脚本
    4. 删除临时文件
  3. shell 脚本
    1. 解析上述产生的临时文件,获取 windows 的 ip,通过 ifconfig 获取 wsl 的 ip
    2. 将 windows 中之前存在的 wsl 的 ip 清除,wsl 一样操作
    3. 将新的 ip 写入对方的 hosts 文件

脚本

假定 wsl 的域名为 wsl,windows 的域名为 win,实现如下

sync-ip.bat
@REM 此脚本需要管理员权限执行!
@echo off
@REM 使用管理员权限执行时,默认路径是 C 盘,脚本在 E 盘,需要使用 /d 选项才能切到脚本的目录
cd /d %~dp0
@REM wsl 无法读取到 windows 的 ip,所以需要先临时写入一个文件,然后 wsl 去解析获取 windows 的 ip
ipconfig > win_ipconfig
@REM 执行 shell 脚本(需要管理员权限)
wsl -u root bash sync-ip.sh
@REM 删除临时文件
del win_ipconfig
pause
sync-ip.sh
#!/bin/bash

# domain's name
win_domain=win
wsl_domain=wsl
# hosts' path
win_hosts=/mnt/c/Windows/System32/drivers/etc/hosts
wsl_hosts=/etc/hosts
# other
log_prefix='>>>'
win_ipconfig=$(dirname $0)/win_ipconfig

function write_hosts_file() {
    ip=$1
    i=$2
    hosts=$3
    domain=$4
    if [ $i -eq 0 ]; then
        content="$ip\t$domain"
    else
        content="$ip\t${domain}_$i"
    fi
    echo -e $content >> $hosts
}

function print_host_file () {
    hosts=$(eval echo '$'$2'_hosts')
    echo -e "$log_prefix $1 $2's hosts\n"
    cat $hosts | grep -v '^#' | sed 's/\r//g' | grep -v '^$'
    echo ''
}

function sync_wsl_to_win() {
    echo "$log_prefix write win's hosts"
    print_host_file old win
    # remove old wsl's ip to win's hosts
    cat $win_hosts | grep -v $wsl_domain > $win_hosts
    # write new wsl's ip to win's hosts
    wsl_ips=($(ifconfig | grep 'inet.*broadcast' | awk -F ' ' '{print $2}'))
    for ((i = 0; i < ${#wsl_ips[@]}; i++)); do
        write_hosts_file ${wsl_ips[i]} $i $win_hosts $wsl_domain
    done
    print_host_file new win
}

function sync_win_to_wsl() {
    echo "$log_prefix write wsl's hosts"
    print_host_file old wsl
    # remove old wsl's ip to wsl's hosts
    cat $wsl_hosts | grep -v $win_domain > $wsl_hosts
    # write new wsl's ip to wsl's hosts
    win_ips=($(cat $win_ipconfig | grep -a IPv4 | awk -F ' ' '{print $NF}' | sed 's/\r//g' | grep -v '\.1$'))
    for ((i = 0; i < ${#win_ips[@]}; i++)); do
        write_hosts_file ${win_ips[i]} $i $wsl_hosts $win_domain
    done
    print_host_file new wsl
}

sync_wsl_to_win
sync_win_to_wsl
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值