Fampidirana ny baiko Linux amin'ny Windows mampiasa PowerShell sy WSL

Fanontaniana mahazatra avy amin'ny mpamorona Windows: "Nahoana no mbola tsy misy <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Na fikapohana mahery vaika izany less na fitaovana mahazatra grep na sed, mila fidirana mora amin'ireo baiko ireo ny mpamorona Windows amin'ny asany andavanandro.

Windows Subsystem for Linux (WSL) dia nanao dingana lehibe amin'izany. Izany dia ahafahanao miantso ny baiko Linux avy amin'ny Windows amin'ny alàlan'ny proxy azy ireo wsl.exe (Oh, wsl ls). Na dia fanatsarana lehibe aza izany, ity safidy ity dia manana fatiantoka maromaro.

  • Fanampiny hatraiza hatraiza wsl mandreraka sy tsy voajanahary.
  • Ny lalan'ny Windows amin'ny tohan-kevitra dia tsy mandeha foana satria ny backslashes dia adika ho toy ny tarehin-tsoratra mandositra fa tsy mpanasaraka lahatahiry.
  • Ny lalan'ny Windows amin'ny adihevitra dia tsy adika amin'ny teboka tendrombohitra mifanaraka amin'izany ao amin'ny WSL.
  • Tsy voahaja amin'ny mombamomba ny WSL miaraka amin'ny solon'anarana sy ny fari-piainan'ny tontolo iainana.
  • Tsy tohanana ny famitana ny lalan'ny Linux.
  • Tsy tohanana ny famitana ny baiko.
  • Tsy tohana ny famitana ny tohan-kevitra.

Vokatr'izany, ny baiko Linux dia raisina ho toy ny olom-pirenena kilasy faharoa amin'ny Windows — ary sarotra kokoa ny mampiasa azy noho ny baiko teratany. Mba hampitoviana ny zony dia ilaina ny mamaha ireo olana voatanisa.

Famonosana fiasa PowerShell

Miaraka amin'ny famonosana fiasa PowerShell, afaka manampy ny famitana ny baiko isika ary manafoana ny filàna prefix wsl, mandika ny lalan'ny Windows ho lalan'ny WSL. Fepetra fototra ho an'ny akorandriaka:

  • Ho an'ny baiko Linux rehetra dia tsy maintsy misy fonosana iray miaraka amin'ny anarana mitovy.
  • Ny akorandriaka dia tsy maintsy mahafantatra ny lalan'ny Windows nandalo ho tohan-kevitra ary mamadika azy ireo ho lalana WSL.
  • Tokony hiantso ny akorany wsl miaraka amin'ny baiko Linux mifanentana amin'ny fidirana amin'ny pipeline ary mandalo ny tohan-kevitry ny baikon'ny baiko alefa amin'ny fiasa.

Koa satria ity lamina ity dia azo ampiharina amin'ny baiko rehetra, dia azontsika atao ny mamintina ny famaritana ireo fonosana ireo ary mamorona azy ireo amin'ny fomba mavitrika avy amin'ny lisitry ny baiko hanafatra.

# 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 ' ')
    }
}
"@
}

Lisitry ny $command mamaritra baiko fanafarana. Avy eo isika dia mamorona dynamique wrapper ho an'ny tsirairay amin'izy ireo amin'ny fampiasana ny baiko Invoke-Expression (amin'ny alàlan'ny fanesorana ireo aliases izay mifanohitra amin'ny fiasa).

Ny fiasa dia miverimberina amin'ny adihevitra andalana baiko, mamaritra ny lalan'ny Windows mampiasa baiko Split-Path и Test-Pathary avy eo dia mamadika ireo lalana ireo ho lalana WSL. Mandeha ny lalana amin'ny alalan'ny asa mpanampy izahay Format-WslArgument, izay hofaritantsika any aoriana. Mandositra tarehin-tsoratra manokana toy ny habaka sy fononteny izay mety ho diso hevitra.

Farany, ampitainay wsl fampidirana pipeline sy ny tohan-kevitra andalana rehetra.

Miaraka amin'ireo fonosana ireo dia azonao atao ny miantso ny baiko Linux ankafizinao amin'ny fomba voajanahary kokoa tsy misy préfix wsl ary tsy manahy momba ny fomba hiovan'ny lalana:

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

Ny baiko fototra dia aseho eto, fa afaka mamorona akorandriaka ho an'ny baiko Linux rehetra ianao amin'ny fampidirana azy fotsiny amin'ny lisitra. Raha ampidirinao ity code ity amin'ny piraofilina PowerShell, ireo baiko ireo dia ho azonao isaky ny fotoam-pivoriana PowerShell, toy ny baikon'ny teratany!

Fikirana Default

Ao amin'ny Linux, mahazatra ny mamaritra ny aliases sy/na ny fari-piainan'ny tontolo iainana ao amin'ny mombamomba ny fidirana, mametraka ny mari-pamantarana default ho an'ny baiko ampiasaina matetika (ohatra, alias ls=ls -AFh na export LESS=-i). Iray amin'ireo tsy fahampian'ny proxy amin'ny alàlan'ny shell tsy misy interactive wsl.exe - fa tsy misy entana ny mombamomba azy, noho izany dia tsy misy amin'ny alàlan'ny default ireo safidy ireo (ie. ls ao amin'ny WSL ary wsl ls dia hitondra tena hafa miaraka amin'ny alias voafaritra etsy ambony).

