PowerShell рдФрд░ WSL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Linux рдХрдорд╛рдВрдб рдХреЛ рд╡рд┐рдВрдбреЛрдЬрд╝ рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд░рдирд╛

рд╡рд┐рдВрдбреЛрдЬрд╝ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рд╢реНрди: тАЬрдЕрднреА рднреА рдРрд╕рд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реИ <╨Т╨б╨в╨Р╨Т╨м╨в╨Х ╨в╨г╨в ╨Ы╨о╨С╨Ш╨Ь╨г╨о ╨Ъ╨Ю╨Ь╨Р╨Э╨Ф╨г LINUX>?. рдЪрд╛рд╣реЗ рд╡рд╣ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕реНрд╡рд╛рдЗрдк рд╣реЛ less рдпрд╛ рдкрд░рд┐рдЪрд┐рдд рдЙрдкрдХрд░рдг grep рдпрд╛ sed, рд╡рд┐рдВрдбреЛрдЬрд╝ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЕрдкрдиреЗ рджреИрдирд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЗрди рдХрдорд╛рдВрдбреЛрдВ рддрдХ рдЖрд╕рд╛рди рдкрд╣реБрдВрдЪ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

Linux рдХреЗ рд▓рд┐рдП Windows рд╕рдмрд╕рд┐рд╕реНрдЯрдо (WSL) рдиреЗ рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ рдПрдХ рдмрдбрд╝рд╛ рдХрджрдо рдЖрдЧреЗ рдмрдврд╝рд╛рдпрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рд╡рд┐рдВрдбреЛрдЬрд╝ рд╕реЗ рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рдХреЛ рдкреНрд░реЙрдХреНрд╕реА рдХрд░рдХреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ wsl.exe (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, wsl ls). рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реБрдзрд╛рд░ рд╣реИ, рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдХрдИ рдиреБрдХрд╕рд╛рдиреЛрдВ рд╕реЗ рдЧреНрд░рд╕реНрдд рд╣реИред

  • рд╕рд░реНрд╡рд╡реНрдпрд╛рдкреА рдЬреЛрдбрд╝ wsl рдердХрд╛рдК рдФрд░ рдЕрдкреНрд░рд╛рдХреГрддрд┐рдХ.
  • рддрд░реНрдХреЛрдВ рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬрд╝ рдкрде рд╣рдореЗрд╢рд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рдХреНрдпреЛрдВрдХрд┐ рдмреИрдХрд╕реНрд▓реИрд╢ рдХреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╡рд┐рднрд╛рдЬрдХ рдХреЗ рдмрдЬрд╛рдп рдПрд╕реНрдХреЗрдк рд╡рд░реНрдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рддрд░реНрдХреЛрдВ рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬрд╝ рдкрдереЛрдВ рдХреЛ рдбрдмреНрд▓реВрдПрд╕рдПрд▓ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдорд╛рдЙрдВрдЯ рдмрд┐рдВрджреБ рдкрд░ рдЕрдиреБрд╡рд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рдЙрдкрдирд╛рдо рдФрд░ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рд╕рд╛рде WSL рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХрд╛ рд╕рдореНрдорд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • Linux рдкрде рдкреВрд░реНрдгрддрд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ.
  • рдЖрджреЗрд╢ рдкреВрд░реНрдгрддрд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ.
  • рддрд░реНрдХ рдкреВрд░реНрдгрддрд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ.

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рдХреЛ рд╡рд┐рдВрдбреЛрдЬрд╝ рдХреЗ рддрд╣рдд рджреНрд╡рд┐рддреАрдп рд╢реНрд░реЗрдгреА рдХреЗ рдирд╛рдЧрд░рд┐рдХреЛрдВ рдХреА рддрд░рд╣ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ - рдФрд░ рдореВрд▓ рдХрдорд╛рдВрдб рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛрддрд╛ рд╣реИред рдЙрдирдХреЗ рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЛ рдмрд░рд╛рдмрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реВрдЪреАрдмрджреНрдз рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдкреЙрд╡рд░рд╢реЗрд▓ рдлрд╝рдВрдХреНрд╢рди рд░реИрдкрд░

рдкреЙрд╡рд░рд╢реЗрд▓ рдлрд╝рдВрдХреНрд╢рди рд░реИрдкрд░ рдХреЗ рд╕рд╛рде, рд╣рдо рдХрдорд╛рдВрдб рдкреВрд░реНрдгрддрд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ wsl, рд╡рд┐рдВрдбреЛрдЬрд╝ рдкрдереЛрдВ рдХреЛ рдбрдмреНрд▓реВрдПрд╕рдПрд▓ рдкрдереЛрдВ рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд░рдирд╛ред рдЧреЛрд▓реЗ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдБ:

  • рдкреНрд░рддреНрдпреЗрдХ рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдирд╛рдо рдХрд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд░реИрдкрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  • рд╢реЗрд▓ рдХреЛ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рд╡рд┐рдВрдбреЛрдЬрд╝ рдкрдереЛрдВ рдХреЛ рдкрд╣рдЪрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдбрдмреНрд▓реВрдПрд╕рдПрд▓ рдкрдереЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
  • рд╢реЗрд▓ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП wsl рдХрд┐рд╕реА рднреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рд╕реА рднреА рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рддрд░реНрдХ рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ред

