Hoʻohui i nā kauoha Linux i Windows me ka hoʻohana ʻana i PowerShell a me WSL

ʻO kahi nīnau maʻamau mai nā mea hoʻomohala Windows: "No ke aha i loaʻa ʻole ai <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Inā paha he swipe ikaika less a i ʻole nā ​​mea hana maʻa grep ai ole ia, sed, Makemake nā mea hoʻomohala Windows i ke komo maʻalahi i kēia mau kauoha i kā lākou hana i kēlā me kēia lā.

Windows Subsystem no Linux (WSL) ua hana nui i mua ma keia mea. Hiki iā ʻoe ke kāhea i nā kauoha Linux mai Windows ma ke koho ʻana iā lākou wsl.exe (e laʻa, wsl ls). ʻOiai he hoʻomaikaʻi koʻikoʻi kēia, pilikia kēia koho i kekahi mau hemahema.

  • Hoʻohui like ʻole wsl luuluu a ano maoli.
  • ʻAʻole hana mau nā ala Windows i nā hoʻopaʻapaʻa no ka mea ua unuhi ʻia nā backslashes ma ke ʻano he mau mea pakele ma mua o nā mea hoʻokaʻawale papa kuhikuhi.
  • ʻAʻole unuhi ʻia nā ala Windows ma nā hoʻopaʻapaʻa i ke kiko mauna i WSL.
  • ʻAʻole mahalo ʻia nā hoʻonohonoho paʻamau i nā moʻolelo WSL me nā inoa inoa a me nā ʻano hoʻololi kaiapuni.
  • ʻAʻole kākoʻo ʻia ka pau ʻana o ke ala Linux.
  • ʻAʻole kākoʻo ʻia ka hoʻopau kauoha.
  • ʻAʻole kākoʻo ʻia ka hoʻokō ʻana i ka hoʻopaʻapaʻa.

ʻO ka hopena, mālama ʻia nā kauoha Linux e like me nā kamaʻāina papa lua ma lalo o Windows-a ʻoi aku ka paʻakikī o ka hoʻohana ʻana ma mua o nā kauoha maoli. No ka hoʻohālikelikeʻana i ko lākou mau pono, pono e hoʻoponopono i nā pilikia i heluʻia.

Nā mea hoʻopili hana PowerShell

Me nā mea hoʻopili hana PowerShell, hiki iā mākou ke hoʻohui i ka hoʻopau kauoha a hoʻopau i ka pono no nā prefix wsl, unuhi i nā ala Windows i nā ala WSL. Nā pono kumu no nā pūpū:

  • No kēlā me kēia kauoha Linux pono e loaʻa i hoʻokahi ʻāpana hana me ka inoa like.
  • Pono ka pūpū e ʻike i nā ala Windows i hala ma ke ʻano he hoʻopaʻapaʻa a hoʻololi iā lākou i nā ala WSL.
  • Pono ka pūpū e kāhea wsl me ke kauoha Linux kūpono i kekahi hoʻokomo pipeline a hāʻawi i nā manaʻo laina kauoha i hāʻawi ʻia i ka hana.

No ka mea hiki ke hoʻohana ʻia kēia ʻano i kekahi kauoha, hiki iā mākou ke hoʻokaʻawale i ka wehewehe ʻana o kēia mau wīwī a hoʻoulu ikaika iā lākou mai kahi papa inoa o nā kauoha e lawe mai.

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

papa inoa $command wehewehe i nā kauoha hoʻokomo. A laila hoʻoulu mākou i kahi wrapper hana no kēlā me kēia me ka hoʻohana ʻana i ke kauoha Invoke-Expression (ma ka wehe mua ʻana i nā inoa inoa e hakakā me ka hana).

Hoʻomaka ka hana ma luna o nā manaʻo hoʻopaʻapaʻa laina kauoha, e hoʻoholo i nā ala Windows me nā kauoha Split-Path и Test-Patha laila hoʻololi i kēia mau ala i nā ala WSL. Holo mākou i nā ala ma o kahi hana kōkua Format-WslArgument, a mākou e wehewehe ai ma hope. Pakele ia i nā huaʻōlelo kūikawā e like me nā hakahaka a me nā pale i hiki ke kuhi hewa ʻia.

ʻO ka hope, hōʻike mākou wsl hoʻokomo pipeline a me nā hoʻopaʻapaʻa laina kauoha.

