Orduithe Linux a chomhtháthú le Windows ag baint úsáide as PowerShell agus WSL

Ceist tipiciúil ó fhorbróirí Windows: “Cén fáth nach bhfuil aon cheist ann go fóill <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Cibé an swipe cumhachtach é less nó uirlisí aithnidiúla grepsed, Ba mhaith le forbróirí Windows rochtain éasca ar na horduithe seo ina gcuid oibre laethúil.

Fochóras Windows le haghaidh Linux (WSL) Tá céim mhór chun tosaigh déanta aige maidir leis seo. Ligeann sé duit orduithe Linux a ghlaoch ó Windows trína seachfhreastalaí wsl.exe (e.e. wsl ls). Cé gur feabhas suntasach é seo, tá roinnt míbhuntáistí ag baint leis an rogha seo.

  • Chomh maith leis uileláithreach wsl tedious agus mínádúrtha.
  • Ní i gcónaí a oibríonn cosáin Windows in argóintí toisc go léirítear cúlslais mar charachtair éalaithe seachas mar dheighilteoirí eolaire.
  • Ní aistrítear cosáin Windows in argóintí go dtí an pointe gléasta comhfhreagrach i WSL.
  • Ní urramaítear socruithe réamhshocraithe i bpróifílí WSL a bhfuil ailiasanna agus athróga timpeallachta acu.
  • Ní thacaítear le críochnú conair Linux.
  • Ní thacaítear le críochnú ordú.
  • Ní thacaítear le críochnú na hargóintí.

Mar thoradh air sin, caitear le horduithe Linux cosúil le saoránaigh den dara grád faoi Windows - agus tá siad níos deacra a úsáid ná orduithe dúchais. Chun a gcearta a chomhionannú, is gá na fadhbanna atá liostaithe a réiteach.

Cumhdaigh feidhm PowerShell

Le fillteáin feidhm PowerShell, is féidir linn críochnú ordaithe a chur leis agus deireadh a chur leis an ngá atá le réimíreanna wsl, ag aistriú cosáin Windows go cosáin WSL. Bunriachtanais maidir le sliogáin:

  • I gcás gach ordú Linux ní mór go mbeadh fillteán feidhm amháin leis an ainm céanna.
  • Caithfidh an bhlaosc na cosáin Windows a ritheadh ​​mar argóintí a aithint agus iad a thiontú go cosáin WSL.
  • Ba chóir an bhlaosc glaoch wsl leis an ordú Linux cuí chuig aon ionchur píblíne agus ag dul thar aon argóintí ordú a chuirtear ar aghaidh chuig an bhfeidhm.

Ós rud é gur féidir an patrún seo a chur i bhfeidhm ar aon ordú, is féidir linn an sainmhíniú ar na cumhdaigh seo a theibí agus iad a ghiniúint go dinimiciúil ó liosta orduithe le hiompórtáil.

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

Liosta $command sainmhíníonn orduithe allmhairithe. Ginimid ansin fillteán feidhme go dinimiciúil do gach ceann acu ag baint úsáide as an ordú Invoke-Expression (trí aon ailiasanna a bheadh ​​contrártha leis an bhfeidhm a bhaint ar dtús).

Athdhearbhaíonn an fheidhm argóintí na n-orduithe, cinneann sé cosáin Windows ag baint úsáide as orduithe Split-Path и Test-Pathagus ansin athraíonn na cosáin seo go cosáin WSL. Ritheann muid na cosáin trí fheidhm cúntóir Format-WslArgument, a shaineoimid níos déanaí. Éalaíonn sé carachtair speisialta ar nós spásanna agus lúibíní a ndéanfaí míthuiscint orthu murach sin.

Ar deireadh, táimid in iúl wsl ionchur píblíne agus aon argóintí ordaithe.

Leis na fillteáin seo is féidir leat na horduithe Linux is fearr leat a ghlaoch ar bhealach níos nádúrtha gan réimír a chur leis wsl agus gan a bheith buartha faoi mar a dhéantar na cosáin a thiontú:

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

Taispeántar an bunsraith orduithe anseo, ach is féidir leat blaosc a chruthú le haghaidh aon ordú Linux ach é a chur leis an liosta. Má chuireann tú an cód seo le do próifíl PowerShell, beidh na horduithe seo ar fáil duit i ngach seisiún PowerShell, díreach cosúil le horduithe dúchais!

Socruithe Réamhshocraithe

I Linux, is coitianta ailiasanna agus/nó athróga timpeallachta a shainiú i bpróifílí logála isteach, ag socrú paraiméadair réamhshocraithe le haghaidh orduithe a úsáidtear go minic (mar shampla, alias ls=ls -AFhexport LESS=-i). Ceann de na míbhuntáistí a bhaineann le seachfhreastalaí trí bhlaoscán neamh-idirghníomhach wsl.exe - nach bhfuil na próifílí luchtaithe, mar sin níl na roghanna seo ar fáil de réir réamhshocraithe (i.e. ls i WSL agus wsl ls iad féin a iompar ar bhealach difriúil leis an ailias atá sainmhínithe thuas).

Soláthraíonn PowerShell $PSDefaultParameterValues, meicníocht chaighdeánach chun paraiméadair réamhshocraithe a shainiú, ach amháin le haghaidh cmdlets agus feidhmeanna chun cinn. Ar ndóigh, is féidir linn feidhmeanna chun cinn a dhéanamh as ár sliogáin, ach tugann sé seo isteach deacrachtaí neamhriachtanach (mar shampla, PowerShell comhghaolú ainmneacha paraiméadar páirteach (mar shampla, -a comhghaol le -ArgumentList), a bheidh i gcoimhlint le horduithe Linux a ghlacann ainmneacha páirteach mar argóintí), agus ní bheidh an chomhréir chun luachanna réamhshocraithe a shainiú an ceann is oiriúnaí (éilíonn argóintí réamhshocraithe ainm an pharaiméadar san eochair, ní hamháin an t-ainm ordaithe) .

