Ukudibanisa imiyalelo yeLinux kwiWindows usebenzisa iPowerShell kunye neWSL

Umbuzo oqhelekileyo ovela kubaphuhlisi beWindows: "Kutheni kungekho <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Nokuba yinto yokuswayipha enamandla less okanye izixhobo eziqhelekileyo grep okanye sed, Abaphuhlisi beWindows bafuna ukufikelela ngokulula kule miyalelo kumsebenzi wabo wemihla ngemihla.

Inkqubo engaphantsi yeWindows yeLinux (WSL) wenze inyathelo elikhulu phambili kulo mba. Ikuvumela ukuba ufowunele imiyalelo yeLinux evela kwiWindows ngokuyisebenzela wsl.exe (umzekelo, wsl ls). Nangona olu luphuculo olubonakalayo, olu khetho luneengxaki ezininzi.

  • Ukongezwa kwendawo yonke wsl edinayo kwaye ayiyondalo.
  • Iindlela ze-Windows kwiingxoxo azisoloko zisebenza kuba ii-backslashs zitolikwa njengoonobumba ababalekayo kunezahluli zolawulo.
  • Iindlela zeWindows kwiingxoxo aziguqulelwanga kwindawo yokunyuka ehambelanayo kwi-WSL.
  • Useto oluhlala lukhona aluhlonitshwa kwiiprofayile zeWSL ezineziteketiso kunye noguquko lwemekobume.
  • Ukugqitywa kwendlela yeLinux ayixhaswanga.
  • Ukugqitywa komyalelo awuxhaswa.
  • Ukugqitywa kwengxoxo akuxhaswa.

Ngenxa yoko, imiyalelo yeLinux iphathwa njengabemi bodidi lwesibini phantsi kweWindows-kwaye kunzima kakhulu ukuyisebenzisa kunemiyalelo yemveli. Ukulinganisa amalungelo abo, kuyimfuneko ukusombulula iingxaki ezidwelisiweyo.

PowerShell umsebenzi wrappers

Ngokusonga umsebenzi wePowerShell, singongeza ukugqitywa komyalelo kwaye sisuse imfuno yezimaphambili wsl, ukuguqulela iindlela zeWindows kwiindlela zeWSL. Iimfuno ezisisiseko zamaqokobhe:

  • Kumyalelo ngamnye weLinux kufuneka kubekho isisongelo somsebenzi omnye onegama elifanayo.
  • Iqokobhe kufuneka libone umendo weWindows ogqithisiweyo njengeengxoxo kwaye uziguqulele kwiindlela ze-WSL.
  • Iqokobhe kufuneka lifowune wsl ngomyalelo ofanelekileyo weLinux kulo naliphi na igalelo lombhobho kwaye ugqithise naziphi na iingxoxo zelayini yomyalelo ezigqithiselwe kumsebenzi.

Ukusukela ukuba le pateni inokusetyenziswa kuwo nawuphi na umyalelo, sinokutsala inkcazo yala ma-wrappers kwaye sivelise ngokwamandla kuluhlu lwemiyalelo yokuthatha ngaphandle.

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

Uluhlu lwe $command ichaza imiyalelo yokungenisa elizweni. Emva koko sivelisa ngokuguquguqukayo isisongelo somsebenzi ngamnye kubo usebenzisa umyalelo Invoke-Expression (ngokuqala ngokususa naziphi na iziteketiso ezinokungqubana nomsebenzi).

Umsebenzi uphinda ngaphezulu kweengxoxo zomgca womyalelo, umisela iindlela zeWindows usebenzisa imiyalelo Split-Path и Test-Pathkwaye ke iguqulela le mendo kwiindlela ze-WSL. Siqhuba iindlela ngomsebenzi womncedisi Format-WslArgument, esiza kuyichaza kamva. Iphepha amagama akhethekileyo anje ngezithuba kunye nezibiyeli ebenokungatolikwa ngendlela engeyiyo.

Ekugqibeleni, sidlulisela wsl igalelo lombhobho kunye naziphi na iingxoxo zomgca womyalelo.

