Kuphatikiza malamulo a Linux mu Windows pogwiritsa ntchito PowerShell ndi WSL

Funso lodziwika bwino kuchokera kwa opanga Windows: "Chifukwa chiyani palibe <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Kaya ndi swipe yamphamvu less kapena zida zodziwika bwino grep kapena sed, Madivelopa a Windows akufuna kupeza mosavuta malamulowa pa ntchito yawo ya tsiku ndi tsiku.

Windows Subsystem ya Linux (WSL) wapita patsogolo kwambiri pankhaniyi. Zimakuthandizani kuti muyitane malamulo a Linux kuchokera pa Windows powatumizira wsl.exe (i.e. wsl ls). Ngakhale izi ndizowongolera kwambiri, njirayi ili ndi zovuta zingapo.

  • Kuwonjezera kulikonse wsl zotopetsa komanso zachilendo.
  • Njira za Windows pazokangana sizigwira ntchito nthawi zonse chifukwa ma backslash amatanthauziridwa ngati zilembo zothawa m'malo molekanitsa zikwatu.
  • Njira za Windows pazokangana sizimasuliridwa kumalo okwera omwe ali mu WSL.
  • Zokonda zokhazikika sizimalemekezedwa mu mbiri ya WSL yokhala ndi ma alias ndi zosintha zachilengedwe.
  • Kumaliza kwa njira ya Linux sikuthandizidwa.
  • Kumaliza kwa lamulo sikutheka.
  • Kumaliza kukangana sikutheka.

Zotsatira zake, malamulo a Linux amatengedwa ngati nzika za kalasi yachiwiri pansi pa Windows-ndipo ndizovuta kugwiritsa ntchito kuposa malamulo achibadwidwe. Kuti mufanane ndi ufulu wawo, m'pofunika kuthetsa mavuto omwe atchulidwa.

PowerShell ntchito wrappers

Ndi PowerShell ntchito wrappers, tikhoza kuwonjezera lamulo kumaliza ndi kuthetsa kufunika prefixes wsl, kumasulira njira za Windows kukhala njira za WSL. Zofunikira za zipolopolo:

  • Pa lamulo lililonse la Linux payenera kukhala cholembera chimodzi chokhala ndi dzina lomwelo.
  • Chipolopolocho chiyenera kuzindikira njira za Windows zomwe zadutsa ngati mikangano ndikusintha kukhala njira za WSL.
  • Chigoba chiyenera kuyimba wsl ndi lamulo loyenera la Linux pakuyika kwa mapaipi aliwonse ndikudutsa mikangano yamtundu uliwonse yoperekedwa ku ntchitoyi.

Popeza chitsanzochi chingagwiritsidwe ntchito pa lamulo lililonse, tikhoza kufotokoza tanthauzo la mapepalawa ndikuwapanga kuchokera pamndandanda wa malamulo oti alowe.

# The commands to import.
$commands = "awk", "emacs", "grep", "head", "less", "ls", "man", "sed", "seq", "ssh", "tail", "vim"
 
