PowerShell에 권장되는 코딩 스타일은 무엇입니까?
PowerShell 스크립트를 작성하는 권장 코딩 스타일이 있습니까?
코드를 어떻게 구성하느냐가 문제가 아닙니다(모듈을 사용하는 경우 기능 수 등).'어떻게 코드를 읽을 수 있게 쓰는가' 입니다.
프로그래밍 언어에는 몇 가지 권장 코딩 스타일(입체할 항목, 들여쓰기 방법 - 공백/탭, 새 줄 만들기, 중괄호 삽입 위치 등)이 있지만 PowerShell에 대한 권장 사항은 없습니다.
특히 관심이 있는 분야는 다음과 같습니다.
파라미터의 기입방법
function New-XYZItem
( [string] $ItemName
, [scriptblock] $definition
) { ...
('V1' 구문에 가깝군요)
또는
function New-PSClass {
param([string] $ClassName
,[scriptblock] $definition
)...
또는 (빈 Atribute를 추가하는 이유)
function New-PSClass {
param([Parameter()][string] $ClassName
,[Parameter()][scriptblock] $definition
)...
또는 (Jaykul의 코드에서 본 다른 포맷)
function New-PSClass {
param(
[Parameter()]
[string]
$ClassName
,
[Parameter()]
[scriptblock]
$definition
)...
아니면...?
복잡한 파이프라인 작성 방법
Get-SomeData -param1 abc -param2 xyz | % {
$temp1 = $_
1..100 | % {
Process-somehow $temp1 $_
}
} | % {
Process-Again $_
} |
Sort-Object -desc
또는 (새 행의 cmdlet 이름)
Get-SomeData -param1 abc -param2 xyz |
% {
$temp1 = $_
1..100 |
% {
Process-somehow $temp1 $_
}
} |
% {
Process-Again $_
} |
Sort-Object -desc |
그리고 만약 그 안에-begin
,-process
,그리고.-end
파라미터?어떻게 하면 가장 읽기 쉽게 만들 수 있을까요?
Get-SomeData -param1 abc -param2 xyz |
% -begin {
init
} -process {
Process-somehow2 ...
} -end {
Process-somehow3 ...
} |
% -begin {
} ....
또는
Get-SomeData -param1 abc -param2 xyz |
% `
-begin {
init
} `
-process {
Process-somehow2 ...
} `
-end {
Process-somehow3 ...
} |
% -begin {
} ....
여기서 들여쓰기는 중요한데 어떤 요소를 새 줄에 넣는지도 중요합니다.
지금까지 자주 생각나는 질문만 다루었습니다.그 밖에도 몇 가지 질문이 있습니다만, 이 스택 오버플로우 질문은 짧게 하고 싶습니다.
그 외의 제안은 모두 환영입니다.
PowerShell v2.0에 대해 몇 년 동안 자세히 살펴본 결과 다음과 같이 결론을 내렸습니다.
<#
.SYNOPSIS
Cmdlet help is awesome. Autogenerate via a template so I never forget.
.DESCRIPTION
.PARAMETER
.PARAMETER
.INPUTS
.OUTPUTS
.EXAMPLE
.EXAMPLE
.LINK
#>
function Get-Widget
{
[CmdletBinding()]
param (
# Think about which parameters users might loop over. If there is a clear
# favorite (80/20 rule), make it ValueFromPipeline and name it InputObject.
[parameter(ValueFromPipeline=$True)]
[alias("Server")]
[string]$InputObject,
# All other loop candidates are marked pipeline-able by property name. Use Aliases to ensure the most
# common objects users want to feed in will "just work".
[parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$True)]
[alias("FullName")]
[alias("Path")]
[string[]]$Name,
# Provide and document defaults for optional parameters whenever possible.
[parameter(Position=1)]
[int]$Minimum = 0,
[parameter(Position=2)]
[int]$ComputerName = "localhost",
# Stick to standardized parameter names when possible. *Especially* with switches. Use Aliases to support
# domain-specific terminology and/or when you want to expose the parameter name of the .Net API you're wrapping.
[parameter()]
[Alias("IncludeFlibbles")]
[switch]$All,
)
# The three main function blocks use this format if & only if they are short one-liners
begin { $buf = new-list string }
# Otherwise they use spacing comparable to a C# method
process
{
# Likewise, control flow statements have a special style for one-liners
try
{
# Side Note: internal variables (which may be inherited from a parent scope)
# are lowerCamelCase. Direct parameters are UpperCamelCase.
if ($All)
{ $flibbles = $Name | Get-Flibble }
elseif ($Minimum -eq 0)
{ $flibbles = @() }
else
{ return }
$path = $Name |
? { $_.Length -gt $Minimum } |
% { $InputObject.InvokeGetAPI($_, $flibbles) } |
ConvertTo-FullPath
}
finally { Cleanup }
# In general, though, control flow statements also stick to the C# style guidelines
while($true)
{
Do-Something
if ($true)
{
try
{
Do-Something
Do-Something
$buf.Add("abc")
}
catch
{
Do-Something
Do-Something
}
}
}
}
}
<#
Pipelines are a form of control flow, of course, and in my opinion the most important. Let's go
into more detail.
I find my code looks more consistent when I use the pipeline to nudge all of PowerShell's supported
language constructs (within reason) toward an "infix" style, regardless of their legacy origin. At the
same time, I get really strict about avoiding complexity within each line. My style encourages a long,
consistent "flow" of command-to-command-to-command, so we can ensure ample whitespace while remaining
quite compact for a .NET language.
Note - from here on out I use aliases for the most common pipeline-aware cmdlets in my stable of
tools. Quick extract from my "meta-script" module definition:
sal ?? Invoke-Coalescing
sal ?: Invoke-Ternary
sal im Invoke-Method
sal gpv Get-PropertyValue
sal spv Set-PropertyValue
sal tp Test-Path2
sal so Select-Object2
sal eo Expand-Object
% and ? are your familiar friends.
Anything else that begins with a ? is a pseudo-infix operator autogenerated from the Posh syntax reference.
#>
function PipelineExamples
{
# Only the very simplest pipes get to be one-liners:
$profileInfo = dir $profile | so @{Path="fullname"; KBs={$_.length/1kb}}
$notNull = $someString | ?? ""
$type = $InputObject -is [Type] | ?: $InputObject $InputObject.GetType()
$ComObject | spv Enabled $true
$foo | im PrivateAPI($param1, $param2)
if ($path | tp -Unc)
{ Do-Something }
# Any time the LHS is a collection (i.e. we're going to loop), the pipe character ends the line, even
# when the expression looks simple.
$verySlowConcat = ""
$buf |
% { $verySlowConcat += $_ }
# Always put a comment on pipelines that have uncaptured output [destined for the caller's pipeline]
$buf |
? { $_ -like "*a*" }
# Multi-line blocks inside a pipeline:
$orders |
? {
$_.SaleDate -gt $thisQuarter -and
($_ | Get-Customer | Test-Profitable) -and
$_.TastesGreat -and
$_.LessFilling
} |
so Widgets |
% {
if ($ReviewCompetition)
{
$otherFirms |
Get-Factory |
Get-ManufactureHistory -Filter $_ |
so HistoryEntry.Items.Widgets
}
else
{
$_
}
} |
Publish-WidgetReport -Format HTML
# Mix COM, reflection, native commands, etc. seamlessly
$flibble = Get-WmiObject SomethingReallyOpaque |
spv AuthFlags 0xf -PassThru |
im Put() -PassThru |
gpv Flibbles |
select -first 1
# The coalescing operator is particularly well suited to this sort of thing
$initializeMe = $OptionalParam |
?? $MandatoryParam.PropertyThatMightBeNullOrEmpty |
?? { pwd | Get-Something -Mode Expensive } |
?? { throw "Unable to determine your blahblah" }
$uncFolderPath = $someInput |
Convert-Path -ea 0 |
?? $fallback { tp -Unc -Folder }
# String manipulation
$myName = "First{0} Last{1} " |
?+ "Suffix{2}" |
?replace "{", ": {" |
?f {eo richard berg jr | im ToUpper}
# Math algorithms written in this style start to approach the elegance of functional languages
$weightedAvg = $values |
Linq-Zip $weights {$args[0] * $args[1]} |
Linq-Sum |
?/ ($weights | Linq-Sum)
}
# Don't be afraid to define helper functions. Thanks to the script:Name syntax, you don't have to cram them into
# the begin{} block or anything like that. Name, parameters, etc don't always need to follow the cmdlet guidelines.
# Note that variables from outer scopes are automatically available. (even if we're in another file!)
function script:Cleanup { $buf.Clear() }
# In these small helpers where the logic is straightforward and the correct behavior well known, I occasionally
# condense the indentation to something in between the "one liner" and "Microsoft C# guideline" styles
filter script:FixComputerName
{
if ($ComputerName -and $_) {
# Handle UNC paths
if ($_[1] -eq "\") {
$uncHost = ($_ -split "\\")[2]
$_.Replace($uncHost, $ComputerName)
} else {
$drive = $_[0]
$pathUnderDrive = $_.Remove(0,3)
"\\$ComputerName\$drive`$\$pathUnderDrive"
}
} else {
$_
}
}
Stack Overflow 구문 형광펜이 완전히 포기되었습니다.ISE에 붙여넣습니다.
PowerShell에 대한 가장 포괄적인 코딩 스타일 리소스는 여전히 PowerShell 모범 사례 및 스타일 가이드라고 생각합니다.
소개부터:
영어 철자법이나 문법 규칙과 마찬가지로 PowerShell 프로그래밍의 베스트 프랙티스나 스타일 규칙에도 거의 예외는 있지만 코드 구조, 명령어 설계, 프로그래밍, 포맷, 심지어 스타일에 대한 기준선을 문서화하고 있습니다.이 기준선은 일반적인 문제를 피하고 보다 재사용 가능한 것을 가능하게 합니다.읽을 수 있는 코드 - 재사용 가능한 코드를 다시 작성할 필요가 없으며 읽을 수 있는 코드를 유지할 수 있습니다.
GitBook 링크도 이용할 수 있게 되었습니다.
저는 최근에 PowerShell의 들여쓰기 스타일에 관한 훌륭한 점을 발견했습니다.링크된 코멘트에 따라 다음 구문의 차이를 확인합니다.
1..10 | Sort-Object
{
-$_
}
그리고.
1..10 | Sort-Object {
-$_
}
로마법을 따르며 표준 C# 들여쓰기 스타일(Allman, 거의)을 사용하는 것이 나의 성향이지만, 나는 이 예외와 이와 유사한 다른 것에 대해 문제 삼는다.
이것에 의해, 개인적으로 마음에 드는 1 TBS를 사용하고 싶다고 생각하고 있습니다만, 그렇지 않으면 납득할 수 있습니다.궁금해서 어떻게 정착했어요?
언급URL : https://stackoverflow.com/questions/2025989/what-is-the-recommended-coding-style-for-powershell
'programing' 카테고리의 다른 글
BOM을 사용하지 않고 PowerShell을 사용하여 UTF-8에 파일 쓰기 (0) | 2023.04.08 |
---|---|
Flatter Doctor --android-licenses : 스레드 "main" java.lang에 예외가 있습니다.NoClassDefFoundError(NoClassDefFound 오류) (0) | 2023.04.08 |
PowerShell 콘솔에 쓰는 방법 (0) | 2023.04.08 |
PowerShell - 시작 프로세스 및 cmdline 스위치 (0) | 2023.04.08 |
SQL Server 2008에서 문자열에 선행 0을 패딩하여 3자 길이 설정 (0) | 2023.04.08 |