рдЪреВрдБрдХрд┐ рдпрд╣ рдкреИрдЯрд░реНрди рдХрд┐рд╕реА рднреА рдХрдорд╛рдВрдб рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╣рдо рдЗрди рд░реИрдкрд░реНрд╕ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ рдЕрдореВрд░реНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдорд╛рдВрдб рдХреА рд╕реВрдЪреА рд╕реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

# 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

рдХрдорд╛рдВрдб рдХрд╛ рдореВрд▓ рд╕реЗрдЯ рдпрд╣рд╛рдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рдХрд░ рдХрд┐рд╕реА рднреА рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ рд╢реЗрд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рдЕрдкрдиреЗ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреЙрд╡рд░рд╢реЗрд▓, рдпреЗ рдХрдорд╛рдВрдб рдЖрдкрдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдкреЙрд╡рд░рд╢реЗрд▓ рд╕рддреНрд░ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрдВрдЧреЗ, рдмрд┐рд▓реНрдХреБрд▓ рдореВрд▓ рдХрдорд╛рдВрдб рдХреА рддрд░рд╣!

рдиреНрдпреВрдирддрд╛ рд╕рдорд╛рдпреЛрдЬрди

рд▓рд┐рдирдХреНрд╕ рдореЗрдВ, рд▓реЙрдЧрд┐рди рдкреНрд░реЛрдлрд╛рдЗрд▓ рдореЗрдВ рдЙрдкрдирд╛рдо рдФрд░/рдпрд╛ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛, рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗрдЯ рдХрд░рдирд╛ рдЖрдо рдмрд╛рдд рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, alias ls=ls -AFh рдпрд╛ export LESS=-i). рдЧреИрд░-рд╕рдВрд╡рд╛рджрд╛рддреНрдордХ рд╢реЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЙрдХреНрд╕реА рдХрд░рдиреЗ рдХреЗ рдиреБрдХрд╕рд╛рдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ wsl.exe - рдХрд┐ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд▓реЛрдб рдирд╣реАрдВ рд╣реБрдИ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпреЗ рд╡рд┐рдХрд▓реНрдк рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВ (рдЕрд░реНрдерд╛рдд ls рдбрдмреНрд▓реНрдпреВрдПрд╕рдПрд▓ рдореЗрдВ рдФрд░ wsl ls рдКрдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЙрдкрдирд╛рдо рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдЧрд╛)ред

рдкреЙрд╡рд░рд╢реЗрд▓ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ $PSDefaultParameterValues, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдирдХ рддрдВрддреНрд░, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╕реАрдПрдордбреАрд▓реЗрдЯреНрд╕ рдФрд░ рдЙрдиреНрдирдд рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдПред рдмреЗрд╢рдХ, рд╣рдо рдЕрдкрдиреЗ рд╢реЗрд▓ рд╕реЗ рдЙрдиреНрдирдд рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЬрдЯрд┐рд▓рддрд╛рдУрдВ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкрд╛рд╡рд░рд╢реЗрд▓ рдЖрдВрд╢рд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдореЛрдВ рдХреЛ рд╕рд╣рд╕рдВрдмрдВрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, -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. рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ PowerShell рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢ рдХреИрд╕реЗ рдЬреЛрдбрд╝реЗрдВред рдЕрдм рд╣рдо рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!

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

рдЪреВрдВрдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдмрд╛рдж рдореЗрдВ рдореЙрдбрд▓ рдХрд┐рдП рдЧрдП рд╣реИрдВ $PSDefaultParameterValues, рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЙрдиреНрд╣реЗрдВ рдЕрдХреНрд╖рдо рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХреБрдВрдЬреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдХреЗ рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ "Disabled" рдЕрд░реНрде рдореЗрдВ $true. рдПрдХ рдЕрд▓рдЧ рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд▓рд╛рдн рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ $WslDefaultParameterValues рд╕реЗ рдЕрд▓рдЧ $PSDefaultParameterValues.

рддрд░реНрдХ рдкреВрд░реНрдг рд╣реЛрдирд╛

рдкреЙрд╡рд░рд╢реЗрд▓ рдЖрдкрдХреЛ рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рддрд░реНрдХ рдЯреНрд░реЗрд▓рд░реЛрдВ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ Register-ArgumentCompleter. рдмреИрд╢ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ рдкреНрд░реЛрдЧреНрд░рд╛рдордпреЛрдЧреНрдп рд╕реНрд╡рддрдГ рдкреВрд░реНрдгрддрд╛ рдЙрдкрдХрд░рдг. WSL рдЖрдкрдХреЛ PowerShell рд╕реЗ рдмреИрд╢ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо рдЕрдкрдиреЗ рдкрд╛рд╡рд░рд╢реЗрд▓ рдлрд╝рдВрдХреНрд╢рди рд░реИрдкрд░ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рдкреВрд░реНрдгрддрд╛рдПрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреВрд░реНрдгрддрд╛рдПрдВ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрд╢ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдмреИрд╢ рдХреЗ рд╕рдорд╛рди рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде рдкреВрд░реНрдг рддрд░реНрдХ рдкреВрд░реНрдгрддрд╛ рдорд┐рд▓рддреА рд╣реИ!

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