PowerShell dia manome $PSDefaultParameterValues, mekanika manara-penitra hamaritana ny mari-pamantarana mahazatra, fa ho an'ny cmdlet sy fiasa mandroso ihany. Mazava ho azy fa afaka manao asa mandroso avy amin'ny akorandriaka isika, saingy miteraka fahasarotana tsy ilaina izany (ohatra, ny PowerShell dia mampifandray ny anaran'ny mari-pamantarana ampahany (ohatra, -a mifandray amin'ny -ArgumentList), izay mifanipaka amin'ny baiko Linux izay maka anarana ampahany ho tohan-kevitra), ary ny syntax hamaritana ny soatoavina default dia tsy ho mety indrindra (ny tohan-kevitra default dia mitaky ny anaran'ny parameter ao amin'ny lakile, fa tsy ny anaran'ny baiko fotsiny) .

Na izany aza, miaraka amin'ny fanovana kely amin'ny akorandriaka, dia afaka mampihatra modely mitovy amin'izany isika $PSDefaultParameterValues, ary avelao ny safidy default ho an'ny baiko 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 ' ')
    }
}

mandalo $WslDefaultParameterValues mankany amin'ny andalana baiko, mandefa masontsivana amin'ny alàlan'ny wsl.exe. Ity manaraka ity dia mampiseho ny fomba hanampiana toromarika ao amin'ny mombamomba anao PowerShell mba hanefena ny firafitry ny default. Afaka manao izany isika izao!

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

Satria ny paramètre dia modely aorian'ny $PSDefaultParameterValues, Ianao dia afaka mora ny manafoana azy ireo vonjimaika amin'ny fametrahana ny fanalahidy "Disabled" amin'ny dikany $true. Ny tombony fanampiny amin'ny latabatra hash misaraka dia ny fahafahana manakana $WslDefaultParameterValues misaraka amin'ny $PSDefaultParameterValues.

Fahavitan'ny adihevitra

Ny PowerShell dia ahafahanao misoratra anarana trailers arguments amin'ny alàlan'ny baiko Register-ArgumentCompleter. Bash dia manana hery fitaovana famenoana mandeha ho azy. WSL dia ahafahanao miantso bash avy amin'ny PowerShell. Raha afaka misoratra anarana ny fahavitan'ny tohan-kevitra ho an'ny famonosana PowerShell izahay ary miantso ny bash mba hamoronana ny famitana, dia mahazo fahavitan'ny tohan-kevitra feno miaraka amin'ny fahamendrehana mitovy amin'ny bash mihitsy izahay!

# 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]
    }
}

Ny kaody dia somary matevina nefa tsy mahazo ny sasany amin'ireo fiasa anatiny ao amin'ny bash, fa ny tena ataontsika dia izao:

  • Mametraka tohan-kevitra feno ho an'ny famonosana fiasa rehetra amin'ny alalan'ny fandefasana lisitra $commands amin'ny parameter -CommandName ho an'ny Register-ArgumentCompleter.
  • Sarintany ny baiko tsirairay amin'ny fiasa shell izay ampiasain'ny bash ho an'ny autocompletion (mba hamaritana ny famaritana autocompletion, fampiasana bash $F, fanafohezana ny complete -F <FUNCTION>).
  • Manova ny tohan-kevitra PowerShell $wordToComplete, $commandAst и $cursorPosition amin'ny endrika andrasana amin'ny fiasan'ny autocompletion bash araka ny fepetra famitana mandeha ho azy programmable bash.
  • Mamorona andalana baiko hafindra any wsl.exe, izay miantoka fa voaorina tsara ny tontolo iainana, miantso ny asa famenoana mandeha ho azy, ary mamoaka ny valiny amin'ny fomba andalana.
  • Dia miantso izahay wsl miaraka amin'ny baikon'ny baiko, manasaraka ny vokatra amin'ny tsipika manasaraka izahay ary mamokatra ho an'ny tsirairay CompletionResults, fanasokajiana azy ireo ary fandosirana ireo endri-tsoratra toy ny habaka sy fononteny izay mety ho diso hevitra.

Vokatr'izany dia hampiasa ny autocompletion mitovy amin'ny bash ny shell command Linux! Ohatra:

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

Ny autocompletion tsirairay dia manome sanda manokana amin'ny tohan-kevitra teo aloha, mamaky angon-drakitra fanamafisana toy ny mpampiantrano fantatra avy amin'ny WSL!

<TAB> dia hivezivezy amin'ny paramètre. <Ctrl + пробел> dia hampiseho ny safidy rehetra misy.

Fanampin'izay, satria manana autocompletion bash isika izao, azonao atao ny mameno ny lalana Linux mivantana ao amin'ny PowerShell!

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

Amin'ny tranga izay tsy miteraka vokatra ny autocompletion bash dia miverina amin'ny lalan'ny Windows default ny PowerShell. Noho izany, amin'ny fampiharana, azonao atao ny mampiasa ireo lalana roa ireo amin'ny fahamendrehanao.

famaranana

Amin'ny fampiasana PowerShell sy WSL, afaka mampiditra ny baiko Linux amin'ny Windows ho fampiharana teratany isika. Tsy ilaina ny mikaroka ny fananganana Win32 na ny fitaovana Linux na manapaka ny fizotranao amin'ny alàlan'ny fandehanana any amin'ny shell Linux. FOTSINY mametraka WSL, configure Profile PowerShell и tanisao ny baiko tianao hohafarana! Ny famenoana fiara ho an'ny baikon'ny Linux sy Windows ary ny lalan'ny rakitra dia fiasa izay tsy hita amin'ny baiko Windows teratany ankehitriny.

Ny kaody loharano feno voalaza etsy ambony, ary koa ny torolalana fanampiny amin'ny fampidirana azy ao amin'ny workflow-nao, dia misy eto.

Inona ny baiko Linux hitanao fa tena ilaina? Inona no zavatra mahazatra hafa tsy hita rehefa miasa amin'ny Windows? Soraty ao amin'ny fanehoan-kevitra na amin'ny GitHub!

Source: www.habr.com

Add a comment