Powershell: λ§€κ°œλ³€μˆ˜ ꡬ문 뢄석/전달: $Args / @Argsλ₯Ό 톡해 κ°„μ ‘μ μœΌλ‘œ 전달될 λ•Œ ꡬ뢄 기호둜 콜둠이 μžˆλŠ” λͺ…λͺ…λœ 인수처럼 λ³΄μ΄λŠ” μΈμš©λ˜μ§€ μ•Šμ€ 토큰은 두 개둜 λ‚˜λ‰©λ‹ˆλ‹€.

에 λ§Œλ“  2018λ…„ 03μ›” 11일  Β·  3μ½”λ©˜νŠΈ  Β·  좜처: PowerShell/PowerShell

κ΄€λ ¨ ν•­λͺ©: #6291, #6292 및 #4624

https://github.com/PowerShell/PowerShell/issues/6292#issuecomment -371344550의 후속 쑰치:

μ°Έκ³ : -foo:bar , 이름이 μ§€μ •λœ PowerShell μΈμˆ˜μ™€ 같은 _look_ κ³Ό 같은 문제의 토큰(그리고, λ°°ν›„μ—μ„œ μ²˜μŒμ—λŠ” 항상 이와 같이 ꡬ문 λΆ„μ„λ©λ‹ˆλ‹€ - μ•„λž˜ @BrucePay 의 μ„€λͺ… μ°Έμ‘°). κ·ΈλŸ¬λ‚˜ λ‹€μŒ κ³Ό 같이 μ „λ‹¬λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. -is(λ¬Έμžμ—΄ ν™•μž₯ κ°€λŠ₯μ„± μ œμ™Έ)λŠ” μ™ΈλΆ€ ν”„λ‘œκ·Έλž¨μ„ ν˜ΈμΆœν•  λ•Œμž…λ‹ˆλ‹€.

