Search code examples
powershell

Expanding variables and squeezing in Powershell


$i = 0

"$($i++)" #will output nothing

"$(($i++))" #will output the old value of $i

Additionally, typing $i++ and ($i++) directly on the console will do the same.

Why? I still don't exactly understand what $() does.


Solution

  • $(...), the subexpression operator is primarily useful in expandable (double-quoted) strings, "...", which is indeed what you're trying to use it for.

    It does not modify the (often implicit) output behavior of the pipeline(s) it encloses.

    ++$i and $i++ are specialized assignment statements, which, like all assignment statements, do not produce pipeline output, but the assigned values can act as expression operands.

    In order for regular, =-based assignments to participate in an expression, they need to be enclosed in (...), the grouping operator, which for ++$i and $i++ isn't strictly necessary; e.g., ++$i + 1

    Using an (...)-enclosed assignment by itself in a pipeline also outputs the assignment value; that is, it passes the value being assigned through to the pipeline.

    • As a by-design variation, the post-increment/decrement assignments, when enclosed in (...) or participating in an expression, pass the variable's current value through, before updating the variable with the incremented/decremented value.

    Therefore, increment / decrement assignments (++ / --) too must be enclosed in (...) in order to produce output: (++$i) and ($i++)

    Inside "...", you must therefore use both (...) and $(...):

    $i = 0
    "$((++$i))" # -> 1
    "$(($i++))" # -> 1, but $i contains 2 afterwards.
    

    For a more comprehensive overview of PowerShell's output behavior, see this answer.