Ngezi wrappers ungabiza imiyalelo yakho yeLinux oyithandayo ngendlela yendalo ngaphandle kokongeza isimaphambili wsl kwaye ngaphandle kokukhathazeka malunga nendlela eziguqulwa ngayo iindlela:

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

Iseti esisiseko yemiyalelo ibonisiwe apha, kodwa ungenza iqokobhe lawo nawuphi na umyalelo weLinux ngokudibanisa ngokulula kuluhlu. Ukuba wongeza le khowudi kweyakho iprofayili I-PowerShell, le miyalelo iya kufumaneka kuwe kuyo yonke iseshoni ye-PowerShell, njengemiyalelo yemveli!

Imimiselo ehlala ikho

KwiLinux, iqhelekile ukuchaza iziteketiso kunye/okanye iimeko-bume eziguquguqukayo kwiinkangeleko zokungena, ukucwangcisa iparameters engagqibekanga kwimiyalelo esetyenziswa rhoqo (umzekelo, alias ls=ls -AFh okanye export LESS=-i). Enye yezinto ezingalunganga zokusebenzisa i-proxy ngeqokobhe elingasebenziyo wsl.exe - ukuba iiprofayili azilayishwanga, ngoko ke olu khetho alufumaneki ngokungagqibekanga (okt. ls kwi-WSL kunye wsl ls iyakuziphatha ngokwahlukileyo ngesibizo esichazwe ngasentla).

I-PowerShell ibonelela $PSDefaultParameterValues, indlela esemgangathweni yokuchaza iparameters ezingagqibekanga, kodwa kuphela kwi cmdlets kunye nemisebenzi ephambili. Ewe kunjalo, sinokwenza imisebenzi ephucukileyo kumaqokobhe ethu, kodwa oku kwazisa iingxaki ezingeyomfuneko (umzekelo, iPowerShell inxibelelanisa amagama eparameter (umzekelo, -a ihambelana ne -ArgumentList), eya kungquzulana nemiyalelo yeLinux ethatha amagama angaphelelanga njengeengxoxo), kunye nesintaksi sokuchaza okungagqibekanga akusayi kuba yeyona ifanelekileyo (ukuchaza iimpikiswano ezingagqibekanga kufuna igama lepharamitha kwisitshixo, hayi nje igama lomyalelo).

Nangona kunjalo, ngokuguqulwa okuncinci kwiigobolondo zethu, sinokusebenzisa imodeli efana nayo $PSDefaultParameterValues, kwaye wenze ukhetho olungagqibekanga lwemiyalelo yeLinux!

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 ' ')
    }
}

Ukupasa $WslDefaultParameterValues kumgca womyalelo, sithumela iiparameters nge wsl.exe. Oku kulandelayo kubonisa indlela yokongeza imiyalelo kwiprofayile yakho yePowerShell ukumisela useto olungagqibekanga. Ngoku singayenza!

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

Ekubeni iiparameters zenziwe ngokomzekelo $PSDefaultParameterValues, Unga kulula ukuzikhubaza okwethutyana ngokufaka isitshixo "Disabled" kwintsingiselo $true. Inzuzo eyongezelelweyo yetafile ye-hash eyahlukileyo kukukwazi ukukhubaza $WslDefaultParameterValues ngokwahlukileyo kwi $PSDefaultParameterValues.

Ukugqitywa kwengxoxo

I-PowerShell ikuvumela ukuba ubhalise iitrailer zengxabano usebenzisa umyalelo Register-ArgumentCompleter. I-Bash inamandla izixhobo zokugqibezela ngokuzenzekelayo ezicwangcisekileyo. I-WSL ikuvumela ukuba ufowunele i-bash kwi-PowerShell. Ukuba sinokubhalisa ukugqityezelwa kweengxoxo zePowerShell yethu yokugoqa umsebenzi kwaye sifowunele i-bash ukuvelisa ukugqitywa, sifumana ukugqitywa kwengxoxo epheleleyo ngokuchaneka okufanayo ne-bash ngokwayo!

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

