Isku dhafka amarrada Linux gudaha Windows iyadoo la adeegsanayo PowerShell iyo WSL

Su'aal caadi ah oo ka timid horumariyeyaasha Windows: "Maxay weli u jiraan <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>? Haddi ay tahay jiid xoog leh less ama qalab la yaqaan grep ama sed, Horumarinta Windows waxay rabaan inay si sahlan u galaan amarradan shaqadooda maalinlaha ah.

Nidaam hoosaadka Windows ee Linux (WSL) tallaabo weyn oo hore loo qaaday ayuu arrintan ka sameeyay. Waxay kuu ogolaanaysaa inaad ka wacdo amarrada Linux ka Windows adigoo wakiil ka ah iyaga wsl.exe (tus., wsl ls). Inkasta oo tani ay tahay horumar la taaban karo, doorashadani waxay la il daran tahay tiro khasaare ah.

  • Kordhinta meel kasta wsl caajis ah oo aan dabiici ahayn.
  • Dariiqooyinka Windows ee dooduhu had iyo jeer ma shaqeeyaan sababtoo ah dib-u-dhacyada waxaa loo fasiraa inay yihiin jilayaal baxsad ah halkii ay ka ahaan lahaayeen kala-soocida hagaha.
  • Dariiqooyinka Windows ee doodaha looma turjuman barta buurta ee WSL.
  • Dejinta asalka ah laguma ixtiraamo astaanta WSL ee leh magacyo iyo doorsoomayaasha deegaanka.
  • Dhamaystirka dariiqa Linux lama taageero
  • Dhamaystirka amarka lama taageero.
  • Dhamaystirka doodda lama taageero.

Natiijo ahaan, amarada Linux waxaa loola dhaqmaa sida muwaadiniinta heerka labaad ee hoos yimaada Windows-waana aad u adag in la isticmaalo marka loo eego amarada asalka ah. Si loo siman yahay xuquuqdooda, waa lagama maarmaan in la xalliyo dhibaatooyinka liiska.

Xirmooyinka shaqada PowerShell

Iyada oo la adeegsanayo duubayaasha shaqada PowerShell, waxaan ku dari karnaa dhamaystirka amarka oo aan baabi'in karno baahida horgalayaasha wsl, u tarjumaadda dariiqyada Windows ee waddooyinka WSL. Shuruudaha aasaasiga ah ee qolofka:

  • Amar kasta oo Linux ah waa inuu jiraa hal duub oo shaqo oo isku magac ah.
  • Qolfku waa inuu aqoonsadaa dariiqyada Windows ee loo maray dood ahaan oo u beddelaa waddooyinka WSL.
  • qoloftu waa inay wacdaa wsl iyada oo la raacayo amarka Linux ee ku habboon gelinta dhuumaha kasta iyo gudbinta dood kasta oo khadka taliska ee loo gudbiyo shaqada.

Maadaama qaabkan lagu dabaqi karo amar kasta, waxaan ka soo saari karnaa qeexida duubabkan oo aan si firfircoon uga soo saarno liiska amarrada soo dejinta.

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

liiska $command qeexayaa amarrada soo dejinta. Kadibna waxaan si firfircoon ugu abuurnaa mid kasta oo iyaga ka mid ah duubista shaqada anagoo adeegsanayna amarka Invoke-Expression (Adiga oo marka hore meesha ka saara magac kasta oo khilaafaya shaqada).

Shaqadu waxay ku celcelisaa doodaha khadka taliska, waxay go'aamisaa waddooyinka Windows iyagoo isticmaalaya amarro Split-Path и Test-Pathka dibna u beddelo waddooyinkan waddooyinka WSL. Waxaan wadooyinkii ku maareynaa shaqo caawiye Format-WslArgument, kaas oo aynu dib u qeexi doono. Waxay ka baxsanaysaa jilayaasha gaarka ah sida meelaha bannaan iyo qawladaha oo haddii kale si khaldan loo fasiri lahaa.

