question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Output redirect from `mkdir` to `cd` shows unexpected internal prefix

See original GitHub issue

Prerequisites

Steps to reproduce

I am experiencing an unexpected behaviour when I created a directory and tried to redirect the output (folder-object) to cd to navigate into the created folder directly.

Expected behavior

PS E:\> mkdir Test | cd
PS E:\Test>

Actual behavior

PS E:\> mkdir Test | cd
PS Microsoft.PowerShell.Core\FileSystem::E:\Test>

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.2.6
PSEdition                      Core
GitCommitId                    7.2.6
OS                             Microsoft Windows 10.0.17763
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

image

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
jhoneillcommented, Aug 24, 2022

@mklement0 yes, interesting point . ValueFromPipelineByPropertyName doesn’t act as Value From Argument By Property name. If there were such a parameter option I have multiple places where it would have simplified function bodies, (if an object is piped use its ID property, but if something passed as an argument, check if it has an ID property, and if so use that in place of the whole object) But I’d want them kept separate.
I think, also, one piped object can go to many parameters with ByPropertyName, but an argument must bind to exactly 1 parameter.

1reaction
jhoneillcommented, Aug 23, 2022

This quirk is expected and correct (but annoying).

TLDR Use cd (mkdir test) or mkdir test | % tostring | cd instead.

First part of the explanation is that many PowerShell commands including Set-Location (alias CD) have parameters like this

    [Parameter(ParameterSetName='Path', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
    [string]$Path,

    [Parameter(ParameterSetName='LiteralPath', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
    [Alias('PSPath','LP')]
    [string]$LiteralPath

This sets the actions for piped objects as follows

  • If they have a property named Path, use that as the -Path parameter.
  • If not, but if they have a property named LiteralPath , PSPath or LP use that as the -LiteralPath parameter (there cannot be a literalpath if path already exists)
  • If they have no such property, convert the object to a string and use that as the -Path parameter

(LiteralPath doesn’t process wildcards which affects [ xx ] with the file system provider, other providers might consider * and/or ? to be legal in a path)

The second part is that if you create a new directory or get one with Get-Item / Get-ChildItem (or one of their aliases) the System.IO.DirectoryInfo object returned doesn’t have a property named path the name used is FullName , but PowerShell adds a PSPath property to files and directories,

Putting the two parts together means Get-Item PowerShell | cd Is equivalent to

 $p = Get-Item PowerShell
 Set-Location -LiteralPath $p.PSPath

Which is seldom what we want (but cd / Set-Location Does allow the current location to be something which does not have a PSDrive, - for example cd Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT. )

If we convert to a string before piping into cd, the string becomes the -Path parameter, and

 $p = Get-Item PowerShell
 Set-Location $p

will assume $P is the -path parameter, and convert it to a string. Doing that returns the fullname property, and works as expected, i.e. cd $p is equivalent to doing Set-Location -path $p.ToString()
We can skip storing the variable, so cd (mkdir test) creates the directory and passes it as the -path parameter which is then converted to a string holding the full name.

$p | command and command $p should, ideally, do the same thing and they don’t here, cd $p does what is expected and $p | cd works differently. This annoyance could be fixed by either or both:

  1. Making Fullname an alias for -Path in commands where it is a problem. This could be done with proxy function (but most people won’t go down that route).
  2. Adding an alias property .Path to file and directory objects (it is possible to define and load a types.PS1xml file to do this, but again most people won’t)

I don’t know if the effort : reward ratio means it has never been worth doing it, or whether either of those would have side-effects we don’t want. I can’t invent a case where there are side effects, but that doesn’t mean there aren’t any.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Combined `mkdir` and `cd`? [duplicate] - bash
-p used on mkdir makes it create extra directories if they do not exist yet, and -P used makes cd resolve symbolic links....
Read more >
First Time Gimp Build - Community
Hi, After three evenings of trying, Gimp is now compiling and running. :melting_face: Knowing nothing about how to “build” was a problem for ......
Read more >
Troubleshoot Azure VM Image Builder
This article helps you troubleshoot common problems and errors you might encounter when you're using Azure VM Image Builder.
Read more >
Bash Reference Manual
Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell. Redirection allows ...
Read more >
cmd/go/internal/script
The command prefix ! indicates that the command on the rest of the line (typically go or ... func (e *Engine) Execute(s *State,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found