பவர்ஷெல் மற்றும் WSL ஐப் பயன்படுத்தி லினக்ஸ் கட்டளைகளை விண்டோஸில் ஒருங்கிணைத்தல்

விண்டோஸ் டெவலப்பர்களிடமிருந்து ஒரு பொதுவான கேள்வி: “ஏன் இன்னும் இல்லை <ВСТАВЬТЕ ТУТ ЛЮБИМУЮ КОМАНДУ LINUX>?. இது ஒரு சக்திவாய்ந்த ஸ்வைப் ஆக இருந்தாலும் சரி less அல்லது பழக்கமான கருவிகள் grep அல்லது sed, Windows டெவலப்பர்கள் தங்கள் அன்றாட வேலைகளில் இந்த கட்டளைகளை எளிதாக அணுக விரும்புகிறார்கள்.

லினக்ஸிற்கான விண்டோஸ் துணை அமைப்பு (WSL) இந்த விஷயத்தில் ஒரு பெரிய படியை முன்னெடுத்துள்ளது. விண்டோஸிலிருந்து லினக்ஸ் கட்டளைகளை ப்ராக்ஸி மூலம் அழைக்க இது உங்களை அனுமதிக்கிறது wsl.exe (உ-ம், wsl ls) இது குறிப்பிடத்தக்க முன்னேற்றம் என்றாலும், இந்த விருப்பம் பல குறைபாடுகளால் பாதிக்கப்படுகிறது.

  • எங்கும் சேர்த்தல் wsl கடினமான மற்றும் இயற்கைக்கு மாறான.
  • வாதங்களில் விண்டோஸ் பாதைகள் எப்போதும் வேலை செய்யாது, ஏனெனில் பின்சாய்வுகள் கோப்பகப் பிரிப்பான்களைக் காட்டிலும் தப்பிக்கும் எழுத்துகளாக விளக்கப்படுகின்றன.
  • வாதங்களில் விண்டோஸ் பாதைகள் WSL இல் தொடர்புடைய மவுண்ட் பாயிண்டிற்கு மொழிபெயர்க்கப்படவில்லை.
  • மாற்றுப்பெயர்கள் மற்றும் சூழல் மாறிகள் கொண்ட WSL சுயவிவரங்களில் இயல்புநிலை அமைப்புகள் மதிக்கப்படுவதில்லை.
  • Linux பாதை நிறைவு ஆதரிக்கப்படவில்லை.
  • கட்டளை நிறைவு ஆதரிக்கப்படவில்லை.
  • வாதத்தை நிறைவு செய்வது ஆதரிக்கப்படவில்லை.

இதன் விளைவாக, லினக்ஸ் கட்டளைகள் விண்டோஸின் கீழ் இரண்டாம் தர குடிமக்களைப் போலவே கருதப்படுகின்றன - மேலும் சொந்த கட்டளைகளை விட பயன்படுத்த கடினமாக உள்ளது. அவர்களின் உரிமைகளை சமன் செய்ய, பட்டியலிடப்பட்ட சிக்கல்களைத் தீர்ப்பது அவசியம்.

பவர்ஷெல் செயல்பாடு ரேப்பர்கள்

பவர்ஷெல் ஃபங்ஷன் ரேப்பர்கள் மூலம், கட்டளை நிறைவுகளைச் சேர்க்கலாம் மற்றும் முன்னொட்டுகளின் தேவையை நீக்கலாம் wsl, விண்டோஸ் பாதைகளை WSL பாதைகளாக மொழிபெயர்த்தல். குண்டுகளுக்கான அடிப்படை தேவைகள்:

  • ஒவ்வொரு லினக்ஸ் கட்டளைக்கும் அதே பெயரில் ஒரு செயல்பாட்டு ரேப்பர் இருக்க வேண்டும்.
  • ஷெல் விண்டோஸ் பாதைகளை வாதங்களாகக் கண்டறிந்து அவற்றை WSL பாதைகளாக மாற்ற வேண்டும்.
  • ஷெல் அழைக்க வேண்டும் wsl எந்தவொரு பைப்லைன் உள்ளீட்டிற்கும் பொருத்தமான Linux கட்டளையுடன் மற்றும் செயல்பாட்டிற்கு அனுப்பப்பட்ட கட்டளை வரி வாதங்களை அனுப்புகிறது.