-foo.bar 처럼 λ³΄μ΄λŠ” 토큰은 λΉ„μŠ·ν•œ 운λͺ…을 κ²ͺμŠ΅λ‹ˆλ‹€(#6291 μ°Έμ‘°).

이것은 이미 _direct_ 인수 μ „λ‹¬λ‘œ μ˜ˆμƒλŒ€λ‘œ μž‘λ™ν•©λ‹ˆλ‹€ (예:
echoArgs -foo:bar λŠ” -foo:bar λ₯Ό 단일 인수둜 μ „λ‹¬ν•©λ‹ˆλ‹€.
), ν•˜μ§€λ§Œ $Args / splatting( @Args )을 전달할 λ•ŒλŠ” μ•„λ‹™λ‹ˆλ‹€.

μ°Έκ³ : 이 λ¬Έμ œλŠ” $Args / @Args μ‚¬μš©μ˜ 근본적인 문제이며 덜 μΌλ°˜μ μ΄μ§€λ§Œ PowerShell κΈ°λ³Έ λͺ…령을 ν˜ΈμΆœν•  λ•Œμ˜ μ‚¬μš©μ—λ„ 영ν–₯을 λ―ΈμΉ©λ‹ˆλ‹€. μ•„λž˜ 주석을 μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

μž¬ν˜„ 단계

macOS λ˜λŠ” Linuxμ—μ„œ μ‹€ν–‰ν•©λ‹ˆλ‹€.

function baz {
  bash -c 'for a; do echo $a; done' - $Args   # note: same with <strong i="32">@Args</strong>
}

baz -foo:bar
'---'
baz -foo.bar

μ˜ˆμƒλ˜λŠ” 행동

-foo:bar
---
-foo.bar

μ‹€μ œ 행동

-foo:
bar
---
-foo
.bar

μΈμˆ˜κ°€ 예기치 μ•Šκ²Œ λ‘˜λ‘œ λ‚˜λ‰©λ‹ˆλ‹€. 배경은 μ—°κ²°λœ 주석을 μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

ν™˜κ²½ 데이터

PowerShell Core v6.0.1 on macOS 10.13.3
PowerShell Core v6.0.1 on Ubuntu 16.04.3 LTS
PowerShell Core v6.0.1 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.674 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Issue-Discussion WG-Language

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‚˜λŠ” μ§€λ‚œ 주에 이 문제둜 μ”¨λ¦„ν–ˆμŠ΅λ‹ˆλ‹€. @Args splattingν•œ ν›„ μ„€μ •λ˜μ§€ μ•Šμ€ κ°•μ œ μ „ν™˜ λ§€κ°œλ³€μˆ˜ κ°’(예: -foo:$bar )κΉŒμ§€ μΆ”μ ν•œ ν›„ 이것이 λͺ¨ν˜Έν•œ λ²”μœ„ 지정 λ¬Έμ œμž„μ— ν‹€λ¦Όμ—†λ‹€κ³  μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ°©μ‹μœΌλ‘œ μŠ€μœ„μΉ˜ λ§€κ°œλ³€μˆ˜ 값을 κ°•μ œ μ μš©ν•˜λ©΄ μ˜ˆμƒν•œ λ™μž‘μ΄ μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€λŠ” 사싀을 λ°œκ²¬ν–ˆμ„ λ•Œμ˜ 놀라움을 상상해 λ³΄μ‹­μ‹œμ˜€. Powershell 7 Preview 1 λ¦΄λ¦¬μŠ€μ—μ„œλ„ ν…ŒμŠ€νŠΈν–ˆμ§€λ§Œ λ™μΌν•œ λ¬Έμ œκ°€ μ—¬μ „νžˆ λ°œμƒν•©λ‹ˆλ‹€. μ•Œλ €μ§„ λ¬Έμ œκ°€ 1λ…„ 이상 μ§€λ‚œ 후에 μˆ˜μ •λ˜κΈ°λ₯Ό λ°”λžλ‹ˆλ‹€.

참고둜 버그λ₯Ό 보여주기 μœ„ν•΄ λ§Œλ“  ν…ŒμŠ€νŠΈμž…λ‹ˆλ‹€. Powershell 7 Preview 1이 μ„€μΉ˜λœ Server 2016 μ‹œμŠ€ν…œκ³Ό Powershell 5.1이 μ„€μΉ˜λœ Server 2012 R2 μ‹œμŠ€ν…œμ—μ„œ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

function foo
{
    param(
        [switch]$testArg = $false
    )

    write-host "Test arg value: '$testArg'"
}

function bar
{
    foo <strong i="9">@Args</strong>
}

$testSplat = @{
    testArg = $false
}

write-host "#### Foo tests ####"

foo
foo -testArg:$true
foo -testArg:$false
foo <strong i="10">@testSplat</strong>

write-host "#### Bar tests ####"

bar
bar -testArg:$true
bar -testArg:$false
bar <strong i="11">@testSplat</strong>

λͺ¨λ“  3 λŒ“κΈ€

μ°Έκ³ : - foo:bar 와 같은 문제의 토큰은 λͺ…λͺ…λœ PowerShell 인수처럼 λ³΄μž…λ‹ˆλ‹€.

@mklement0 #6292의 μ£Όμ„μ—μ„œ μ„€λͺ…ν–ˆλ“―이 이 _are_ 이름은 PowerShell μΈμˆ˜μž…λ‹ˆλ‹€. μ–Έμ œλ‚˜. λ§€κ°œλ³€μˆ˜ 바인딩은 컴파일이 μ™„λ£Œλœ ν›„ μ˜€λž«λ™μ•ˆ μˆ˜ν–‰λ©λ‹ˆλ‹€. 이제 컴파일된 ASTμ—μ„œ -foo: λŒ€ν•œ ν† ν°μ—λŠ” μ†ŒμŠ€ μ½”λ“œ 뒀에 곡백이 μ—†μŒμ„ λ‚˜νƒ€λ‚΄λŠ” ν”Œλž˜κ·Έκ°€ μžˆμŠ΅λ‹ˆλ‹€. NativeCommandParameterBinder λŠ” 이 AST μš”μ†Œμ— ν”Œλž˜κ·Έκ°€ μ„€μ •λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•œ λ‹€μŒ λ§€κ°œλ³€μˆ˜μ™€ 인수λ₯Ό 곡백 없이 μ—°κ²°ν•©λ‹ˆλ‹€. μ„€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ 곡백이 μ‚½μž…λ©λ‹ˆλ‹€. 이것은 μΈμˆ˜κ°€ λ¦¬ν„°λŸ΄μΈ κ²½μš°μ—λ§Œ μž‘λ™ν•©λ‹ˆλ‹€(예: NativeCommandParameter κ°€ μΈμˆ˜μ— λŒ€ν•œ AST에 μ•‘μ„ΈμŠ€ν•œ 경우). splatting의 경우 μΈμˆ˜λŠ” λ¦¬ν„°λŸ΄ μΈμˆ˜κ°€ μ•„λ‹Œ κ°’μ΄λ―€λ‘œ 곡백이 μƒκΉλ‹ˆλ‹€.

이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” ν•œ 가지 방법은 "NoSpace" 토큰 속성을 ν•΄λ‹Ή λ¬Έμžμ—΄ κ°’μ˜ λ©”νƒ€λ°μ΄ν„°λ‘œ μ „νŒŒν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. NativeCommandParameterBinder λŠ” arg 배열을 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•  λ•Œ 이 메타데이터λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. ν•΄κ²°ν•΄μ•Ό ν•  λ‹€λ₯Έ 사둀(특히 *nix νŠΉμ • 사둀)κ°€ μžˆλŠ”μ§€ μ•Œμ•„λ³΄κΈ° μœ„ν•΄ 이에 λŒ€ν•΄ μ’€ 더 생각해 λ³Ό κ°€μΉ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.

6492(μ€‘λ³΅μœΌλ‘œ λ‹«ν˜”μœΌλ―€λ‘œ)λŠ” PowerShell ν•¨μˆ˜(μ™ΈλΆ€ ν”„λ‘œκ·Έλž¨λΏλ§Œ μ•„λ‹ˆλΌ)λ₯Ό ν˜ΈμΆœν•  λ•Œ @args μŠ€ν”Œλž˜νŒ…λ„ μ†μƒλ˜μ—ˆμŒμ„ λ³΄μ—¬μ€λ‹ˆλ‹€.

λͺ…λͺ…λœ λ§€κ°œλ³€μˆ˜κ°€ μ›λž˜ μœ ν˜•κ³Ό ν•¨κ»˜ μžˆλŠ” κ·ΈλŒ€λ‘œ μ „λ‹¬λ˜κΈ°λ₯Ό κΈ°λŒ€ν•˜κΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μ§€μ›ν•˜λŠ” 것은 μ•„λ§ˆλ„ 훨씬 더 κΉŒλ‹€λ‘œμšΈ κ²ƒμž…λ‹ˆλ‹€.

λ‹€μŒμ€ λ‹¨μˆœν™”λœ μž¬ν˜„μž…λ‹ˆλ‹€.

function b {
  Param
  (
      [Switch] $p1,
      [int] $p2,
      $rest
  )
  "`$p1: [$p1]"
  "`$p2: [$p2]"
  "`$rest: [$rest]"
}

& { b <strong i="9">@args</strong> } -p1:$false 666
$p1: [True]  # `-p1:` was interpreted as just `-p1`
$p2: [0]      # `$false`, as a separate argument, was coerced to [int] 0
$rest: [666] # what was meant to be the 2nd argument was passed as the 3rd

ν•΄κ²° 방법 - 그리고 λ¨Όμ € μ‹œμž‘ν•˜λŠ” 것이 λ°”λžŒμ§ν•œ μ†”λ£¨μ…˜μ€ 쀑계 κΈ°λŠ₯μ—μ„œ λ™μΌν•œ param() 블둝을 μ •μ˜ν•˜κ³  @PSBoundParameters μž…λ‹ˆλ‹€.

λ‚˜λŠ” μ§€λ‚œ 주에 이 문제둜 μ”¨λ¦„ν–ˆμŠ΅λ‹ˆλ‹€. @Args splattingν•œ ν›„ μ„€μ •λ˜μ§€ μ•Šμ€ κ°•μ œ μ „ν™˜ λ§€κ°œλ³€μˆ˜ κ°’(예: -foo:$bar )κΉŒμ§€ μΆ”μ ν•œ ν›„ 이것이 λͺ¨ν˜Έν•œ λ²”μœ„ 지정 λ¬Έμ œμž„μ— ν‹€λ¦Όμ—†λ‹€κ³  μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ°©μ‹μœΌλ‘œ μŠ€μœ„μΉ˜ λ§€κ°œλ³€μˆ˜ 값을 κ°•μ œ μ μš©ν•˜λ©΄ μ˜ˆμƒν•œ λ™μž‘μ΄ μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€λŠ” 사싀을 λ°œκ²¬ν–ˆμ„ λ•Œμ˜ 놀라움을 상상해 λ³΄μ‹­μ‹œμ˜€. Powershell 7 Preview 1 λ¦΄λ¦¬μŠ€μ—μ„œλ„ ν…ŒμŠ€νŠΈν–ˆμ§€λ§Œ λ™μΌν•œ λ¬Έμ œκ°€ μ—¬μ „νžˆ λ°œμƒν•©λ‹ˆλ‹€. μ•Œλ €μ§„ λ¬Έμ œκ°€ 1λ…„ 이상 μ§€λ‚œ 후에 μˆ˜μ •λ˜κΈ°λ₯Ό λ°”λžλ‹ˆλ‹€.

참고둜 버그λ₯Ό 보여주기 μœ„ν•΄ λ§Œλ“  ν…ŒμŠ€νŠΈμž…λ‹ˆλ‹€. Powershell 7 Preview 1이 μ„€μΉ˜λœ Server 2016 μ‹œμŠ€ν…œκ³Ό Powershell 5.1이 μ„€μΉ˜λœ Server 2012 R2 μ‹œμŠ€ν…œμ—μ„œ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

function foo
{
    param(
        [switch]$testArg = $false
    )

    write-host "Test arg value: '$testArg'"
}

function bar
{
    foo <strong i="9">@Args</strong>
}

$testSplat = @{
    testArg = $false
}

write-host "#### Foo tests ####"

foo
foo -testArg:$true
foo -testArg:$false
foo <strong i="10">@testSplat</strong>

write-host "#### Bar tests ####"

bar
bar -testArg:$true
bar -testArg:$false
bar <strong i="11">@testSplat</strong>
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