当前位置:网站首页>WSL 自动更新 ip hosts 文件

WSL 自动更新 ip hosts 文件

2022-06-10 23:56:00 码道人

这篇笔记已经写了一年了,起初是在使用 WSL 时,因为需要链接 WSL 里面的 XRDP 图形界面,但是,WSL 的 ip 每次重启的时候都是变化的,需要手动使用命令查看,十分不方便,于是,我自己写了一个脚本用于自动更新 hosts 文件,使 wsl.host 指向 wsl 的 ip 地址,免去每次都手动查看的烦恼。

时隔一年,发现,网上有很多人在寻求最终方法,但始终没有人给出一个可行方案,遂发此文。

使用场景

WSL2 每次启动时,虚拟网卡的 宿主机 Windows 的 ip 和 wsl 的ip都是变化的,在登录 wsl 的图形界面和测试网络程序时,都很不方便,所以写了一个脚本自动更新 宿主机 和 wsl 的 hosts文件。同时,在wsl的环境变量中加入 winip 和 wslip 两个环境变量指示 ip 地址

在下文中,我将使用“主机”指代运行Windows的主机,wsl 指代 Windows sub Linux 系统

怎么做

如果你只关心达到目的,只看这一节即可

1.创建脚本文件 /opt/cron/boot.sh

写入以下内容


#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

startDate=`date +"%Y-%m-%d %H:%M:%S"`

echo "------------ Script Start At $startDate -----------------"

win_hosts_path='/mnt/c/Windows/System32/drivers/etc/hosts'

msg="##the wsl hosts. autogenerationn"

tmp="/tmp/hosts_tmp"

export winip=$(ip route | grep default | awk '{print $3}')  && echo "export winip:$winip" || echo "get winip falut"

export wslip=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}') && echo "export wslip:$wslip" || echo "get wslip fault"

# update windows hosts

if [ ! -f $tmp ]; then

        echo $(touch $tmp && echo "touch $tmp")

else

        echo "tmp file:$tmp"

fi

echo "process windows hosts"

sed '/win.host/d' $win_hosts_path  |

        sed '/wsl.host/d'|

        sed '/#Update At/d' |

        sed '/'"$msg"'/d' |

        sed '$a'"$msg$winip win.hostn$wslip wsl.hostn#Update At $startDate" > $tmp

echo 'writting windows hosts'

cat $tmp > $win_hosts_path

if [ $? -eq 0 ];then

        echo "write successfully"

else

        echo "write fail"

fi

echo "process wsl hosts"

sed "/win.host/d" /etc/hosts |

        sed "/wsl.host/d" |

        sed "/Update At/d" |

        sed '/'"$msg"'/d' |

        sed '$a'"$msg$winip win.hostn$wslip wsl.hostn#Update At $startDate" > $tmp

echo 'writing wsl hosts'

cat $tmp > /etc/hosts

if [ $? -eq 0 ];then

        echo "write successfully"

else

        echo "write fail"

fi

endDate=`date +"%Y-%m-%d %H:%M:%S"`

echo "----------- Script Finished At $endDate ----------"

实际使用时,又更改了些许设置如下


#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

startDate=`date +"%Y-%m-%d %H:%M:%S"`

echo "----------- Script Start At $startDate ----------"

win_hosts_path='/mnt/c/Windows/System32/drivers/etc/hosts'

msg="##the wsl hosts. autogenerationn"

tmp="/tmp/hosts_tmp"

unset winip

unset wslip

Exit(){

        endDate=`date +"%Y-%m-%d %H:%M:%S"`

        echo "----------- Script Finished At $endDate ----------"

        exit

}

Log(){

        date=`date +"%H:%M:%S"`

        echo "[$date] $*"

}

winip=$(ip route | grep default | awk '{print $3}')

if [ $winip ];then

        Log "windows ip:$winip"
else

        Log "get Windows ip falut,Exiting...."

        Exit

fi

wslip=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}')

if [ $wslip ];then

        Log "WSL ip:$wslip"

else

        Log "get WSL ip falut,Exiting...."

        Exit

fi

# update windows hosts

# rm $tmp

if [ ! -f $tmp ]; then

        Log $(touch $tmp && echo "touch $tmp")

else

        Log "tmp file:$tmp"

fi

Log "process windows hosts"

sed '/win.host/d' $win_hosts_path  |

        sed '/wsl.host/d'|

        sed '/#Update At/d' |

        sed '/'"$msg"'/d' |

        sed '$a'"$msg$winip win.hostn$wslip wsl.hostn#Update At $startDate" > $tmp