இந்த வடிவத்தை எந்த கட்டளைக்கும் பயன்படுத்த முடியும் என்பதால், இந்த ரேப்பர்களின் வரையறையை சுருக்கி, இறக்குமதி செய்வதற்கான கட்டளைகளின் பட்டியலிலிருந்து மாறும் வகையில் அவற்றை உருவாக்கலாம்.

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

பட்டியல் $command இறக்குமதி கட்டளைகளை வரையறுக்கிறது. கட்டளையைப் பயன்படுத்தி ஒவ்வொன்றிற்கும் ஒரு செயல்பாட்டு ரேப்பரை மாறும் வகையில் உருவாக்குகிறோம் Invoke-Expression (செயல்பாட்டுடன் முரண்படும் மாற்றுப்பெயர்களை முதலில் அகற்றுவதன் மூலம்).

செயல்பாடு கட்டளை வரி வாதங்களை மீண்டும் மீண்டும், கட்டளைகளை பயன்படுத்தி விண்டோஸ் பாதைகளை தீர்மானிக்கிறது Split-Path и Test-Pathபின்னர் இந்த பாதைகளை WSL பாதைகளாக மாற்றுகிறது. ஒரு உதவி செயல்பாட்டின் மூலம் பாதைகளை இயக்குகிறோம் Format-WslArgument, அதை நாம் பின்னர் வரையறுப்போம். இது ஸ்பேஸ்கள் மற்றும் அடைப்புக்குறிகள் போன்ற சிறப்பு எழுத்துக்களைத் தவிர்க்கிறது, இல்லையெனில் தவறாகப் புரிந்துகொள்ளப்படும்.

இறுதியாக, நாங்கள் தெரிவிக்கிறோம் wsl பைப்லைன் உள்ளீடு மற்றும் ஏதேனும் கட்டளை வரி வாதங்கள்.

இந்த ரேப்பர்கள் மூலம் உங்களுக்குப் பிடித்த லினக்ஸ் கட்டளைகளை முன்னொட்டைச் சேர்க்காமல் இயற்கையான முறையில் அழைக்கலாம் wsl பாதைகள் எவ்வாறு மாற்றப்படுகின்றன என்பதைப் பற்றி கவலைப்படாமல்:

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

கட்டளைகளின் அடிப்படை தொகுப்பு இங்கே காட்டப்பட்டுள்ளது, ஆனால் பட்டியலில் சேர்ப்பதன் மூலம் எந்த லினக்ஸ் கட்டளைக்கும் ஷெல்லை உருவாக்கலாம். இந்த குறியீட்டை உங்களுடன் சேர்த்தால் சுயவிவர பவர்ஷெல், இந்த கட்டளைகள் ஒவ்வொரு பவர்ஷெல் அமர்விலும், சொந்த கட்டளைகளைப் போலவே உங்களுக்குக் கிடைக்கும்!

இயல்புநிலை அமைப்புகள்

Linux இல், உள்நுழைவு சுயவிவரங்களில் மாற்றுப்பெயர்கள் மற்றும்/அல்லது சூழல் மாறிகளை வரையறுப்பது பொதுவானது, அடிக்கடி பயன்படுத்தப்படும் கட்டளைகளுக்கு இயல்புநிலை அளவுருக்களை அமைக்கிறது (எடுத்துக்காட்டாக, alias ls=ls -AFh அல்லது export LESS=-i) ஊடாடாத ஷெல் மூலம் ப்ராக்ஸியின் குறைபாடுகளில் ஒன்று wsl.exe - சுயவிவரங்கள் ஏற்றப்படவில்லை, எனவே இந்த விருப்பங்கள் இயல்பாக கிடைக்காது (அதாவது. ls WSL இல் மற்றும் wsl ls மேலே வரையறுக்கப்பட்ட மாற்றுப்பெயருடன் வித்தியாசமாக நடந்துகொள்ளும்).

