Kev sib xyaw Linux cov lus txib rau hauv Windows siv PowerShell thiab WSL
Cov lus nug ib txwm los ntawm Windows developers: “Vim li cas tseem tsis muaj <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. Seb nws yog lub zog los so less los yog cov cuab yeej paub grep los yog sed, Windows developers xav tau yooj yim nkag mus rau cov lus txib hauv lawv cov haujlwm niaj hnub.
Windows Subsystem rau Linux (WSL) tau ua ib kauj ruam loj rau pem hauv ntej ntawm qhov no. Nws tso cai rau koj hu rau Linux cov lus txib los ntawm Windows los ntawm kev tso npe rau lawv wsl.exe (Xws li. wsl ls). Txawm hais tias qhov no yog qhov kev txhim kho tseem ceeb, qhov kev xaiv no raug kev txom nyem los ntawm ntau qhov tsis zoo.
Ubiquitous ntxiv wsl tedious thiab unnatural.
Txoj hauv kev Windows hauv kev sib cav tsis yog ib txwm ua haujlwm vim tias cov backslashes raug txhais ua cov cim khiav tawm es tsis yog cov npe cais.
Txoj hauv kev Windows hauv kev sib cav tsis tau txhais mus rau qhov sib thooj mount point hauv WSL.
Raws li qhov tshwm sim, Linux cov lus txib raug kho zoo li cov pej xeem thib ob hauv qab Windows - thiab nyuaj rau siv dua li cov lus txib ib txwm muaj. Txhawm rau kom sib npaug lawv cov cai, nws yog ib qho tsim nyog los daws cov teeb meem teev tseg.
PowerShell muaj nuj nqi wrappers
Nrog PowerShell muaj nuj nqi wrappers, peb tuaj yeem ntxiv cov lus txib ua tiav thiab tshem tawm qhov xav tau ua ntej wsl, txhais Windows paths rau hauv WSL paths. Cov ntsiab lus tseem ceeb rau cov plhaub:
Rau txhua qhov Linux hais kom ua yuav tsum muaj ib txoj haujlwm wrapper nrog tib lub npe.
Lub plhaub yuav tsum paub txog lub Windows paths dhau los ua kev sib cav thiab hloov mus rau WSL txoj hauv kev.
Lub plhaub yuav tsum hu wsl nrog rau qhov tsim nyog Linux hais kom ua rau cov raj xa dej tawm thiab dhau ib qho kev sib cav hais kom dhau mus rau txoj haujlwm.
Txij li cov qauv no tuaj yeem siv rau txhua qhov kev hais kom ua, peb tuaj yeem paub qhov tseeb ntawm cov ntaub qhwv no thiab ua kom muaj zog los ntawm cov npe ntawm cov lus txib kom import.
# 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 ' ')
}
}
"@
}
Nrog cov wrappers no koj tuaj yeem hu koj nyiam Linux cov lus txib hauv txoj hauv kev zoo dua yam tsis tau ntxiv cov npe ua ntej wsl thiab tsis muaj kev txhawj xeeb txog yuav ua li cas cov kev hloov dua siab tshiab:
man bash
less -i $profile.CurrentUserAllHosts
ls -Al C:Windows | less
grep -Ein error *.log
tail -f *.log
Cov txheej txheem ntawm cov lus txib tau qhia ntawm no, tab sis koj tuaj yeem tsim lub plhaub rau ib qho Linux hais kom ua los ntawm kev ntxiv rau hauv daim ntawv. Yog tias koj ntxiv cov cai no rau koj profile PowerShell, cov lus txib no yuav muaj rau koj hauv txhua qhov kev sib tham PowerShell, ib yam li cov lus txib ib txwm!
Default Settings
Hauv Linux, nws yog ib qho tsim nyog los txheeb xyuas cov npe npe thiab / lossis ib puag ncig hloov pauv hauv cov ntawv nkag mus, teeb tsa qhov tsis raug rau cov lus txib nquag siv (piv txwv li, alias ls=ls -AFh los yog export LESS=-i). Ib qho tsis zoo ntawm kev tso npe los ntawm lub plhaub tsis sib tham wsl.exe - tias cov profiles tsis thauj khoom, yog li cov kev xaiv no tsis muaj los ntawm lub neej ntawd (piv txwv li. ls hauv WSL thiab wsl ls yuav coj txawv txawv nrog cov alias teev saum toj no).
Txawm li cas los xij, nrog kev hloov kho me ntsis rau peb lub plhaub, peb tuaj yeem siv cov qauv zoo ib yam li $PSDefaultParameterValues, thiab pab kom muaj kev xaiv rau Linux cov lus txib!
Hla $WslDefaultParameterValues mus rau kab hais kom ua, peb xa cov parameters ntawm wsl.exe. Cov hauv qab no qhia yuav ua li cas ntxiv cov lus qhia rau koj qhov profile PowerShell kom teeb tsa qhov chaw pib. Tam sim no peb tuaj yeem ua tau!
Txij li cov parameters yog qauv tom qab $PSDefaultParameterValues, Koj ua tau nws yooj yim rau lov tes taw lawv ib ntus los ntawm kev txhim kho tus yuam sij "Disabled" rau hauv lub ntsiab lus $true. Ib qho txiaj ntsig ntxiv ntawm lub rooj sib cais hash yog qhov muaj peev xwm ua haujlwm tsis tau $WslDefaultParameterValues cais los ntawm $PSDefaultParameterValues.
Kev sib cav tiav
PowerShell tso cai rau koj los sau npe sib cav sib cav siv cov lus txib Register-ArgumentCompleter. Bash muaj zog programmable auto-completion cov cuab yeej. WSL tso cai rau koj hu bash los ntawm PowerShell. Yog tias peb tuaj yeem sau npe sib cav ua tiav rau peb lub PowerShell muaj nuj nqi wrappers thiab hu bash los tsim cov kev ua tiav, peb tau txais kev sib cav tag nrho nrog tib qhov tseeb li bash nws tus kheej!
# 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]
}
}
Cov cai yog me ntsis ntom yam tsis nkag siab qee qhov ntawm bash lub luag haujlwm sab hauv, tab sis qhov peb ua yog qhov no:
Sau npe qhov kev sib cav ua tiav rau tag nrho peb cov ntaub ntawv muaj nuj nqi los ntawm kev dhau ib daim ntawv teev npe $commands nyob rau hauv parameter -CommandName rau Register-ArgumentCompleter.
Peb daim ntawv qhia txhua qhov hais kom ua rau lub plhaub ua haujlwm uas bash siv rau kev ua tiav autocompletion (kom txhais cov ntsiab lus autocompletion, bash siv $F, abbreviation rau complete -F <FUNCTION>).
Hloov PowerShell Arguments $wordToComplete, $commandAst и $cursorPosition rau hauv hom xav tau los ntawm bash's autocompletion functions raws li cov specifications programmable pib ua kom tiav bash.
Peb sau cov kab hais kom hloov mus rau wsl.exe, uas ua kom ntseeg tau tias ib puag ncig raug teeb tsa kom raug, hu rau qhov tsim nyog nws pib ua tiav, thiab tso tawm cov txiaj ntsig hauv kab-los-kab zam.
Ces peb hu wsl nrog cov kab hais kom ua, peb cais cov zis los ntawm kab cais thiab tsim rau txhua tus CompletionResults, txheeb lawv thiab khiav cov cim xws li qhov chaw thiab cov kab lus uas yuav txhais tau yuam kev.
Yog li ntawd, peb cov lus txib Linux yuav siv raws nraim tib yam autocompletion li bash! Piv txwv li: