Ho kopanya litaelo tsa Linux ho Windows ho sebelisa PowerShell le WSL

Potso e tloaelehileng e tsoang ho baetsi ba Windows: "Hobaneng ho se na <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Hore na ke swipe e matla less kapa lisebelisoa tse tloaelehileng grep kapa sed, Baetsi ba Windows ba batla ho fumana litaelo tsena habonolo mosebetsing oa bona oa letsatsi le letsatsi.

Windows Subsystem bakeng sa Linux (WSL) e hatetse pele haholo ntlheng ena. E u lumella ho letsetsa litaelo tsa Linux ho tsoa ho Windows ka ho li etsa proxy wsl.exe (mohlala. wsl ls). Leha sena e le ntlafatso e kholo, khetho ena e na le mefokolo e mengata.

  • Keketso e fumanehang hohle wsl e tenang ebile e seng tlhaho.
  • Litsela tsa Windows litabeng tsa likhang ha li sebetse kamehla hobane li-backslash li hlalosoa e le litlhaku tse balehang ho e-na le ho arola libuka.
  • Litsela tsa Windows ka likhang ha li fetoleloe sebakeng se lumellanang sa WSL.
  • Litlhophiso tsa kamehla ha li hlomphuoe liprofaeleng tsa WSL tse nang le li-aliases le maemo a fapaneng a tikoloho.
  • Ho phethela tsela ea Linux ha hoa tšehetsoa.
  • Ho phethela taelo ha hoa tšehetsoa.
  • Ho phethela khang ha hoa tšehetsoa.

Ka lebaka leo, litaelo tsa Linux li tšoaroa joalo ka baahi ba boemo ba bobeli tlasa Windows — 'me ho thata ho li sebelisa ho feta litaelo tsa matsoalloa. Ho leka-lekanya litokelo tsa bona, ho hlokahala ho rarolla mathata a thathamisitsoeng.

Lisebelisoa tsa ts'ebetso ea PowerShell

Ka li-wrappers tsa ts'ebetso ea PowerShell, re ka eketsa ho phethela taelo le ho tlosa tlhoko ea lihlomathiso wsl, ho fetolela litsela tsa Windows ho litsela tsa WSL. Litlhoko tsa mantlha tsa likhetla:

  • Bakeng sa taelo e 'ngoe le e' ngoe ea Linux ho tlameha ho ba le sekoahelo se le seng sa mosebetsi se nang le lebitso le tšoanang.
  • Khetla e tlameha ho lemoha litsela tsa Windows tse fetisitsoeng e le likhang le ho li fetolela ho litsela tsa WSL.
  • Khetla e lokela ho letsa wsl ka taelo e nepahetseng ea Linux ho kenyelletso efe kapa efe ea liphaephe le ho fetisa likhang life kapa life tsa mola oa taelo tse fetiselitsoeng tšebetsong.

Kaha mokhoa ona o ka sebelisoa ho taelo leha e le efe, re ka hula tlhaloso ea li-wrappers tsena 'me ra li hlahisa ka matla ho tsoa lethathamong la litaelo tse lokelang ho kenngoa.

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

Lethathamo la $command e hlalosa ditaelo tsa ho reka kantle ho naha. Ka mor'a moo re hlahisa sekoahelo sa ts'ebetso bakeng sa e mong le e mong oa bona a sebelisa taelo Invoke-Expression (ka ho qala ka ho tlosa mabitso afe kapa afe a ka hananang le mosebetsi).

Ts'ebetso e pheta-pheta likhang tsa mola oa taelo, e khetha litsela tsa Windows ho sebelisa litaelo Split-Path и Test-Pathebe o fetolela litsela tsena ho litsela tsa WSL. Re tsamaisa litsela ka ts'ebetso ea mothusi Format-WslArgument, eo re tla e hlalosa hamorao. E phonyoha litlhaku tse khethehileng tse kang likheo le masakakana tse neng li ka hlalosoa hampe.