Me kēia mau wīwī hiki iā ʻoe ke kāhea i kāu mau kauoha Linux punahele ma ke ʻano kūlohelohe me ka ʻole o ka hoʻohui ʻana i kahi prefix wsl a me ka hopohopo ʻole e pili ana i ka hoʻohuli ʻia ʻana o nā ala.

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

Hōʻike ʻia ka hoʻonohonoho kumu o nā kauoha ma aneʻi, akā hiki iā ʻoe ke hana i kahi pūpū no kēlā me kēia kauoha Linux ma ka hoʻohui ʻana iā ia i ka papa inoa. Inā ʻoe e hoʻohui i kēia code i kāu РїїЂѕѕ „„ "СЊ PowerShell, e loaʻa iā ʻoe kēia mau kauoha i kēlā me kēia kau PowerShell, e like me nā kauoha maoli!

Nā hoʻonohonoho paʻamau

Ma Linux, he mea maʻamau ka wehewehe ʻana i nā inoa inoa a/a i ʻole nā ​​ʻano hoʻololi kaiapuni ma nā ʻaoʻao hoʻopaʻa inoa, e hoʻonohonoho ana i nā ʻāpana paʻamau no nā kauoha i hoʻohana pinepine ʻia (no ka laʻana, alias ls=ls -AFh ai ole ia, export LESS=-i). ʻO kekahi o nā hemahema o ka hoʻololi ʻana ma o ka pūpū non-interactive wsl.exe - ʻaʻole i hoʻouka ʻia nā profiles, no laila ʻaʻole i loaʻa kēia mau koho ma ke ʻano maʻamau (ʻo ia hoʻi. ls ma WSL a wsl ls e hana ʻokoʻa me ka alias i wehewehe ʻia ma luna).

Hāʻawi ʻo PowerShell $PSDefaultParameterValues, he mīkini maʻamau no ka wehewehe ʻana i nā ʻāpana paʻamau, akā no nā cmdlets a me nā hana holomua. ʻOiaʻiʻo, hiki iā mākou ke hana i nā hana kiʻekiʻe mai loko mai o kā mākou pūpū, akā hoʻopuka kēia i nā hoʻopiʻi pono ʻole (no ka laʻana, hoʻoponopono ʻo PowerShell i nā inoa ʻāpana hapa (no ka laʻana, -a pili me -ArgumentList), ka mea e paio me nā kauoha Linux e lawe i nā inoa ʻāpana ma ke ʻano he hoʻopaʻapaʻa), a ʻo ka syntax no ka wehewehe ʻana i nā waiwai paʻamau ʻaʻole ia e kūpono loa (pono nā manaʻo paʻamau i ka inoa o ka parameter i ke kī, ʻaʻole wale ka inoa kauoha) .

Eia naʻe, me ka hoʻololi iki i kā mākou pūpū, hiki iā mākou ke hoʻokō i kahi hoʻohālike e like me $PSDefaultParameterValues, a hiki i nā koho paʻamau no nā kauoha 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 ' ')
    }
}

e hala ana $WslDefaultParameterValues i ka laina kauoha, hoʻouna mākou i nā ʻāpana ma o wsl.exe. Hōʻike kēia i ka hoʻohui ʻana i nā ʻōlelo aʻoaʻo i kāu ʻaoʻao PowerShell e hoʻonohonoho i nā hoʻonohonoho paʻamau. I kēia manawa hiki iā mākou ke hana!

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

No ka mea, ua hoʻohālike ʻia nā ʻāpana $PSDefaultParameterValueshiki iā ʻoe maʻalahi ke hoʻopau iā lākou no ka manawa pōkole ma ke kau ʻana i ke kī "Disabled" i ke ano $true. ʻO kahi pōmaikaʻi ʻē aʻe o kahi pākaukau hash kaʻawale ka hiki ke hoʻopau $WslDefaultParameterValues kaawale mai $PSDefaultParameterValues.

Paʻa hoʻopaʻapaʻa

Hāʻawi ʻo PowerShell iā ʻoe e hoʻopaʻa inoa i nā huakaʻi hoʻopaʻapaʻa me ka hoʻohana ʻana i ke kauoha Register-ArgumentCompleter. He mana ko Bash nā mea hana hoʻokō ʻakomi hiki ke hoʻolālā. ʻAe ʻo WSL iā ʻoe e kāhea i ka bash mai PowerShell. Inā hiki iā mākou ke hoʻopaʻa inoa i nā hoʻopaʻapaʻa hoʻopaʻapaʻa no kā mākou PowerShell hana wīwī a kāhea aku i ka bash e hana i ka hoʻopau ʻana, loaʻa iā mākou ka hoʻopau hoʻopaʻapaʻa piha me ka pololei like me ka bash ponoʻī!

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