Mar sin féin, le modhnú beag ar ár sliogáin, is féidir linn múnla cosúil leis a chur i bhfeidhm $PSDefaultParameterValues, agus cumasaigh roghanna réamhshocraithe le haghaidh orduithe 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 ' ')
    }
}

Trí tharchur $WslDefaultParameterValues chuig an líne ordaithe, cuirimid paraiméadair trí wsl.exe. Léiríonn an méid seo a leanas conas treoracha a chur le do phróifíl PowerShell chun socruithe réamhshocraithe a chumrú. Anois is féidir linn é a dhéanamh!

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

Ós rud é go ndéantar na paraiméadair a mhúnlú i ndiaidh $PSDefaultParameterValues, Is féidir leat tá sé éasca iad a dhíchumasú go sealadach tríd an eochair a shuiteáil "Disabled" isteach sa chiall $true. Buntáiste breise a bhaineann le tábla hash ar leith ná an cumas díchumasaithe $WslDefaultParameterValues ar leithligh ó $PSDefaultParameterValues.

Argóint a chríochnú

Ligeann PowerShell duit leantóirí argóinte a chlárú ag baint úsáide as an ordú Register-ArgumentCompleter. Tá cumhachtach ag Bash uirlisí uath-chríochnaithe ríomhchláraithe. Ligeann WSL duit bash a ghlaoch ó PowerShell. Más féidir linn críochnuithe argóinte a chlárú le haghaidh ár gcumhdaigh feidhm PowerShell agus bash glaonna chun na críochnuithe a ghiniúint, faighimid críochnú argóint iomlán leis an cruinneas céanna leis an bash féin!

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

Tá an cód beagán dlúth gan tuiscint a fháil ar chuid d'fheidhmeanna inmheánacha bash, ach go bunúsach is é seo a dhéanaimid:

  • Comhlánaitheoir argóint a chlárú dár gcumhdaigh feidhme go léir trí liosta a rith $commands isteach i bparaiméadar -CommandName le haghaidh Register-ArgumentCompleter.
  • Mapálaimid gach ordú go dtí an fheidhm bhlaosc a úsáideann bash le haghaidh uathchríochnú (chun sonraíochtaí uathchríochnaithe, úsáidí bash a shainiú $F, giorrúchán le haghaidh complete -F <FUNCTION>).
  • Argóintí PowerShell a Thiontú $wordToComplete, $commandAst и $cursorPosition isteach san fhormáid a bhfuiltear ag súil le feidhmeanna uathchríochnaithe bash de réir na sonraíochtaí uathchríochnú ríomhchláraithe bash.
  • Déanaimid líne ordaithe le haistriú go dtí wsl.exe, a chinntíonn go gcuirtear an timpeallacht ar bun i gceart, glaonna an fheidhm uathoibríoch-chríochnaithe cuí, agus aschuireann sé na torthaí ar bhealach líne-ar-líne.
  • Ansin tugaimid wsl Leis an líne ordaithe, scaraimid an t-aschur de réir deighilteoirí líne agus ginimid do gach ceann acu CompletionResults, iad a shórtáil agus éalú ó charachtair ar nós spásanna agus lúibíní a ndéanfaí míthuiscint orthu murach sin.

Mar thoradh air sin, úsáidfidh ár sliogáin orduithe Linux go díreach an uathchríochnú céanna le bash! Mar shampla:

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

Soláthraíonn gach uathchríochnú luachanna a bhaineann go sonrach leis an argóint roimhe seo, ag léamh sonraí cumraíochta cosúil le hóstach aitheanta ó WSL!

<TAB> timthriall trí na paraiméadair. <Ctrl + пробел> taispeánfaidh sé na roghanna go léir atá ar fáil.

Ina theannta sin, ós rud é go bhfuil uathchríochnú bash againn anois, is féidir leat cosáin Linux a uathchríochnú go díreach i PowerShell!

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

I gcásanna nach dtugann uathchríochnú bash aon torthaí, téann PowerShell ar ais chuig cosáin réamhshocraithe an chórais Windows. Mar sin, go praiticiúil, is féidir leat an dá chonair a úsáid ag an am céanna de do rogha féin.

Conclúid

Ag baint úsáide as PowerShell agus WSL, is féidir linn orduithe Linux a chomhtháthú isteach i Windows mar fheidhmchláir dhúchasacha. Ní gá cuardach a dhéanamh le haghaidh tógálacha Win32 nó fóntais Linux ná cur isteach ar do shreabhadh oibre trí dhul chuig sliogán Linux. Díreach shuiteáil WSL, a chumrú Próifíl PowerShell и liostaigh na horduithe is mian leat a iompórtáil! Is feidhmiúlacht é uathchríochnú saibhir le haghaidh paraiméadair orduithe Linux agus Windows agus cosáin comhaid nach bhfuil ar fáil fiú in orduithe dúchais Windows inniu.

Tá an cód foinse iomlán a gcuirtear síos air thuas, chomh maith le treoirlínte breise chun é a ionchorprú isteach i do shreabhadh oibre, ar fáil anseo.

Cé na horduithe Linux is úsáidí duit? Cad iad na rudaí coitianta eile atá in easnamh agus tú ag obair i Windows? Scríobh sna tuairimí nó ar GitHub!

Foinse: will.com

Add a comment