# Register a function for each command.
$commands | ForEach-Object { Invoke-Expression @"
Remove-Alias $_ -Force -ErrorAction Ignore
function global:$_() {
    for (`$i = 0; `$i -lt `$args.Count; `$i++) {
        # If a path is absolute with a qualifier (e.g. C:), run it through wslpath to map it to the appropriate mount point.
        if (Split-Path `$args[`$i] -IsAbsolute -ErrorAction Ignore) {
            `$args[`$i] = Format-WslArgument (wsl.exe wslpath (`$args[`$i] -replace "", "/"))
        # If a path is relative, the current working directory will be translated to an appropriate mount point, so just format it.
        } elseif (Test-Path `$args[`$i] -ErrorAction Ignore) {
            `$args[`$i] = Format-WslArgument (`$args[`$i] -replace "", "/")
        }
    }
 
    if (`$input.MoveNext()) {
        `$input.Reset()
        `$input | wsl.exe $_ (`$args -split ' ')
    } else {
        wsl.exe $_ (`$args -split ' ')
    }
}
"@
}

mndandanda $command imatanthauzira malamulo otengera katundu. Kenako timapanga chopukutira ntchito kwa aliyense wa iwo pogwiritsa ntchito lamulo Invoke-Expression (poyamba kuchotsa zilembo zilizonse zomwe zingasemphane ndi ntchitoyi).

Ntchitoyi imabwereza pamakangano a mzere wa malamulo, imasankha njira za Windows pogwiritsa ntchito malamulo Split-Path и Test-Pathndikusintha njira izi kukhala njira za WSL. Timayendetsa njira kudzera mu ntchito yothandizira Format-WslArgument, zomwe tidzafotokoza pambuyo pake. Imathawa zilembo zapadera monga mipata ndi mabatani omwe angatanthauziridwe molakwika.

Pomaliza, timapereka wsl kulowetsa mapaipi ndi mikangano iliyonse yamalamulo.

Ndi ma wrappers awa mutha kuyitanitsa malamulo omwe mumakonda a Linux mwanjira yachilengedwe popanda kuwonjezera chilembo wsl ndipo popanda kudandaula za momwe njirazo zimasinthira:

  • man bash
  • less -i $profile.CurrentUserAllHosts
  • ls -Al C:Windows | less
  • grep -Ein error *.log
  • tail -f *.log

Malamulo oyambira akuwonetsedwa apa, koma mutha kupanga chipolopolo cha lamulo lililonse la Linux mwa kungowonjezera pamndandanda. Ngati muwonjezera code iyi ku yanu mbiri PowerShell, malamulo awa azipezeka kwa inu mu gawo lililonse la PowerShell, monga malamulo achibadwidwe!

Zokonda Zofikira

Mu Linux, ndizofala kutanthauzira zilembo ndi/kapena zosintha zamalo muzambiri zolowera, kuyika magawo osakhazikika pamalamulo omwe amagwiritsidwa ntchito pafupipafupi (mwachitsanzo, alias ls=ls -AFh kapena export LESS=-i). Kuyipa kumodzi kokhala ngati proxy kudzera mu chipolopolo chosalumikizana wsl.exe - kuti mbiriyo siidakwezedwe, kotero zosankhazi sizipezeka mwachisawawa (ie. ls mu WSL ndi wsl ls adzachita mosiyana ndi dzina lomwe lafotokozedwa pamwambapa).

PowerShell imapereka $PSDefaultParameterValues, makina okhazikika ofotokozera magawo osasinthika, koma a cmdlets ndi ntchito zapamwamba. Zachidziwikire, titha kupanga ntchito zapamwamba kuchokera ku zipolopolo zathu, koma izi zimabweretsa zovuta zosafunikira (mwachitsanzo, PowerShell imagwirizanitsa mayina a parameter (mwachitsanzo, -a zimagwirizana ndi -ArgumentList), zomwe zingasemphane ndi malamulo a Linux omwe amatenga mayina pang'ono ngati mikangano), ndipo mawu ofotokozera zachikhalidwe sangakhale oyenera kwambiri (zosakhazikika zimafuna dzina lachidziwitso pakiyi, osati dzina la lamulo) .

Komabe, ndi kusinthidwa pang'ono kwa zipolopolo zathu, titha kugwiritsa ntchito chitsanzo chofanana ndi $PSDefaultParameterValues, ndikuthandizira zosankha zosasinthika zamalamulo a Linux!

function global:$_() {
    …
 
    `$defaultArgs = ((`$WslDefaultParameterValues.$_ -split ' '), "")[`$WslDefaultParameterValues.Disabled -eq `$true]
    if (`$input.MoveNext()) {
        `$input.Reset()
        `$input | wsl.exe $_ `$defaultArgs (`$args -split ' ')
    } else {
        wsl.exe $_ `$defaultArgs (`$args -split ' ')
    }
}

Kudutsa $WslDefaultParameterValues ku mzere wolamula, timatumiza magawo kudzera wsl.exe. Zotsatirazi zikuwonetsa momwe mungawonjezere malangizo ku mbiri yanu ya PowerShell kuti musinthe makonda osasintha. Tsopano titha kuchita!

$WslDefaultParameterValues["grep"] = "-E"
$WslDefaultParameterValues["less"] = "-i"
$WslDefaultParameterValues["ls"] = "-AFh --group-directories-first"

Popeza magawo amatsatiridwa pambuyo pake $PSDefaultParameterValues, Mutha ndikosavuta kuwaletsa kwakanthawi poyika kiyi "Disabled" mu mtengo $true. Phindu lina la tebulo lapadera la hashi ndikutha kuletsa $WslDefaultParameterValues mosiyana ndi $PSDefaultParameterValues.

Kumaliza kukangana