பவர்ஷெல் வழங்குகிறது $PSDefaultParameterValues, இயல்புநிலை அளவுருக்களை வரையறுப்பதற்கான ஒரு நிலையான வழிமுறை, ஆனால் cmdlets மற்றும் மேம்பட்ட செயல்பாடுகளுக்கு மட்டுமே. நிச்சயமாக, எங்கள் ஷெல்களில் இருந்து மேம்பட்ட செயல்பாடுகளை உருவாக்கலாம், ஆனால் இது தேவையற்ற சிக்கல்களை அறிமுகப்படுத்துகிறது (எடுத்துக்காட்டாக, பவர்ஷெல் பகுதி அளவுரு பெயர்களை தொடர்புபடுத்துகிறது (எடுத்துக்காட்டாக, -a உடன் தொடர்புடையது -ArgumentList), இது பகுதி பெயர்களை வாதங்களாக எடுத்துக் கொள்ளும் லினக்ஸ் கட்டளைகளுடன் முரண்படும்), மேலும் இயல்புநிலை மதிப்புகளை வரையறுப்பதற்கான தொடரியல் மிகவும் பொருத்தமானதாக இருக்காது (இயல்புநிலை வாதங்களுக்கு கட்டளையின் பெயர் மட்டுமல்ல, விசையில் உள்ள அளவுருவின் பெயர் தேவைப்படுகிறது) .

எவ்வாறாயினும், எங்கள் ஷெல்களில் ஒரு சிறிய மாற்றத்துடன், இதேபோன்ற மாதிரியை நாம் செயல்படுத்தலாம் $PSDefaultParameterValues, மற்றும் 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 ' ')
    }
}

கடந்து செல்கிறது $WslDefaultParameterValues கட்டளை வரிக்கு, நாம் அளவுருக்களை அனுப்புகிறோம் wsl.exe. இயல்புநிலை அமைப்புகளை உள்ளமைக்க, உங்கள் பவர்ஷெல் சுயவிவரத்தில் எவ்வாறு வழிமுறைகளைச் சேர்ப்பது என்பதை பின்வரும் காட்டுகிறது. இப்போது நாம் அதை செய்ய முடியும்!

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

அளவுருக்கள் மாதிரியாக இருப்பதால் $PSDefaultParameterValues, உன்னால் முடியும் அவற்றை முடக்குவது எளிது விசையை நிறுவுவதன் மூலம் தற்காலிகமாக "Disabled" அர்த்தத்தில் $true. தனி ஹாஷ் அட்டவணையின் கூடுதல் நன்மை முடக்கும் திறன் ஆகும் $WslDefaultParameterValues தனித்தனியாக $PSDefaultParameterValues.

வாதம் நிறைவு

பவர்ஷெல் கட்டளையைப் பயன்படுத்தி வாத டிரெய்லர்களைப் பதிவு செய்ய உங்களை அனுமதிக்கிறது Register-ArgumentCompleter. பாஷ் சக்தி வாய்ந்தது நிரல்படுத்தக்கூடிய தானியங்கு நிறைவு கருவிகள். பவர்ஷெல்லில் இருந்து பாஷை அழைக்க WSL உங்களை அனுமதிக்கிறது. எங்கள் பவர்ஷெல் ஃபங்ஷன் ரேப்பர்களுக்கான வாத நிறைவுகளைப் பதிவுசெய்து, நிறைவுகளை உருவாக்க பாஷை அழைக்க முடிந்தால், பாஷைப் போலவே துல்லியமாக முழு வாதத்தையும் பெறுவோம்!

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

பாஷின் சில உள் செயல்பாடுகளைப் புரிந்து கொள்ளாமல் குறியீடு சற்று அடர்த்தியாக உள்ளது, ஆனால் அடிப்படையில் நாம் செய்வது இதுதான்:

  • ஒரு பட்டியலை அனுப்புவதன் மூலம் எங்களின் அனைத்து ஃபங்ஷன் ரேப்பர்களுக்கும் ஆர்குமெண்ட் நிறைவை பதிவு செய்தல் $commands அளவுருவில் -CommandName செய்ய Register-ArgumentCompleter.
  • ஒவ்வொரு கட்டளையையும் தானாக நிரப்புவதற்கு பாஷ் பயன்படுத்தும் ஷெல் செயல்பாட்டிற்கு மேப் செய்கிறோம். $F, என்பதன் சுருக்கம் complete -F <FUNCTION>).
  • பவர்ஷெல் வாதங்களை மாற்றுகிறது $wordToComplete, $commandAst и $cursorPosition விவரக்குறிப்புகளின்படி பாஷின் தன்னியக்க செயல்பாடுகளால் எதிர்பார்க்கப்படும் வடிவத்தில் நிரல்படுத்தக்கூடிய தானியங்கு நிறைவு பாஷ்.
  • மாற்றுவதற்கு ஒரு கட்டளை வரியை உருவாக்குகிறோம் wsl.exe, இது சூழல் சரியாக அமைக்கப்பட்டிருப்பதை உறுதிசெய்கிறது, பொருத்தமான தன்னியக்க-நிறைவு செயல்பாட்டை அழைக்கிறது மற்றும் முடிவுகளை வரிக்கு வரி முறையில் வெளியிடுகிறது.
  • பிறகு அழைக்கிறோம் wsl கட்டளை வரியுடன், வரி பிரிப்பான் மூலம் வெளியீட்டை பிரித்து ஒவ்வொன்றிற்கும் உருவாக்குகிறோம் CompletionResults, அவற்றை வரிசைப்படுத்துதல் மற்றும் ஸ்பேஸ்கள் மற்றும் அடைப்புக்குறிகள் போன்ற எழுத்துக்களைத் தப்பித்தல், இல்லையெனில் தவறாகப் புரிந்துகொள்ளப்படும்.