Ugu dambeyntii, waxaan gudbineynaa wsl gelinta dhuumaha iyo dood kasta oo khadka taliska.

Duubabkan waxaad wici kartaa amarada Linux ee aad ugu jeceshahay si dabiici ah adigoon ku darin horgale wsl oo aan ka welwelin sida waddooyinka loo rogo:

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

Xeerarka aasaasiga ah ee amarrada ayaa halkan lagu muujiyey, laakiin waxaad u abuuri kartaa qolof amar kasta oo Linux ah adigoo si fudud ugu daraya liiska. Haddii aad ku darto koodkan kaaga astaan ​​guud PowerShell, amarradan waxay diyaar kuu noqon doonaan fadhi kasta oo PowerShell ah, sida amarrada waddaniga ah!

Dejinta asalka ah

Linux, waa wax caadi ah in lagu qeexo magacyadooda iyo/ama doorsoomayaasha deegaanka ee profiles-ka gelitaanka, dejinta xuduudaha caadiga ah ee amarrada inta badan la isticmaalo (tusaale, alias ls=ls -AFh ama export LESS=-i). Mid ka mid ah faa'iido darrada ay leedahay wakiilnimada iyada oo loo marayo qolof aan is-dhexgal lahayn wsl.exe - in profiles-yada aan la rarin, markaa fursadahan lama heli karo si caadi ah (ie. ls ee WSL iyo wsl ls waxay u dhaqmi doontaa si ka duwan magacii kor lagu qeexay).

PowerShell waxay bixisaa Qiimaha $PSDefaultParameter, hab caadi ah oo lagu qeexo xuduudaha caadiga ah, laakiin kaliya ee cmdlets iyo hawlaha horumarsan. Dabcan, waxaan ka samayn karnaa hawlo horumarsan qolofkeena, laakiin tani waxay soo bandhigaysaa dhibaatooyin aan loo baahnayn (tusaale ahaan, PowerShell waxay xidhiidhisaa magacyada halbeegyada qayb ahaan (tusaale ahaan, -a xiriir la leh -ArgumentList), taas oo ka hor imanaysa amarrada Linux ee magaca qayb ahaan u qaata dood ahaan), iyo syntax si loo qeexo qiyamka caadiga ah ma noqon doono kuwa ugu habboon ( doodaha caadiga ah waxay u baahan yihiin magaca halbeegga furaha, maaha kaliya magaca amarka) .

Si kastaba ha ahaatee, iyada oo wax yar laga beddelayo qolofkeena, waxaan hirgelin karnaa qaab la mid ah $PSDefaultParameterValues, oo awood u yeelo ikhtiyaarada caadiga ah ee amarrada 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 ' ')
    }
}

Gudub $WslDefaultParameterValues khadka taliska, waxaan u dirnaa cabbirada via wsl.exe. Kuwa soo socdaa waxay muujinayaan sida loogu daro tilmaamaha astaantaada PowerShell si loo habeeyo dejimaha caadiga ah. Hadda waan sameyn karnaa!

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

Maaddaama halbeegyada loo qaabeeyey $PSDefaultParameterValues, Waad awoodaa way fududahay in la joojiyo si ku meel gaar ah adigoo ku rakibaya furaha "Disabled" macno ahaan $true. Faa'iidada dheeraadka ah ee miiska xashiishka ee goonida ah waa awoodda lagu joojin karo $WslDefaultParameterValues si gooni ah uga $PSDefaultParameterValues.

Dhamaystirka doodda

PowerShell wuxuu kuu ogolaanayaa inaad diwaangeliso raadraacayaasha dooda adoo isticmaalaya amarka Register-ArgumentCompleter. Bash ayaa awood leh Aalado si toos ah loo dhammaystiri karo. WSL waxay kuu ogolaanaysaa inaad ka wacdo bash PowerShell. Haddii aan diiwaangelin karno dhammaystirka dooda ee xirmooyinkayada shaqada PowerShell oo aan u wacno bash si aan u abuurno dhammaystirka, waxaan helnaa dhammaystir buuxa oo dood ah isla saxnaanta bash lafteeda!

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