Ikhowudi ixinene ngaphandle kokuqonda eminye yemisebenzi yangaphakathi ye-bash, kodwa eyona nto siyenzayo yile:

  • Ukubhalisa umgqibeli wengxabano kuwo wonke umsebenzi wethu wokusonga ngokugqithisa uluhlu $commands kwipharamitha -CommandName kuba Register-ArgumentCompleter.
  • Senza imephu yomyalelo ngamnye kumsebenzi weqokobhe olusetyenziswa yi-bash ukugqibezela ngokuzenzekelayo (ukuchaza ugqibo oluzenzekelayo oluzenzekelayo, ukusetyenziswa kwe-bash $F, isifinyezo se complete -F <FUNCTION>).
  • Ukuguqula iingxoxo zePowerShell $wordToComplete, $commandAst и $cursorPosition kwifomati elindelekileyo yi-bash's autocompletion function ngokwemigaqo ukugqibezela okuzenzekelayo okucwangcisekileyo bash.
  • Siqulunqa umgca womyalelo oza kudluliselwa kuwo wsl.exe, eqinisekisa ukuba imo engqongileyo imiselwe ngokuchanekileyo, ibiza umsebenzi ofanelekileyo wokugqibezela ngokuzenzekelayo, kwaye ikhupha iziphumo ngendlela yomgca-ngomgca.
  • Emva koko siyabiza wsl ngomgca womyalelo, sahlula imveliso ngabahluli belayini kwaye sivelise nganye CompletionResults, ukuwahlela nokubaleka iimpawu ezifana nezikhewu nezibiyeli ebenokungatolikwa gwenxa ngenye indlela.

Ngenxa yoko, iiqokobhe zethu zomyalelo weLinux ziya kusebenzisa kanye ukugqibezela okuzenzekelayo okufanayo njenge-bash! Umzekelo:

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

Ukuzigqibezela ngakunye kubonelela amaxabiso angqale kwingxoxo yangaphambili, ukufunda idatha yoqwalaselo efana nenginginya eyaziwayo evela kwiWSL!

<TAB> iyakujikeleza iparameters. <Ctrl + пробел> izakubonisa zonke iinketho ezikhoyo.

Kwaye, kuba ngoku sinokugqibezela okuzenzekelayo kwe-bash, unokugqibezela iindlela zeLinux ngokuthe ngqo kwiPowerShell!

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

Kwiimeko apho ukugqiba ngokuzenzekelayo kwe-bash kungavelisi naziphi na iziphumo, i-PowerShell ibuyela kwiindlela zeWindows ezingagqibekanga. Ke, ekusebenzeni, ungasebenzisa ngaxeshanye zombini iindlela ngokubona kwakho.

isiphelo

Ukusebenzisa i-PowerShell kunye ne-WSL, sinokudibanisa imiyalelo ye-Linux kwi-Windows njengezicelo zendalo. Akukho mfuneko yokukhangela iWin32 yokwakha okanye iLinux eziluncedo okanye uphazamise ukuhamba kwakho ngokuya kwiqokobhe leLinux. Nje faka i-WSL, qwalasela Iprofayile yePowerShell и dwelisa imiyalelo ofuna ukuyingenisa ngaphandle! Ukuzigqibezela okutyebileyo kweLinux kunye neeparamitha zomyalelo weWindows kunye neendlela zefayile kukusebenza okungafumanekiyo nakwimiyalelo yemveli yeWindows namhlanje.

Ikhowudi yomthombo ogcweleyo echazwe ngasentla, kunye nezikhokelo ezongezelelweyo zokuyibandakanya kuhambo lwakho lomsebenzi, iyafumaneka apha.

Yeyiphi imiyalelo yeLinux oyifumana iluncedo kakhulu? Ziziphi ezinye izinto eziqhelekileyo ezingekhoyo xa usebenza kwiWindows? Bhala kwizimvo okanye kwiGitHub!

umthombo: www.habr.com

Yongeza izimvo