Log 'writting windows hosts'

cat $tmp > $win_hosts_path

if [ $? -eq 0 ];then

        Log "write successfully"

else

        Log "write fail"

        Exit

fi

Log "process wsl hosts"

sed "/win.host/d" /etc/hosts |

        sed "/wsl.host/d" |

        sed "/Update At/d" |

        sed '/'"$msg"'/d' |

        sed '$a'"$msg$winip win.hostn$wslip wsl.hostn#Update At $startDate" > $tmp

Log 'writing wsl hosts'

cat $tmp > /etc/hosts

if [ $? -eq 0 ];then

        Log "write successfully"

else

        Log "write fail"

        Exit

fi

Exit

2. 创建 /etc/wsl.conf 文件

写入以下内容


# Automatically mount Windows drive when the distribution is launched

[automount]

# Set to true will automount fixed drives (C:/ or D:/) with DrvFs under the root directory set above. Set to false means drives won't be mounted automatically, but need to be mounted manually or with fstab.

enabled = true

# Sets the directory where fixed drives will be automatically mounted. This example changes the mount location, so your C-drive would be /c, rather than the default /mnt/c.

root = /mnt/

# DrvFs-specific options can be specified.

options = "metadata,uid=1003,gid=1003,umask=077,fmask=11,case=off"

# Sets the `/etc/fstab` file to be processed when a WSL distribution is launched.

mountFsTab = true

# Network host settings that enable the DNS server used by WSL 2. This example changes the hostname, sets generateHosts to false, preventing WSL from the default behavior of auto-generating /etc/hosts, and sets generateResolvConf to false, preventing WSL from auto-generating /etc/resolv.conf, so that you can create your own (ie. nameserver 1.1.1.1).

[network]

hostname = Su

generateHosts = false

generateResolvConf = true

# Set whether WSL supports interop process like launching Windows apps and adding path variables. Setting these to false will block the launch of Windows processes and block adding $PATH environment variables.

[interop]

enabled = false

appendWindowsPath = false

# Set the user when launching a distribution with WSL.

[user]

default = aja

# Set a command to run when a new WSL instance launches. This example starts the Docker container service.

[boot]

command = /bin/bash /opt/cron/boot.sh >> /var/log/user/iboot.log

3.创建日志文件


mkdir -p /var/log/user/

touch /var/log/user/iboot.log

chmod 777 /var/log/iboot.log

4.更改 Windows 主机权限

打开 C:\Windows\System32\drivers

点击 etc 文件夹的属性,取消只读属性,

点击 安全->高级:

更改所有者

选择 Users ,点击确定

关闭属性窗口,重新打开,将 Users 的权限全部打开。允许完全控制

一切OK

此时,在Windows 主机和 WSl 内,都可以使用 win.host 和 wsl.host 访问主机和 wsl 网络。

BTW , 在 bash 环境变量中导入 ip

终端运行一下指令


echo "export winip=$(ip route | grep default | awk '{print $3}')" >> /etc/profile

echo "export wslip=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}')" >> /etc/profile

source /etc/profile

在终端有 winip 和 wslip 两个环境变量

Enjoy it!

现在,你可以在 WSL 和 Windows 里面,使用 wsl.host 指代 WSL 的ip,win.host 指代 Win 的ip。同时,在 WSL 里面,您可以使用 $winip 得到 windows 的 ip, $wslip 得到 WSL 自身 ip 地址。

实现思路:

一、脚本编写基础条件--如何自动执行脚本

1.1阻碍

  • wsl 无法在启动时使用 crontab ,意味着无法使用 crontab 自动运行脚本,必须每次启动手动运行
  • profile 无法取得权限修改 hosts 文件,可以更改文件权限,但,,并非上策

1.2 解决方案

WSl2 中有一个配置文件在 /etc/wsl.conf ,默认可能不存在这个文件,可以手动创建,在这个文件中可以指定一个脚本,该脚本将在 WSL 启动时以 root 身份运行,以供用户编写初始化脚本。完美!

条件达成

二、脚本编写

2.1整体流程

脚本获取主机 和 WSL 的 ip ,然后,更新 WSL 和 Windows 的 hosts 文件,从而使用 wsl.host win.host 即可访问 WSL 和 主机

2.2 获取 主机 和 WSL 的ip