Koodhku waa yara cufan iyada oo aan la fahmin qaar ka mid ah hawlaha gudaha ee bash, laakiin asal ahaan waxa aan samayno waa tan:

  • Diiwangelinta dhamaystirka dooda ee dhammaan duubayaasha shaqadeena anagoo gudbinaya liis $commands in parameter -CommandName si ay u Register-ArgumentCompleter.
  • Waxaan u khariideynaa amar kasta shaqada qolofka uu bash u isticmaalo dhamaystirka otomaatiga (si loo qeexo qeexida dhamaystirka, isticmaalka bash $F, soo gaabinta complete -F <FUNCTION>).
  • Beddelka Doodaha PowerShell $wordToComplete, $commandAst и $cursorPosition qaabka la filayo ee bash's auto dhamaystirka hawlaha sida ku qeexan otomaatig u dhammaystirka barnaamijka bash
  • Waxaan diyaarinay khadka taliska si aan ugu wareejino wsl.exe, kaas oo hubiya in deegaanka si sax ah loo dejiyay, wac shaqada ku habboon ee dhamaystirka auto-dhammeynta, oo soo saarta natiijooyinka qaab line-by-line fashion.
  • Markaa waanu wacnaa wsl iyadoo xariiqda taliska, waxaan ku kala soocnaa wax soo saarka iyadoo loo eegayo kala-soocida xariiqda oo mid kasta ayaa soo saarta CompletionResults, kala soocida iyaga oo ka baxsanaya jilayaasha sida meelaha bannaan iyo qawlka oo haddii kale si khaldan loo fasiri lahaa.

Natiijo ahaan, qolofkeena taliska Linux waxay isticmaali doonaan isla dhammaystirka bash! Tusaale ahaan:

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

Dhammaystir kastaa wuxuu bixiyaa qiime u gaar ah dooddii hore, akhrinta xogta qaabeynta sida martigaliyayaasha loo yaqaan WSL!

<TAB> wareegga wareegga. <Ctrl + пробел> waxay tusi doontaa dhammaan fursadaha jira.

Intaa waxaa dheer, maadaama aan hadda haysanno bash autocompletion, waxaad si toos ah ugu buuxin kartaa waddooyinka Linux PowerShell!

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

Kiisaska halka dhamaystirka bashku aanu soo saarin wax natiijooyin ah, PowerShell waxay ku noqotaa nidaamka dariiqyada Windows ee caadiga ah. Sidaa darteed, ficil ahaan, waxaad isku mar isticmaali kartaa labada dariiq ee go'aankaaga.

gunaanad

Isticmaalka PowerShell iyo WSL, waxaan ku dhex dari karnaa amarada Linux Windows sida codsiyada hooyo. Looma baahna in la raadiyo dhismooyinka Win32 ama adeegyada Linux ama la joojiyo socodkaaga shaqada adoo aadaya qolof Linux ah. Kaliya ku rakib WSL, habayn Muuqaalka PowerShell и qor amarrada aad rabto inaad soo dejiso! Dhammaystir qani ah oo loogu talagalay xuduudaha amarka Linux iyo Windows iyo waddooyinka faylalka waa shaqeyn aan xitaa laga heli karin amarrada Windows-ka asalka ah maanta.

Koodhka isha buuxa ee lagu sifeeyay korka, iyo sidoo kale tilmaamo dheeraad ah oo lagu daro socodka shaqadaada, ayaa diyaar ah halkan.

Waa kuwee amarada Linux ee aad u aragto inay ugu waxtar badan yihiin? Maxaa kale oo caadi ah ayaa ka maqan marka laga shaqeynayo Windows? Ku qor faallooyinka ama ku yaal GitHub!

Source: www.habr.com

Add a comment