ʻO ke code he ʻano liʻiliʻi me ka ʻole o ka hoʻomaopopo ʻana i kekahi o nā hana o loko o ka bash, akā ʻo ka mea nui kā mākou e hana nei:

  • Ke hoʻopaʻa inoa nei i kahi hoʻopaʻapaʻa hoʻopau no kā mākou mau mea hana a pau ma ka waiho ʻana i kahi papa inoa $commands ma ka palena -CommandName no ka mea, Register-ArgumentCompleter.
  • Mākaukau mākou i kēlā me kēia kauoha i ka hana shell e hoʻohana ai ka bash no ka autocompletion (e wehewehe i nā kikoʻī autocompletion, hoʻohana bash $F, ka pōkole no complete -F <FUNCTION>).
  • Ke hoʻololi nei i nā manaʻo hoʻopaʻapaʻa PowerShell $wordToComplete, $commandAst и $cursorPosition i ke ʻano i manaʻo ʻia e nā hana autocompletion a bash e like me nā kikoʻī hoʻopau ʻakomi polokalamu bash.
  • Hoʻokumu mākou i kahi laina kauoha e hoʻoili i wsl.exe, ka mea e hōʻoiaʻiʻo i ka hoʻonohonoho pono ʻana o ke kaiapuni, kāhea i ka hana hoʻopau auto kūpono, a hoʻopuka i nā hopena ma ke ʻano laina-by-line.
  • A laila kāhea mākou wsl me ka laina kauoha, hoʻokaʻawale mākou i ka hoʻopuka e nā mea hoʻokaʻawale laina a hana i kēlā me kēia CompletionResults, ka hoʻokaʻawale ʻana iā lākou a me ka pakele ʻana i nā huaʻōlelo e like me nā hakahaka a me nā pale i hiki ke kuhi hewa ʻia.

Ma muli o ka hopena, e hoʻohana like kā mākou Linux kauoha i ka autocompletion like me bash! ʻo kahi laʻana:

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

Hāʻawi kēlā me kēia autocompletion i nā waiwai kikoʻī i ka hoʻopaʻapaʻa mua, e heluhelu ana i ka ʻikepili hoʻonohonoho e like me nā pūʻali i ʻike ʻia mai WSL!

<TAB> e pōʻai ma nā ʻāpana. <Ctrl + пробел> e hōʻike i nā koho āpau i loaʻa.

Eia kekahi, ʻoiai ua loaʻa iā mākou ka bash autocompletion, hiki iā ʻoe ke hoʻopiha pololei i nā ala Linux ma PowerShell!

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

I nā hihia i loaʻa ʻole ai nā hopena bash autocompletion, hoʻi hou ʻo PowerShell i nā ala Windows paʻamau. No laila, ma ka hoʻomaʻamaʻa, hiki iā ʻoe ke hoʻohana i nā ala ʻelua i kou manaʻo.

hopena

Ke hoʻohana nei iā PowerShell a me WSL, hiki iā mākou ke hoʻohui i nā kauoha Linux i loko o Windows ma ke ʻano he noi maoli. ʻAʻohe pono e ʻimi no Win32 builds a i ʻole Linux utility a hoʻopau i kāu kaʻina hana ma ka hele ʻana i kahi shell Linux. wale hoʻokomo iā WSL, hoʻonohonoho Hōʻike manaʻo PowerShell и papa inoa i nā kauoha āu e makemake ai e hoʻokomo! ʻO ka autocompletion waiwai no nā ʻāpana kauoha Linux a me Windows a me nā ala faila he hana i loaʻa ʻole i nā kauoha Windows maoli i kēia lā.

Loaʻa ka code kumu piha i hōʻike ʻia ma luna, a me nā alakaʻi ʻē aʻe no ka hoʻokomo ʻana i loko o kāu kaila hana maanei.

ʻO wai nā kauoha Linux āu e ʻike pono ai? He aha nā mea maʻamau ʻē aʻe e nalowale ana i ka wā e hana ana ma Windows? E kākau i nā manaʻo a i ʻole ma GitHub!

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka