启动时使用 WSL IP 更新 Windows“主机”文件

Ike*_*kwu 6 powershell windows-10 windows-subsystem-for-linux

我在 Windows 10 上使用 WSL2。

我的发行版是 Debian。

我想为我的发行版设置静态 IP,但我发现从这个答案中无法为 WSL 完成此操作。

但我发现可能还有其他一些可能性。

是否可以有一个 Powershell 脚本来更新 Windows 10 上的 etc 主机,并使用指向自定义域名的新 WSL IP(如172.18.225.26 dev.local启动时那样)?并且不会在主机文件上留下任何先前的 WSL 配置。

我的主机文件当前如下所示:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost
# Added by Docker Desktop
192.168.8.101 host.docker.internal
192.168.8.101 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section


# Added by Custom Script For WSL Distro
172.18.225.26 dev.local
#End of section

Run Code Online (Sandbox Code Playgroud)

我对 Powershell 脚本一无所知,我非常感谢您的帮助。

Ike*_*kwu 4

感谢这个答案的帮助,我已经能够得到我想要的东西,但我确实做了一些修改。

基本上,我创建了一个update_wsl_ip_to_domain.ps1文件并保存到此 PATH C:\Scripts\update_wsl_ip_to_domain.ps1,然后添加了以下脚本

#
# Powershell script for adding/removing/showing entries to the hosts file.
#
# Known limitations:
# - does not handle entries with comments afterwards ("<ip>    <host>    # comment")
#

$file = "C:\Windows\System32\drivers\etc\hosts"
$wsl_ip = (wsl -d debian hostname -I).trim()
$data = @('add','localwsl.com',$wsl_ip)

function add-host([string]$filename, [string]$hostname, [string]$ip) {
    remove-host $filename $hostname
    $ip + "`t`t" + $hostname | Out-File -encoding ASCII -append $filename
}

function remove-host([string]$filename, [string]$hostname) {
    $c = Get-Content $filename
    $newLines = @()

    foreach ($line in $c) {
        $bits = [regex]::Split($line, "\t+")
        if ($bits.count -eq 2) {
            if ($bits[1] -ne $hostname) {
                $newLines += $line
            }
        } else {
            $newLines += $line
        }
    }

    # Write file
    Clear-Content $filename
    foreach ($line in $newLines) {
        $line | Out-File -encoding ASCII -append $filename
    }
}

function print-hosts([string]$filename) {
    $c = Get-Content $filename

    foreach ($line in $c) {
        $bits = [regex]::Split($line, "\t+")
        if ($bits.count -eq 2) {
            Write-Host $bits[0] `t`t $bits[1]
        }
    }
}

try {
    if ($data[0] -eq "add") {

        if ($data.count -lt 3) {
            throw "Not enough arguments for add."
        } else {
            add-host $file $data[1] $data[2]
        }

    } elseif ($data[0] -eq "remove") {

        if ($data.count -lt 2) {
            throw "Not enough arguments for remove."
        } else {
            remove-host $file $data[1]
        }

    } elseif ($data[0] -eq "show") {
        print-hosts $file
    } else {
        throw "Invalid operation '" + $data[0] + "' - must be one of 'add', 'remove', 'show'."
    }
} catch  {
    Write-Host $error[0]
    Write-Host "`nUsage: hosts add <ip> <hostname>`n       hosts remove <hostname>`n       hosts show"
}
Run Code Online (Sandbox Code Playgroud)

接下来,我update_wsl_ip_to_domain.cmd在与该文件相同的目录中创建了一个单独的文件ps1,并添加了以下命令。

PowerShell Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Powershell -File C:\Scripts\update_wsl_ip_to_domain.ps1
PowerShell Set-ExecutionPolicy Restricted
Run Code Online (Sandbox Code Playgroud)

因此,为了让该update_wsl_ip_to_domain.cmd文件在启动时运行,我创建了该目录的快捷方式C:\Users\<user_name>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\并为其授予了管理员权限。

最后,我还在update_wsl_ip_to_domain.cmd桌面上添加了另一个具有管理员权限的文件快捷方式,我手动运行该快捷方式,因为由于某种原因,前一个快捷方式并不总是在启动时运行。

更新

在我的Debian WSL发行版上,我考虑apache在端口 80 和nginx端口 81 上运行。

因此,为了给他们一个静态 IP 和域名,我编辑了我的update_wsl_ip_to_domain.ps1文件并在底部添加了以下代码。

#GIVING WSL NGINX A STATIC IP. IT RUNS AT PORT 81 ON MY DEBIAN
netsh interface portproxy add v4tov4 listenport=80 listenaddress=127.65.43.21 connectport=81 connectaddress=$wsl_ip

#GIVING WSL APACHE  A STATIC IP. IT RUNS AT PORT 80 ON MY DEBIAN
netsh interface portproxy add v4tov4 listenport=80 listenaddress=127.65.43.22 connectport=80 connectaddress=$wsl_ip
Run Code Online (Sandbox Code Playgroud)

hosts然后我在 10 日的文件中做了以下条目Windows

127.65.43.21        localwslnginx.com

127.65.43.22        localwslapache.com
Run Code Online (Sandbox Code Playgroud)

我相信这有很大的潜力,我可能可以使用我的apachenginx.

我将继续进行更新。

更新 2(2021 年 12 月 28 日)

我已经能够运行多个应用程序,wsl每个应用程序都有其独特的域名。这是我hosts在 Windows 上的文件的样子:

127.65.43.21        localwslnginx.com

127.65.43.22        localwslapache.com

# Laravel Apps
127.65.43.22        evangrest.test

127.65.43.22        firstbarcodes.test
Run Code Online (Sandbox Code Playgroud)

localwslapache.com它们必须分别与或和localwslnginx.com具有相同的静态 IP 。apachenginx

对于apache,我使用以下配置来运行我的laravel应用程序:

<VirtualHost *:80>
    DocumentRoot "/data/www/firstbarcodes/public"
    DirectoryIndex "index.php"
    ServerName firstbarcodes.test
    ServerAlias firstbarcodes.test    

    <Directory "/data/www/firstbarcodes">
       Options Indexes FollowSymLinks
       AllowOverride None
       Require all granted
    </Directory>
   
    <Directory "/data/www/firstbarcodes/public">
      Options Indexes FollowSymLinks MultiViews ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
      Require all granted
    </Directory>
    
    #Alias /js /data/www/firstbarcodes/public/js
    #<Directory /data/www/firstbarcodes/public/js>
    #  Options Indexes FollowSymLinks MultiViews ExecCGI
    #  AllowOverride All
    #  Order allow,deny
    #  Allow from all
    #  Require all granted
    #</Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

您可能还需要运行此sudo a2enmod rewrite命令apache

我想通过这种方式,我已经能够以某种方式创建一个 hack,为我的所有应用程序提供apache静态nginxIP WSL

接下来我想做的是让我在启动时WSL Debian自动启动。apachemariadbwindows