Equivalent of "&& cd $_" in Powershell

626 views Asked by At

With bash I can create a directory and immediately enter it with mkdir mydir && cd $_. Is there a powershell equivalent of $_?

1

There are 1 answers

1
Lance U. Matthews On BEST ANSWER

There are a few ways to do this. Remember that cd is an alias for the Set-Location cmdlet.

Pipe the newly-created directory to cd

PS X:\> mkdir mydir | cd
PS Microsoft.PowerShell.Core\FileSystem::X:\mydir>

Notice that after running the command the current location uses the directory's provider path.

If you don't like the visual clutter, you could instead...

Pass the newly-created directory to -Path

Via a delay-bind script block
PS X:\> mkdir mydir | cd -Path { $_ }
PS X:\mydir>

-Path must be specified as a named parameter for this to work.

Via a direct parameter value
PS X:\> cd -Path (mkdir mydir)
PS X:\mydir>

...or simply...

PS X:\> cd (mkdir mydir)
PS X:\mydir>

Pipe the newly-created directory's FullName property to cd

In a comment @zett42 suggests...

PS X:\> mkdir mydir | % FullName | cd
PS X:\mydir>

...which is a shorter way of writing...

PS X:\> mkdir mydir | ForEach-Object -MemberName 'FullName' | cd
PS X:\mydir>

...and works the same as...

PS X:\> mkdir mydir | Select-Object -ExpandProperty 'FullName' | cd
PS X:\mydir>

...and much the same as...

PS X:\> (mkdir mydir).FullName | cd
PS X:\mydir>

Use ForEach-Object to pass the $_ automatic variable to both mkdir and cd

In this answer to Create new directory and navigate into it (Windows CMD) @Shenk suggests...

PS X:\> echo mydir | % { mkdir $_; cd $_ }


    Directory: X:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         8/15/2022   2:35 PM                mydir


PS X:\mydir>

...which can be simplified to...

'mydir' | % { mkdir $_; cd $_ }

...and is much the same as...

$name = 'mydir'; mkdir $name; cd $name
Considerations

Notice that, unlike the other solutions, because the output of mkdir is not captured by a variable, pipeline, parameter, etc. it is written to the console. If this is undesirable, you'll need to explictly suppress that output with something like...

'mydir' | % { mkdir $_; cd $_ } | Out-Null

...or...

'mydir' | % { mkdir $_; cd $_ } > $null

Also, if mkdir fails then cd could be unconditionally executed, anyways. For example, this...

PS X:\> 'Directory name with invalid characters ?*' | % { mkdir $_; cd $_ }
mkdir : Illegal characters in path.
At line:1 char:51
+ 'Directory name with invalid characters ?*' | % { mkdir $_; cd $_ }
+                                                   ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (X:\Directory na...d characters ?*:String) [New-Item], ArgumentExceptio
   n
    + FullyQualifiedErrorId : CreateDirectoryArgumentError,Microsoft.PowerShell.Commands.NewItemCommand

cd : Cannot find path 'Directory name with invalid characters ?*' because it does not exist.
At line:1 char:61
+ 'Directory name with invalid characters ?*' | % { mkdir $_; cd $_ }
+                                                             ~~~~~
    + CategoryInfo          : ObjectNotFound: (Directory name ...d characters ?*:String) [Set-Location], ItemNotFoundE
   xception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS X:\>

...produces two errors, not one, after the directory could not be created due to an invalid name, and this...

PS X:\> 'Directory name that already exists' | % { mkdir $_; cd $_ }
mkdir : An item with the specified name X:\Directory name that already exists already exists.
At line:1 char:44
+ 'Directory name that already exists' | % { mkdir $_; cd $_ }
+                                            ~~~~~~~~
    + CategoryInfo          : ResourceExists: (X:\Directory name that already exists:String) [New-Item], IOException
    + FullyQualifiedErrorId : DirectoryExist,Microsoft.PowerShell.Commands.NewItemCommand

PS X:\Directory name that already exists>

...changes the current directory even after mkdir failed to create a directory that already exists.