What does $($variableName) mean in expandable strings in PowerShell?

后端 未结 2 1306
囚心锁ツ
囚心锁ツ 2020-11-27 04:51

I\'ve seen a number of example scripts online that use this. Most recently, I saw it in a script on automating TFS:

[string] $fields = \"Title=$($taskTitle);         


        
相关标签:
2条回答
  • 2020-11-27 05:25

    The syntax helps with evaluating the expression inside it.

    $arr = @(1,2,3)
    
    $msg1 = "$arr.length"
    echo $msg1 # prints 1 2 3.length - .length was treated as part of the string
    
    $msg2 = "$($arr.length)"
    echo $msg2 # prints 3
    

    You can read more at http://ss64.com/ps/syntax-operators.html

    0 讨论(0)
  • 2020-11-27 05:46

    To complement Amith George's helpful answer with more background information:

    From what I can tell, $($taskTitle) seems to be equivalent to $taskTitle.

    Indeed, in the context of "...", an expandable string (interpolating string):

    • You do NOT need $(...) with a simple variable reference such as $taskTitle or $env:HOME

      • Sometimes you must (or may choose to) use the form ${taskTitle} or ${env:HOME} - i.e., {...} around the identifier - so as to disambiguate the variable name from subsequent characters in the string.
    • You DO need $(...) for anything else:

      • accessing a property; e.g.:
        "count is: $($var.Count)"
      • embedding an expression; e.g.:
        "path prefix: $($var + '/')"
      • embedding entire commands (possibly even multiple ones); e.g.:
        "file names: $(Get-ChildItem *.txt | Select-Object -ExpandProperty Name)"

    In short:

    • $(...) inside "..." is needed for anything other than simple variable references and allows you to embed entire statements inside "..."; as usual, when the string is evaluated, the $(...) part is replaced with the (stringified) output from the embedded statement(s).

    • If you don't want to think about when $(...) is and isn't needed, you can choose to always use it (e.g., $($taskTitle)), but note that it's cumbersome to type and visually "noisy".

      • Caveat: There is an edge case where the behavior of $($var) is not the same as that of $var / ${var}, namely if $var is a collection (implementing [System.Collections.IEnumerable]) that happens to contain only a single item - see PetSerAl's comments below.
    • Unless the referenced variable's / embedded statement's value already is a string, it is stringified using the .NET .ToString() method, with the notable twist that types that support culture-sensitive stringification are stringified with the invariant culture, which, loosely speaking, is like US-English format; e.g., "$(1.2)" always yields 1.2, even in cultures where , is the decimal mark; see this answer of mine for more.

    Documentation:

    The official name for $(...) is the subexpression operator, as (tersely) documented in Get-Help about_Operators, though the explanation there doesn't discuss the operator's specific use in the context of expandable strings.

    Conversely, Get-Help about_Quoting_Rules, which discusses string literals including expandable strings, shows examples of $(...) use only in the context of expandable strings.

    0 讨论(0)
提交回复
热议问题