Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does $_ TRULY mean in PowerShell? [duplicate]

Possible Duplicate:
What does $_ mean in powershell?

I have already seen someone else's question and answer on the same subject but for me it does not answer the question.

I know how to use Select-Object, Where-Object, ForEach-Object etc and pass a script block in, for example:

dir | ForEach-Object { $_.Name }

which returns an array of all file names in the current directory.

This is similar to C#'s Select extension method:

Dir.Select(x => x.Name)

However, the above C# is easily understandable because we are passing a function to the Select method which then executes it for each element in the list.

However, the equivalent in PowerShell:

dir | ForEach-Object { param($x) $x.Name }

does not return anything. However

& { param($x) $x.Name } (dir)[0]

works as expected.

Can someone please explain the magic of $_ to someone familiar to C# but not the world of scripting? It is a special keyword? Can it be only be used in script blocks which are passed into cmdlets? How do you invoke one without piping one to ForEach-Object (or any other cmdlet)? i.e:

& { $_.Name } (dir)[0]

?

like image 698
Tahir Hassan Avatar asked Oct 25 '12 17:10

Tahir Hassan


2 Answers

The $_ is only created in the context of a pipeline, that is the passing of output objects from one command into the "input" of another. For pipeline filters (which are like functions), powershell automatically populates the $_ variable with the current object of the pipeline. Now I say current because it is important to note that when multiple objects are passed down the pipeline, the process scriptblock of your filter is executed once per object.

Now, you could rename the the pipeline objects to one of you input parameters, but you have to tell powershell that you are doing so. For e.g.:

# C:\> filter get-name-filt {Param([parameter(ValueFromPipeline=$true)]$x) $x.name}
# C:\> (dir)[0] | get-name-filt

which is not terribly convenient on the command line, hence the $_ automatic variable.

like image 190
zdan Avatar answered Sep 19 '22 08:09

zdan


The $_ is the current pipe-line item.

For example:

 dir | ForEach-Object { $_.Name }

Means:

  1. Run the dir command
  2. Pass the output to the next pipeline command
  3. ForEach-Object uses the output from dir as a variable called $_

Since the output of dir has the property .name then the pipelined $_ will also have the same property. It's simply a way to pass data down the pipe

like image 29
Nick Avatar answered Sep 21 '22 08:09

Nick