1.在默认条件下,WSL 启动时会自动生成 /etc/resolv.conf 文件,文件中将给出主机 IP,一个 resolv.conf 文件内容如下:


# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:

# [network]

# generateResolvConf = false

nameserver 172.22.240.1

此时:


cat /etc/resolv.conf | grep nameserver | awk {'print $2'} #可获取 主机 ip

ifconfig | grep inet | awk {'print $2'} # 获取 WSL ip

2.使用命令 ip route


default via 172.22.240.1 dev eth0

172.22.240.0/20 dev eth0 proto kernel scope link src 172.22.245.160

其中 default via 后面的地址即主机 IP ,src 后面为 WSL ip

命令


ip route | grep default | awk {'print $3'} # 获取主机 ip

ip route | grep src | awk {'print $2'} # 获取 WSL ip

由于,我们目的是更新 hosts 文件,设置环境变量,所以,resolv.conf 的自动生成就没有必要。我们将关闭 resolv.conf 的生成

更改 /etc/wsl.conf 如下


# Automatically mount Windows drive when the distribution is launched

[automount]

# Set to true will automount fixed drives (C:/ or D:/) with DrvFs under the root directory set above. Set to false means drives won't be mounted automatically, but need to be mounted manually or with fstab.

enabled = true

# Sets the directory where fixed drives will be automatically mounted. This example changes the mount location, so your C-drive would be /c, rather than the default /mnt/c.

root = /mnt/

# DrvFs-specific options can be specified.

options = "metadata,uid=1003,gid=1003,umask=077,fmask=11,case=off"

# Sets the `/etc/fstab` file to be processed when a WSL distribution is launched.

mountFsTab = true

# Network host settings that enable the DNS server used by WSL 2. This example changes the hostname, sets generateHosts to false, preventing WSL from the default behavior of auto-generating /etc/hosts, and sets generateResolvConf to false, preventing WSL from auto-generating /etc/resolv.conf, so that you can create your own (ie. nameserver 1.1.1.1).

[network]

hostname = Su

generateHosts = false

generateResolvConf = true

# Set whether WSL supports interop process like launching Windows apps and adding path variables. Setting these to false will block the launch of Windows processes and block adding $PATH environment variables.

[interop]

enabled = false

appendWindowsPath = false

# Set the user when launching a distribution with WSL.

[user]

default = aja

# Set a command to run when a new WSL instance launches. This example starts the Docker container service.

[boot]

command = /bin/bash /opt/cron/boot.sh >> /var/log/user/iboot.log

2.3 脚本内容


#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

startDate=`date +"%Y-%m-%d %H:%M:%S"`

echo "------------ Script Start At $startDate -----------------"

win_hosts_path='/mnt/c/Windows/System32/drivers/etc/hosts'

msg="##the wsl hosts. autogenerationn"

tmp="/tmp/hosts_tmp"

export winip=$(ip route | grep default | awk '{print $3}')  && echo "export winip:$winip" || echo "get winip falut"

export wslip=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}') && echo "export wslip:$wslip" || echo "get wslip fault"

# update windows hosts

if [ ! -f $tmp ]; then

        echo $(touch $tmp && echo "touch $tmp")

else

        echo "tmp file:$tmp"

fi

echo "process windows hosts"

sed '/win.host/d' $win_hosts_path  |

        sed '/wsl.host/d'|

        sed '/#Update At/d' |

        sed '/'"$msg"'/d' |

        sed '$a'"$msg$winip win.hostn$wslip wsl.hostn#Update At $startDate" > $tmp

echo 'writting windows hosts'

cat $tmp > $win_hosts_path

if [ $? -eq 0 ];then

        echo "write successfully"

else

        echo "write fail"

fi

echo "process wsl hosts"

sed "/win.host/d" /etc/hosts |

        sed "/wsl.host/d" |

        sed "/Update At/d" |

        sed '/'"$msg"'/d' |

        sed '$a'"$msg$winip win.hostn$wslip wsl.hostn#Update At $startDate" > $tmp

echo 'writing wsl hosts'

cat $tmp > /etc/hosts

if [ $? -eq 0 ];then

        echo "write successfully"

else

        echo "write fail"

fi

endDate=`date +"%Y-%m-%d %H:%M:%S"`

echo "----------- Script Finished At $endDate ----------"
原网站

版权声明
本文为[码道人]所创,转载请带上原文链接,感谢
https://markdowner.net/v1/article/by_user/322864583368785920