рдкреНрд░рддреНрдпреЗрдХ рд╕реНрд╡рдд: рдкреВрд░реНрдгрддрд╛ рдкрд┐рдЫрд▓реЗ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рди рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ, рдбрдмреНрд▓реВрдПрд╕рдПрд▓ рд╕реЗ рдЬреНрдЮрд╛рдд рд╣реЛрд╕реНрдЯ рдЬреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдбреЗрдЯрд╛ рдХреЛ рдкрдврд╝рддреА рд╣реИ!

<TAB> рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрдХреНрд░рд┐рдд рд╣реЛрдЧрд╛ред <Ctrl + ╨┐╤А╨╛╨▒╨╡╨╗> рд╕рднреА рдЙрдкрд▓рдмреНрдз рд╡рд┐рдХрд▓реНрдк рджрд┐рдЦрд╛рдПрдЧрд╛.

рд╕рд╛рде рд╣реА, рдЪреВрдБрдХрд┐ рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмреИрд╢ рд╕реНрд╡рддрдГ рдкреВрд░реНрдгрддрд╛ рд╣реИ, рдЖрдк рд╕реАрдзреЗ рдкреЙрд╡рд░рд╢реЗрд▓ рдореЗрдВ рд▓рд┐рдирдХреНрд╕ рдкрдереЛрдВ рдХреЛ рд╕реНрд╡рддрдГ рдкреВрд░реНрдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!

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

рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЬрд╣рд╛рдВ рдмреИрд╢ рд╕реНрд╡рдд: рдкреВрд░реНрдгрддрд╛ рдХреЛрдИ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рджреЗрддреА рд╣реИ, рдкрд╛рд╡рд░рд╢реЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡рд┐рдВрдбреЛрдЬ рдкрде рдкрд░ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдЖрдк рдЕрдкрдиреЗ рд╡рд┐рд╡реЗрдХ рд╕реЗ рджреЛрдиреЛрдВ рд░рд╛рд╕реНрддреЛрдВ рдХрд╛ рдПрдХ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдирд┐рд╖реНрдХрд░реНрд╖

рдкреЙрд╡рд░рд╢реЗрд▓ рдФрд░ рдбрдмреНрд▓реВрдПрд╕рдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рдХреЛ рд╡рд┐рдВрдбреЛрдЬрд╝ рдореЗрдВ рдореВрд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред Win32 рдмрд┐рд▓реНрдб рдпрд╛ Linux рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдпрд╛ Linux рд╢реЗрд▓ рдкрд░ рдЬрд╛рдХрд░ рдЕрдкрдиреЗ рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЕрднреА рдбрдмреНрд▓реВрдПрд╕рдПрд▓ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ рдкреЙрд╡рд░рд╢реЗрд▓ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ ╨╕ рдЙрди рдЖрджреЗрд╢реЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░реЗрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдЖрдпрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ! рд▓рд┐рдирдХреНрд╕ рдФрд░ рд╡рд┐рдВрдбреЛрдЬ рдХрдорд╛рдВрдб рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рдлрд╝рд╛рдЗрд▓ рдкрдереЛрдВ рдХреЗ рд▓рд┐рдП рд░рд┐рдЪ рд╕реНрд╡рдд: рдкреВрд░реНрдгрддрд╛ рдРрд╕реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИ рдЬреЛ рдЖрдЬ рдореВрд▓ рд╡рд┐рдВрдбреЛрдЬ рдХрдорд╛рдВрдб рдореЗрдВ рднреА рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИред

рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб, рд╕рд╛рде рд╣реА рдЗрд╕реЗ рдЖрдкрдХреЗ рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рджрд┐рд╢рд╛рдирд┐рд░реНрджреЗрд╢ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ рдпрд╣рд╛рдВ.

рдЖрдкрдХреЛ рдХреМрди рд╕рд╛ рд▓рд┐рдирдХреНрд╕ рдХрдорд╛рдВрдб рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рд▓рдЧрддрд╛ рд╣реИ? рд╡рд┐рдВрдбреЛрдЬрд╝ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдЕрдиреНрдп рдХреМрди рд╕реА рд╕рд╛рдорд╛рдиреНрдп рдЪреАрдЬрд╝реЗрдВ рдЧрд╛рдпрдм рд╣реИрдВ? рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗрдВ рдпрд╛ рдЧреАрдерд╣рдм рдкрд░!

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