PowerShell imakupatsani mwayi wolembetsa ma trailer otsutsana pogwiritsa ntchito lamulo Register-ArgumentCompleter. Bash ali ndi mphamvu zida zomalizirira zokha zokha. WSL imakulolani kuyimba bash kuchokera ku PowerShell. Ngati titha kulembetsa kumalizidwa kwa mikangano yamapulogalamu athu a PowerShell ndikuyimbira bash kuti tikwaniritse, timapeza mkangano wathunthu ndikulondola komweko monga bash yokha!

# Register an ArgumentCompleter that shims bash's programmable completion.
Register-ArgumentCompleter -CommandName $commands -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)
 
    # Map the command to the appropriate bash completion function.
    $F = switch ($commandAst.CommandElements[0].Value) {
        {$_ -in "awk", "grep", "head", "less", "ls", "sed", "seq", "tail"} {
            "_longopt"
            break
        }
 
        "man" {
            "_man"
            break
        }
 
        "ssh" {
            "_ssh"
            break
        }
 
        Default {
            "_minimal"
            break
        }
    }
 
    # Populate bash programmable completion variables.
    $COMP_LINE = "`"$commandAst`""
    $COMP_WORDS = "('$($commandAst.CommandElements.Extent.Text -join "' '")')" -replace "''", "'"
    for ($i = 1; $i -lt $commandAst.CommandElements.Count; $i++) {
        $extent = $commandAst.CommandElements[$i].Extent
        if ($cursorPosition -lt $extent.EndColumnNumber) {
            # The cursor is in the middle of a word to complete.
            $previousWord = $commandAst.CommandElements[$i - 1].Extent.Text
            $COMP_CWORD = $i
            break
        } elseif ($cursorPosition -eq $extent.EndColumnNumber) {
            # The cursor is immediately after the current word.
            $previousWord = $extent.Text
            $COMP_CWORD = $i + 1
            break
        } elseif ($cursorPosition -lt $extent.StartColumnNumber) {
            # The cursor is within whitespace between the previous and current words.
            $previousWord = $commandAst.CommandElements[$i - 1].Extent.Text
            $COMP_CWORD = $i
            break
        } elseif ($i -eq $commandAst.CommandElements.Count - 1 -and $cursorPosition -gt $extent.EndColumnNumber) {
            # The cursor is within whitespace at the end of the line.
            $previousWord = $extent.Text
            $COMP_CWORD = $i + 1
            break
        }
    }
 
    # Repopulate bash programmable completion variables for scenarios like '/mnt/c/Program Files'/<TAB> where <TAB> should continue completing the quoted path.
    $currentExtent = $commandAst.CommandElements[$COMP_CWORD].Extent
    $previousExtent = $commandAst.CommandElements[$COMP_CWORD - 1].Extent
    if ($currentExtent.Text -like "/*" -and $currentExtent.StartColumnNumber -eq $previousExtent.EndColumnNumber) {
        $COMP_LINE = $COMP_LINE -replace "$($previousExtent.Text)$($currentExtent.Text)", $wordToComplete
        $COMP_WORDS = $COMP_WORDS -replace "$($previousExtent.Text) '$($currentExtent.Text)'", $wordToComplete
        $previousWord = $commandAst.CommandElements[$COMP_CWORD - 2].Extent.Text
        $COMP_CWORD -= 1
    }
 
    # Build the command to pass to WSL.
    $command = $commandAst.CommandElements[0].Value
    $bashCompletion = ". /usr/share/bash-completion/bash_completion 2> /dev/null"
    $commandCompletion = ". /usr/share/bash-completion/completions/$command 2> /dev/null"
    $COMPINPUT = "COMP_LINE=$COMP_LINE; COMP_WORDS=$COMP_WORDS; COMP_CWORD=$COMP_CWORD; COMP_POINT=$cursorPosition"
    $COMPGEN = "bind `"set completion-ignore-case on`" 2> /dev/null; $F `"$command`" `"$wordToComplete`" `"$previousWord`" 2> /dev/null"
    $COMPREPLY = "IFS=`$'n'; echo `"`${COMPREPLY[*]}`""
    $commandLine = "$bashCompletion; $commandCompletion; $COMPINPUT; $COMPGEN; $COMPREPLY" -split ' '
 
    # Invoke bash completion and return CompletionResults.
    $previousCompletionText = ""
    (wsl.exe $commandLine) -split 'n' |
    Sort-Object -Unique -CaseSensitive |
    ForEach-Object {
        if ($wordToComplete -match "(.*=).*") {
            $completionText = Format-WslArgument ($Matches[1] + $_) $true
            $listItemText = $_
        } else {
            $completionText = Format-WslArgument $_ $true
            $listItemText = $completionText
        }
 
        if ($completionText -eq $previousCompletionText) {
            # Differentiate completions that differ only by case otherwise PowerShell will view them as duplicate.
            $listItemText += ' '
        }
 
        $previousCompletionText = $completionText
        [System.Management.Automation.CompletionResult]::new($completionText, $listItemText, 'ParameterName', $completionText)
    }
}
 