இதன் விளைவாக, எங்கள் லினக்ஸ் கட்டளை ஷெல்களும் பாஷைப் போலவே தானாக நிறைவு செய்யும்! உதாரணத்திற்கு:

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

ஒவ்வொரு தன்னியக்க நிறைவும் முந்தைய வாதத்திற்கு குறிப்பிட்ட மதிப்புகளை வழங்குகிறது, WSL இலிருந்து அறியப்பட்ட ஹோஸ்ட்கள் போன்ற உள்ளமைவுத் தரவைப் படிக்கிறது!

<TAB> அளவுருக்கள் மூலம் சுழற்சி செய்யும். <Ctrl + пробел> கிடைக்கக்கூடிய அனைத்து விருப்பங்களையும் காண்பிக்கும்.

கூடுதலாக, எங்களிடம் இப்போது பாஷ் தன்னியக்க நிறைவு இருப்பதால், பவர்ஷெல்லில் நேரடியாக லினக்ஸ் பாதைகளைத் தானாக முடிக்கலாம்!

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

பாஷ் தன்னியக்க நிறைவு எந்த முடிவையும் தராத சந்தர்ப்பங்களில், பவர்ஷெல் கணினி இயல்புநிலை விண்டோஸ் பாதைகளுக்குத் திரும்புகிறது. எனவே, நடைமுறையில், நீங்கள் ஒரே நேரத்தில் உங்கள் விருப்பப்படி இரண்டு பாதைகளையும் பயன்படுத்தலாம்.

முடிவுக்கு

பவர்ஷெல் மற்றும் டபிள்யூஎஸ்எல் ஆகியவற்றைப் பயன்படுத்தி, லினக்ஸ் கட்டளைகளை விண்டோஸில் நேட்டிவ் அப்ளிகேஷன்களாக ஒருங்கிணைக்கலாம். Win32 பில்ட்கள் அல்லது லினக்ஸ் பயன்பாடுகளைத் தேட வேண்டிய அவசியமில்லை அல்லது லினக்ஸ் ஷெல்லுக்குச் சென்று உங்கள் பணிப்பாய்வுக்கு இடையூறு விளைவிக்க வேண்டிய அவசியமில்லை. வெறும் WSL ஐ நிறுவவும், கட்டமைக்கவும் பவர்ஷெல் சுயவிவரம் и நீங்கள் இறக்குமதி செய்ய விரும்பும் கட்டளைகளை பட்டியலிடுங்கள்! லினக்ஸ் மற்றும் விண்டோஸ் கட்டளை அளவுருக்கள் மற்றும் கோப்பு பாதைகளுக்கான பணக்கார தன்னியக்க நிறைவு என்பது இன்று நேட்டிவ் விண்டோஸ் கட்டளைகளில் கூட கிடைக்காத செயல்பாடாகும்.

மேலே விவரிக்கப்பட்ட முழு மூலக் குறியீடும், உங்கள் பணிப்பாய்வுகளில் அதை இணைப்பதற்கான கூடுதல் வழிகாட்டுதல்களும் உள்ளன இங்கே.

எந்த லினக்ஸ் கட்டளைகளை நீங்கள் மிகவும் பயனுள்ளதாக கருதுகிறீர்கள்? விண்டோஸில் பணிபுரியும் போது வேறு என்ன பொதுவான விஷயங்கள் காணவில்லை? கருத்துகளில் எழுதுங்கள் அல்லது GitHub இல்!

ஆதாரம்: www.habr.com

கருத்தைச் சேர்