แขแแแแฃแ แ แจแแแแแฎแแ Windows-แแก แแแแแแแแแ แแแแกแแแ: โแ แแขแแ แฏแแ แแแแแ แแ แแ แแก <ะะกะขะะะฌะขะ ะขะฃะข ะะฎะะะะฃะฎ ะะะะะะะฃ LINUX>
?. แแฅแแแแ แแก แซแแแแ แ แแแ แขแงแแ less
แแ แแแชแแแแ แแแ แแฆแแแ grep
แแ sed
Windows-แแก แแแแแแแแแ แแแก แกแฃแ แ แแ แแ แซแแแแแแแแ แแแ แขแแแ แฌแแแแแ แงแแแแแแฆแแฃแ แแฃแจแแแแแจแ.
wsl.exe
(แแแแแแแแแ, wsl ls
). แแแฃแฎแแแแแแ แแแแกแ, แ แแ แแก แแ แแก แแแแจแแแแแแแแแ แแแฃแแฏแแแแกแแแ, แแ แแแ แแแแขแก แแฅแแก แแแแแ แ แแแ แฃแแ แงแแคแแแ แแฎแแ แแแแ.
- แกแแงแแแแแแแ แแแแแขแแแ
wsl
แแแแฆแแแแ แแ แแ แแแฃแแแแ แแแ. - Windows-แแก แแแแแแแแ แแ แแฃแแแแขแแแจแ แงแแแแแแแแก แแ แแฃแจแแแแก, แ แแแแแ แฃแแแแ แฎแแแแแ แแแขแแ แแ แแขแแ แแแฃแแแ, แ แแแแ แช แแแฅแชแแแแก แกแแแแแแแแแ แแ แแ แ แแแ แแฅแขแแ แแแก แแแแงแแคแแแ.
- Windows-แแก แแแแแแแแ แแ แแฃแแแแขแแแจแ แแ แแแแ แแแแแแ WSL-แแก แจแแกแแแแแแก แกแแแแแขแแแ แฌแแ แขแแแจแ.
- แแแแฃแแแกแฎแแแแ แแแ แแแแขแ แแแ แแ แแ แแก แแแชแฃแแ WSL แแ แแคแแแแแจแ แแแขแกแแฎแแแแแแแ แแ แแแ แแแแก แชแแแแแแแแ.
- Linux แแแแแแแก แแแกแ แฃแแแแ แแ แแ แแก แแฎแแ แแแญแแ แแแ.
- แแ แซแแแแแแก แแแกแ แฃแแแแ แแ แแ แแก แแฎแแ แแแญแแ แแแ.
- แแ แแฃแแแแขแแก แแแกแ แฃแแแแ แแฎแแ แแแญแแ แแแ แแ แแ แแก.
แจแแแแแแ, Linux-แแก แแ แซแแแแแแแ แแแแแฎแแแแแ, แ แแแแ แช แแแแ แ แแแแกแแก แแแฅแแแแฅแแแแ Windows-แจแ - แแ แฃแคแ แ แ แแฃแแ แแแแแกแแงแแแแแแแแ, แแแแ แ แแจแแแแแฃแ แ แแ แซแแแแแแแ. แแแแ แฃแคแแแแแแแก แแแกแแแแแแแ แแแแแ แแฃแชแแแแแแแแ แฉแแแแแแแแแ แแ แแแแแแแแแก แแแแแญแ แ.
PowerShell แคแฃแแฅแชแแแก แจแแคแฃแแแแแ
PowerShell แคแฃแแฅแชแแแก แจแแคแฃแแแแ, แฉแแแ แจแแแแแซแแแ แแแแแแแขแแ แแ แซแแแแแแก แแแกแ แฃแแแแ แแ แแฆแแแแคแฎแแ แแ แแ แแคแแฅแกแแแแก แกแแญแแ แแแแ wsl
Windows แแแแแแแแแก แแแ แแแแ WSL แแแแแแแแแ. แญแฃแ แแแก แซแแ แแแแแ แแแแฎแแแแแแ:
- Linux-แแก แงแแแแ แแ แซแแแแแแกแแแแก แฃแแแ แแงแแก แแ แแ แคแฃแแฅแชแแแก แจแแคแฃแแแ แแแแแ แกแแฎแแแแ.
- Shell-แแ แฃแแแ แแฆแแแ แแก แแ แแฃแแแแขแแแแ แแแแแชแแแฃแแ Windows แแแแแแแแ แแ แแแแแแงแแแแแก แแกแแแ 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
(แแแ แแแ แ แแแจแ แแแแแกแแแแ แ แแแขแกแแฎแแแแก แฌแแจแแแ, แ แแแแแแช แแฌแแแแแฆแแแแแแแ แคแฃแแฅแชแแแก).
แคแฃแแฅแชแแ แแแแแ แแแก แแ แซแแแแแแก แฎแแแแก แแ แแฃแแแแขแแแก, แแแแกแแแฆแแ แแแก Windows แแแแแแแแก แแ แซแแแแแแแแก แแแแแงแแแแแแ Split-Path
ะธ Test-Path
แแ แจแแแแแ แแแ แแแฅแแแแก แแ แแแแแแแแก WSL แแแแแแแแแ. แฉแแแ แแแขแแ แแแ แแแแแแแแก แแแแฎแแแ แ แคแฃแแฅแชแแแก แแแจแแแแแแ Format-WslArgument
, แ แแแแแกแแช แแแแแแแแแแแ แแแแแกแแแฆแแ แแแ. แแก แแแฃแ แแแก แกแแแชแแแแฃแ แกแแแแแแแแแก, แ แแแแ แแชแแ แกแแแ แชแแแแ แแ แคแ แฉแฎแแแแแ, แ แแแแแแแช แกแฎแแแแแแ แแ แแฅแแแแแแ แแ แแกแฌแแ แแแขแแ แแ แแขแแชแแแก.
แแแแแก แแแแแแชแแแ wsl
แแแแกแแแแแแก แจแแงแแแแ แแ แแ แซแแแแแแก แฎแแแแก แแแแแกแแแแ แ แแ แแฃแแแแขแ.
แแ แจแแคแฃแแแแ แจแแแแซแแแแ แแแแแแซแแฎแแ แแฅแแแแ แกแแงแแแ แแแ Linux แแ แซแแแแแแแ แฃแคแ แ แแฃแแแแ แแแ แแแแ, แแ แแคแแฅแกแแก แแแแแขแแแแก แแแ แแจแ wsl
แแ แคแแฅแ แแก แแแ แแจแ, แแฃ แ แแแแ แแแ แแแแฅแแแแแ แแแแแแแแ:
man bash
less -i $profile.CurrentUserAllHosts
ls -Al C:Windows | less
grep -Ein error *.log
tail -f *.log
แแ แซแแแแแแแแก แซแแ แแแแแ แแแแ แแแ แแแฉแแแแแแแ แแฅ, แแแแ แแ แแฅแแแ แจแแแแซแแแแ แจแแฅแแแแ แญแฃแ แแ แแแแแกแแแแ แ Linux แแ แซแแแแแแกแแแแก, แฃแแ แแแแ แกแแแจแ แแแกแ แแแแแขแแแแ. แแฃ แแ แแแแก แแแแแแขแแแ แแฅแแแแก
แแแแฃแแแกแฎแแแแ แแแ แแแแขแ แแแ
Linux-แจแ แฎแจแแ แแ แแแแแกแแแแก แแ/แแ แแแ แแแแก แชแแแแแแแแก แแแแกแแแฆแแ แ แจแแกแแแแก แแ แแคแแแแแจแ, แฎแจแแ แแ แแแแแงแแแแแฃแแ แแ แซแแแแแแแแก แแแแฃแแแกแฎแแแแ แแแ แแแแขแ แแแแก แแแงแแแแแ (แแแแแแแแแ, alias ls=ls -AFh
แแ export LESS=-i
). แแ แแแแขแแ แแฅแขแแฃแแ แแแ แกแแก แแแจแแแแแแ แแ แแฅแกแแแแแแก แแ แ-แแ แแ แแแแฃแกแ wsl.exe
- แ แแ แแ แแคแแแแแ แแ แแ แแก แฉแแขแแแ แแฃแแ, แแแแขแแ แแก แแแ แแแแขแ แแแ แแ แแ แแก แฎแแแแแกแแฌแแแแแ แแแแฃแแแกแฎแแแแแ (แ.แ. ls
WSL-แจแ แแ wsl ls
แแแแกแฎแแแแแแฃแแแ แแแแฅแชแแแ แแแแแ แแแแกแแแฆแแ แฃแแ แแแขแกแแฎแแแแ).
PowerShell แฃแแ แฃแแแแแงแแคแก -a
แฃแแแแจแแ แแแแ -ArgumentList
), แ แแแแแแช แแฌแแแแแฆแแแแแแแ Linux-แแก แแ แซแแแแแแแก, แ แแแแแแแช แแ แแฃแแแแขแแแแ แแฆแแแแ แแแฌแแแแแ แแ แกแแฎแแแแแก) แแ แแแแฃแแแกแฎแแแแ แแ แแฃแแแแขแแแแก แแแแกแแแฆแแ แแก แกแแแขแแฅแกแ แแ แแฅแแแแ แงแแแแแแ แจแแกแแคแแ แแกแ (แแแแฃแแแกแฎแแแแ แแ แแฃแแแแขแแแแก แแแแกแแแฆแแ แ แแแแแฎแแแก แแแ แแแแขแ แแก แกแแฎแแแก แแแกแแฆแแแจแ แแ แแ แ แแฎแแแแ แแ แซแแแแแแก แกแแฎแแแก).
แแฃแแชแ, แฉแแแแ แญแฃแ แแแแแก แแชแแ แ แแแแแคแแแแชแแแ, แฉแแแ แจแแแแแซแแแ แแแแแแฎแแ แชแแแแแ แแกแแแแกแ แแแแแแ $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
. แฅแแแแแ แแแชแแแฃแแแ, แแฃ แ แแแแ แฃแแแ แแแแแแขแแ แแแกแขแ แฃแฅแชแแแแ แแฅแแแแก PowerShell แแ แแคแแแจแ แแแแฃแแแกแฎแแแแ แแแ แแแแขแ แแแแก แแแแคแแแฃแ แแชแแแกแแแแก. แแฎแแ แฉแแแ แจแแแแแซแแแ แแแแก แแแแแแแแ!
$WslDefaultParameterValues["grep"] = "-E"
$WslDefaultParameterValues["less"] = "-i"
$WslDefaultParameterValues["ls"] = "-AFh --group-directories-first"
แแแแแแแแ แแแ แแแแขแ แแแแก แแแแแแแ แแแ แฎแแแแ $PSDefaultParameterValues
แจแแแแซแแแ "Disabled"
แแแแจแแแแแแแแจแ $true
. แชแแแแแฃแแ แฐแแจแแก แชแฎแ แแแแก แแแแแขแแแแแ แฃแแแ แแขแแกแแแ แแ แแก แแแแแ แแแแก แจแแกแแซแแแแแแแ $WslDefaultParameterValues
แชแแแแ $PSDefaultParameterValues
.
แแ แแฃแแแแขแแก แแแกแ แฃแแแแ
PowerShell แกแแจแฃแแแแแแก แแแซแแแแ แแแแ แแแแกแขแ แแ แแ แแ แแฃแแแแขแแแแก แแ แแแแแ แ แแ แซแแแแแแก แแแแแงแแแแแแ Register-ArgumentCompleter
. แแแจแก แแฅแแก แซแแแแ แ
# 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
. - แฉแแแ แแแคแแฅแกแแ แแแ แแแแแแฃแ แแ แซแแแแแแก shell แคแฃแแฅแชแแแแ, แ แแแแแกแแช bash แแงแแแแแก แแแขแแแแขแฃแ แ แจแแแกแแแแกแแแแก (แแแขแแแแขแฃแ แ แจแแแกแแแแก แกแแแชแแคแแแแชแแแแแก แแแกแแแแแแแ, bash แแงแแแแแก
$F
, แแแ แแแแแขแฃแ แcomplete -F <FUNCTION>
). - PowerShell แแ แแฃแแแแขแแแแก แแแแแแ แขแแชแแ
$wordToComplete
,$commandAst
ะธ$cursorPosition
แคแแ แแแขแจแ, แ แแแแแแช แแแกแแแแแแแแแ bash-แแก แแแขแแแแขแฃแ แ แจแแแกแแแแก แคแฃแแฅแชแแแแแก แแแฎแแแแแ, แกแแแชแแคแแแแชแแแแแก แแแฎแแแแแแแ แแแ แแแแ แแแแแ แแแขแแแแขแฃแ แ แแแกแ แฃแแแแ แแแจ. - แฉแแแ แแฅแแแแ แแ แซแแแแแแก แฎแแแก แแแแแกแแชแแแแ
wsl.exe
, แ แแแแแแช แฃแแ แฃแแแแแงแแคแก แแแ แแแแก แกแฌแแ แแ แแแงแแแแแแก, แแซแแฎแแแก แจแแกแแแแแแก แแแขแแแแขแฃแ แ แจแแแกแแแแก แคแฃแแฅแชแแแก แแ แแแแแแฅแแก แจแแแแแแแ แกแขแ แแฅแแ-แกแขแ แแฅแแแจแ. - แแแ แ แแฃแ แแแแแ
wsl
แแ แซแแแแแแก แฎแแแแ แแแแแแงแแคแ แแแแแแแแแแก แฎแแแแก แแแแงแแคแแแแก แแแฎแแแแแ แแ แแแฌแแ แแแแแ แแแแแแฃแแกCompletionResults
, แแแแ แแแฎแแ แแกแฎแแแ แแ แแกแแแ แกแแแแแแแแแแก แแแฅแชแแแ, แ แแแแ แแชแแ แกแแแ แชแแแแ แแ แคแ แฉแฎแแแแแ, แ แแแแแแแช แกแฎแแแแแแ แแ แแ แแกแฌแแ แแ แแฅแแแแแแ แแแขแแ แแ แแขแแ แแแฃแแ.
แจแแแแแแ, แฉแแแแ Linux แแ แซแแแแแแก แญแฃแ แแ แแแแแแงแแแแแก แแฃแกแขแแ แแแแแ แแแขแแแแขแฃแ แแแกแ แฃแแแแแก, แ แแแแ แช bash! แฒแแแแแแแแ:
ssh -c <TAB> -J <TAB> -m <TAB> -O <TAB> -o <TAB> -Q <TAB> -w <TAB> -b <TAB>
แแแแแแฃแแ แแแขแแแแขแฃแ แ แแแกแ แฃแแแแ แแฌแแแแก แฌแแแ แแ แแฃแแแแขแแกแแแแก แกแแแชแแคแแแฃแ แแแแจแแแแแแแแแก, แแแแฎแฃแแแแก แแแแคแแแฃแ แแชแแแก แแแแแชแแแแแก, แ แแแแ แแชแแ แชแแแแแแ แฐแแกแขแแแ WSL-แแแ!
<TAB>
แจแแแแแแแแก แแแ แแแแขแ แแแก. <Ctrl + ะฟัะพะฑะตะป>
แแฉแแแแแแก แงแแแแ แจแแกแแซแแ แแแ แแแแขแก.
แแแ แแ แแแแกแ, แ แแแแแ แฉแแแ แแฎแแ แแแแฅแแก bash แแแขแแแแขแฃแ แ แแแกแ แฃแแแแ, แจแแแแซแแแแ แแแขแแแแขแฃแ แแ แจแแแแกแแ Linux แแแแแแแแ แแแ แแแแแ PowerShell-แจแ!
less /etc/<TAB>
ls /usr/share/<TAB>
vim ~/.bash<TAB>
แแ แจแแแแฎแแแแแแจแ, แ แแแแกแแช bash แแแขแแแแขแฃแ แ แแแกแ แฃแแแแ แแ แแซแแแแ แ แแแแ แจแแแแแก, PowerShell แฃแแ แฃแแแแแ แกแแกแขแแแแก แแแแฃแแแกแฎแแแ Windows แแแแแแแแก. แแแ แแแแ, แแ แแฅแขแแแแจแ, แแฅแแแ แจแแแแซแแแแ แแ แแแ แแฃแแแ แแแแแแงแแแแ แแ แแแ แแแ แแฅแแแแ แจแแฎแแแฃแแแแแกแแแแแ .
แแแกแแแแ
PowerShell-แแกแ แแ WSL-แแก แแแแแงแแแแแแ, แฉแแแ แจแแแแแซแแแ Linux-แแก แแ แซแแแแแแแแก แแแขแแแ แแ แแแ Windows-แจแ, แ แแแแ แช แแจแแแแแฃแ แแแแแแแชแแแแจแ. แแ แแ แแก แกแแญแแ แ Win32 build-แแแแก แแ Linux-แแก แฃแขแแแแขแแแแก แซแแแแ แแ แแฅแแแแ แกแแแฃแจแแ แแ แแชแแกแแก แจแแฌแงแแแขแ Linux-แแก แแแ แกแแ แแแแแกแแแแ. แฒฃแแ แแแแ
แแแแแ แแฆแฌแแ แแแ แกแ แฃแแ แฌแงแแ แแก แแแแ, แแกแแแ แ แแแแ แช แแแแแขแแแแแ แแแกแขแ แฃแฅแชแแแแ แแฅแแแแก แกแแแฃแจแแ แแ แแชแแกแจแ แแแกแ แฉแแ แแแแกแแแแก, แฎแแแแแกแแฌแแแแแแ
Linux-แแก แ แแแแแ แแ แซแแแแแแแ แแแแแฉแแแแ แงแแแแแแ แกแแกแแ แแแแแ? แ แ แกแฎแแ แกแแแ แแ แ แแ แแแแแ Windows-แจแ แแฃแจแแแแแกแแก? แแแฌแแ แแ แแแแแแขแแ แแแจแ แแ
แฌแงแแ แ: www.habr.com