# Helper function to escape characters in arguments passed to WSL that would otherwise be misinterpreted.
function global:Format-WslArgument([string]$arg, [bool]$interactive) {
    if ($interactive -and $arg.Contains(" ")) {
        return "'$arg'"
    } else {
        return ($arg -replace " ", " ") -replace "([()|])", ('$1', '`$1')[$interactive]
    }
}

Khodiyo ndi yowuma pang'ono osamvetsetsa zina mwazochita zamkati za bash, koma kwenikweni zomwe timachita ndi izi:

  • Kulembetsa omaliza mkangano pazantchito zathu zonse popereka mndandanda $commands mu parameter -CommandName chifukwa Register-ArgumentCompleter.
  • Timayika lamulo lililonse ku chipolopolo chomwe bash amagwiritsa ntchito pokonzekera zokha (kutanthauzira mafotokozedwe a autocompletion, bash amagwiritsa ntchito $F, chidule cha complete -F <FUNCTION>).
  • Kutembenuza Makangano a PowerShell $wordToComplete, $commandAst и $cursorPosition m'mawonekedwe omwe amayembekezeredwa ndi bash's autocompletion ntchito molingana ndi zomwe zafotokozedwa kumalizitsa kokhazikika bash.
  • Timalemba mzere wolamula kuti titumizeko wsl.exe, zomwe zimatsimikizira kuti chilengedwe chakhazikitsidwa bwino, chimayitana ntchito yoyenera yokonzekera yokha, ndipo imatulutsa zotsatira mumzere ndi mzere.
  • Ndiye timayitana wsl ndi mzere wolamula, timalekanitsa zotuluka ndi olekanitsa mizere ndikupanga chilichonse CompletionResults, kusanja ndi zilembo zothawa monga mipata ndi mabatani zomwe sizikanatanthauziridwa molakwika.

Zotsatira zake, zipolopolo zathu za Linux zidzagwiritsa ntchito kukhazikika komweko monga bash! Mwachitsanzo:

  • ssh -c <TAB> -J <TAB> -m <TAB> -O <TAB> -o <TAB> -Q <TAB> -w <TAB> -b <TAB>

Kukonzekera kulikonse kumapereka mikangano yofananira ndi mkangano wam'mbuyomu, ndikuwerenga zosintha monga makamu odziwika kuchokera ku WSL!

<TAB> idzazungulira pazigawo. <Ctrl + пробел> idzawonetsa zosankha zonse zomwe zilipo.

Kuphatikiza apo, popeza tsopano tili ndi bash autocompletion, mutha kumaliza njira za Linux mwachindunji mu PowerShell!

  • less /etc/<TAB>
  • ls /usr/share/<TAB>
  • vim ~/.bash<TAB>

Munthawi yomwe kukwaniritsidwa kwa bash sikutulutsa zotsatira, PowerShell imabwerera kumayendedwe a Windows osasintha. Chifukwa chake, pochita, mutha kugwiritsa ntchito njira ziwiri nthawi imodzi mwakufuna kwanu.

Pomaliza

Pogwiritsa ntchito PowerShell ndi WSL, titha kuphatikiza malamulo a Linux mu Windows ngati mapulogalamu achilengedwe. Palibe chifukwa chofufuzira zomanga za Win32 kapena zida za Linux kapena kusokoneza mayendedwe anu popita ku chipolopolo cha Linux. Basi kukhazikitsa WSL, konza Mbiri ya PowerShell и tchulani malamulo omwe mukufuna kuitanitsa! Kukonzekera kolemera kwa Linux ndi Windows command parameters ndi njira zamafayilo ndizochita zomwe sizikupezeka m'malamulo a Windows masiku ano.

Khodi yathunthu yomwe yafotokozedwa pamwambapa, komanso malangizo owonjezera ophatikizira mumayendedwe anu, ilipo apa.

Ndi malamulo ati a Linux omwe mumawona kuti ndi othandiza kwambiri? Ndi zinthu zina ziti zomwe zimasowa mukamagwira ntchito mu Windows? Lembani mu ndemanga kapena pa GitHub!

Source: www.habr.com

Kuwonjezera ndemanga