Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between () and $() [duplicate]

Tags:

powershell

What's the difference between

Write-Host (Get-Date) # just paren

and

Write-Host $(Get-Date) # dollar-paren

Content within the parens could be anything, just going with a simple example. Is there any difference between the two?

I consider myself reasonably experienced with PS, but it's these little things that bug me, especially during code review and the like. Has anyone come across a good source for "here is how the language works" with enough detail to derive answers to these sorts of questions?

like image 763
Ken Hiatt Avatar asked Nov 13 '17 22:11

Ken Hiatt


3 Answers

The sub expression ($(...)) contains a StatementBlockAst. It can take any number of statements, meaning keywords (if, foreach, etc), pipelines, commands, etc. Parsing is similar to the inside of a named block like begin/process/end.

The paren expression ((...)) can contain a single ExpressionAst which is a limited subset of the AST. The most notable difference between a statement and an expression is that keywords are not parsed.

$(if ($true) { 'It worked!' })
# It worked!

(if ($true) { 'It worked!' })
# if : The term 'if' is not recognized as the name of a cmdlet, function, 
# script file, or operable program. Check the spelling of the name, or
# if a path was included, verify that the path is correct and try again.
# At line:1 char:2
# + (if ($true) { 'It worked' })
# +  ~~
#     + CategoryInfo          : ObjectNotFound: (if:String) [], CommandNotFoundException
#     + FullyQualifiedErrorId : CommandNotFoundException

Also as others have noted, the sub expression will expand in double quoted strings.

like image 63
Patrick Meinecke Avatar answered Oct 30 '22 16:10

Patrick Meinecke


The () helps with order of operations

The $() helps with evaluating values inside of the ()

For instance, if you're trying to find today's date in a string you could do the following:

echo "The length of Bryce is (Get-Date)"
echo "The length of Bryce is $(Get-Date)"

You'll see that the output is different (in one it gives you literally "(Get-Date)" whereas in the other it gives you the evaluated expression of Get-Date)

You can read more about syntax operators here

like image 28
Bryce McDonald Avatar answered Oct 30 '22 18:10

Bryce McDonald


Parenthesis are used to group and establish order just as they do in mathematics. Starting in PowerShell v3 you can also use them to evaluate a property of a group, such as getting the file names for the files in the current folder by running:

(Get-ChildItem).Name

A sub-expression $() evaluates the script within it, and then presents the output of that to be used in the command. Often times used within strings to expand a property of an object such as:

"Hello $($User.Name), would you like to play a game?"

It can also be useful when working with ComObjects, such as Excel where you may have a range that you want to test against a property of each item. While this does not work because the Range object does not have a Font property:

$Range.Font|Where{$_.Bold}

This would work, because it would output the Range as a collection of Cell objects, each of which have a Font property:

$($Range).Font|Where{$_.Bold}

You can think of sub-expressions as being a script within your script, since they can be several commands long, and the entire thing is evaluated at once so that the end output can be used for the parent command.

like image 21
TheMadTechnician Avatar answered Oct 30 '22 16:10

TheMadTechnician