Qetellong, re fetisa wsl pipeline input le likhang life kapa life tsa mola oa taelo.

Ka li-wrappers tsena u ka bitsa litaelo tsa Linux tseo u li ratang ka tsela ea tlhaho ntle le ho eketsa sehlomathiso wsl le ntle le ho tšoenyeha ka hore na litsela li fetoloa joang:

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

Litaelo tsa mantlha li bonts'oa mona, empa o ka etsa khetla bakeng sa taelo efe kapa efe ea Linux ka ho e kenyelletsa feela lenaneng. Haeba u eketsa khoutu ena ho ea hau boemo PowerShell, litaelo tsena li tla fumaneha ho uena lenaneong le leng le le leng la PowerShell, joalo ka litaelo tsa matsoalloa!

Litlhophiso tsa kamehla

Ho Linux, ho tloaelehile ho hlalosa li-aliases le/kapa maemo a fapaneng a tikoloho liprofinseng tsa ho kena, ho beha maemo a kamehla bakeng sa litaelo tse sebelisoang khafetsa (mohlala, alias ls=ls -AFh kapa export LESS=-i). E 'ngoe ea mefokolo ea ho ba moemeli ka khetla e sa sebelisaneng wsl.exe - hore li-profile ha li laeloe, kahoo likhetho tsena ha li fumanehe ka mokhoa o ikhethileng (ke hore. ls ho WSL le wsl ls e tla itšoara ka tsela e fapaneng le mabitso a hlalositsoeng ka holimo).

PowerShell e fana ka $PSDefaultParameterValues, mochine o tloaelehileng oa ho hlalosa li-parameter tsa kamehla, empa feela bakeng sa cmdlets le mesebetsi e tsoetseng pele. Ehlile, re ka etsa mesebetsi e tsoetseng pele ho tsoa ho likhetla tsa rona, empa sena se hlahisa mathata a sa hlokahaleng (mohlala, PowerShell e hokahanya mabitso a parameter (mohlala, -a e tsamaellana le -ArgumentList), e tla hanyetsana le litaelo tsa Linux tse nkang mabitso a sa fellang e le likhang), 'me syntax ea ho hlalosa litekanyetso tsa kamehla e ke ke ea e-ba eona e nepahetseng ka ho fetisisa (likhang tsa kamehla li hloka lebitso la parameter ho senotlolo, eseng lebitso la taelo feela) .

Leha ho le joalo, ka phetoho e fokolang ho likhetla tsa rona, re ka kenya ts'ebetsong mohlala o tšoanang le $PSDefaultParameterValues, 'me u lumelle likhetho tsa kamehla bakeng sa litaelo tsa 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 ' ')
    }
}

Ho feta $WslDefaultParameterValues ho mola oa taelo, re romella liparamente ka wsl.exe. Lintlha tse latelang li bontša mokhoa oa ho kenya litaelo profaeleng ea hau ea PowerShell ho hlophisa litlhophiso tsa kamehla. Joale re ka e etsa!

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

Kaha li-parameter li entsoe ka mor'a $PSDefaultParameterValues, U ka khona ho bonolo ho li thibela nakoana ka ho kenya senotlolo "Disabled" ho ba le moelelo $true. Molemo o mong oa tafole e arohaneng ea hash ke bokhoni ba ho tima $WslDefaultParameterValues ka thoko ho $PSDefaultParameterValues.

Qetello ya ngangisano

PowerShell e u lumella ho ngolisa li-trailer tsa likhang u sebelisa taelo Register-ArgumentCompleter. Bash e na le matla lisebelisoa tsa ho phethela li-auto-programme. WSL e u lumella ho letsetsa bash ho tsoa ho PowerShell. Haeba re ka ngolisa phetho ea likhang bakeng sa li-wrappers tsa ts'ebetso ea PowerShell le ho letsetsa bash ho hlahisa liphetho, re fumana phehisano e felletseng ka nepo e tšoanang le ea bash ka boeona!

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

Khoutu e teteaneng ntle le ho utloisisa tse ling tsa mesebetsi ea kahare ea bash, empa ha e le hantle seo re se etsang ke sena:

  • Ho ngolisa motlatsi oa likhang bakeng sa li-wrappers tsohle tsa rona ka ho fetisa lenane $commands ka parameter -CommandName etsoe Register-ArgumentCompleter.
  • Re etsa 'mapa oa taelo e' ngoe le e 'ngoe bakeng sa ts'ebetso ea khetla eo bash e e sebelisang bakeng sa ho phethela ka boits'oaro (ho hlalosa litlhaloso tsa autocompletion, tšebeliso ea bash $F, khutsufatso ea complete -F <FUNCTION>).
  • Ho Fetola Likhang tsa PowerShell $wordToComplete, $commandAst и $cursorPosition ka sebopeho se lebelletsoeng ke mesebetsi ea bash's autocompletion ho latela litlhaloso ho phethela ka tsela e hlophisehang bash.
  • Re qapa mola oa taelo ho fetisetsa ho wsl.exe, e etsang bonnete ba hore tikoloho e behiloe ka nepo, e bitsa mosebetsi o loketseng oa ho tlatsa ka boits'oaro, 'me e hlahisa liphetho ka mokhoa oa line-by-line.
  • Ebe rea bitsa wsl ka mola oa taelo, re arola lihlahisoa ka li-separators tsa mela le ho hlahisa bakeng sa e 'ngoe le e' ngoe CompletionResults, ho li hlopha le litlhaku tse phonyohang tse kang likheo le masakakana tse neng li ka hlalosoa hampe.

Ka lebaka leo, likhetla tsa rona tsa taelo ea Linux li tla sebelisa autocompletion e ts'oanang hantle le bash! Ka mohlala:

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

Katoloso e 'ngoe le e' ngoe ea boiketsetso e fana ka boleng bo ikhethileng khang e fetileng, ho bala lintlha tsa tlhophiso joalo ka mabotho a tsebahalang a tsoang ho WSL!

<TAB> e tla potoloha liparamente. <Ctrl + пробел> e tla bontša likhetho tsohle tse fumanehang.

Hape, kaha joale re na le bash autocompletion, u ka iketsetsa litsela tsa Linux ka kotloloho ho PowerShell!

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

Maemong ao bash autocompletion e sa hlahiseng liphetho, PowerShell e khutlela mekhoeng ea kamehla ea Windows. Ka hona, ts'ebetsong, u ka sebelisa litsela tse peli ka nako e le 'ngoe ka boikhethelo ba hau.

fihlela qeto e

Re sebelisa PowerShell le WSL, re ka kopanya litaelo tsa Linux ho Windows joalo ka lits'ebetso tsa lehae. Ha ho na tlhoko ea ho batla lisebelisoa tsa Win32 kapa lisebelisoa tsa Linux kapa ho sitisa ts'ebetso ea hau ka ho ea ho khetla ea Linux. Feela kenya WSL, lokisa Profaele ea PowerShell и thathamisa litaelo tseo u batlang ho li kenya! Tlatsetso e ruileng ea li-auto complement tsa Linux le Windows le litsela tsa faele ke ts'ebetso e sa fumaneheng le ho litaelo tsa Windows tsa matsoalloa kajeno.

Khoutu e felletseng ea mohloli e hlalositsoeng kaholimo, hammoho le litataiso tse ling tsa ho e kenyelletsa tšebetsong ea hau ea mosebetsi, lia fumaneha mona.

Ke litaelo life tsa Linux tseo u fumanang li le molemo haholo? Ke lintho life tse ling tse tloaelehileng tse haellang ha u sebetsa Windows? Ngola maikutlong kapa ho GitHub!

Source: www.habr.com

Eketsa ka tlhaloso