PowerShell 如何处理“."在路径中? [英] How does PowerShell treat "." in paths?

查看:55
本文介绍了PowerShell 如何处理“."在路径中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在打开 PowerShell 终端时考虑以下命令序列:

Consider the following sequence of commands upon opening a PowerShell terminal:

PS C:\Users\username> cd source
PS C:\Users\username\source> $dir = ".\temp"
PS C:\Users\username\source> [System.IO.Path]::GetFullPath($dir)
C:\Users\username\temp

现在这个:

PS C:\Users\username> cd source
PS C:\Users\username\source> powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Users\username\source> $dir = ".\temp"
PS C:\Users\username\source> [System.IO.Path]::GetFullPath($dir)
C:\Users\username\source\temp

为什么 PowerShell 解释."相对于启动 PowerShell 的目录,而不是当前目录?我怎样才能让它解释."相对于当前目录?

Why does PowerShell interpret "." relative to the directory in which PowerShell was started, rather than the current directory? How can I get it to interpret "." relative to the current directory?

推荐答案

正如 js2010 的有用答案 所述,它是使用引入问题的.NET方法:
.NET 的单个进程范围当前目录通常和设计[1] 不同于 PowerShell 的运行空间特定 一个.

As js2010's helpful answer states, it is the use of a .NET method that introduces the problem:
.NET's single, process-wide current directory typically and by design[1] differs from PowerShell's runspace-specific one.

这具有以下含义:

  • 因为 PowerShell 本身确实可靠地将 . 解释为当前的位置(这是 PowerShell 的概括当前目录的概念也可以引用其他类型的位置,在其他 PowerShell 驱动器提供程序公开的驱动器上,例如 注册表 提供程序),您可以使用PowerShell 命令(如果可用)避免该问题.

  • Since PowerShell itself does reliably interpret . as the current location (which is PowerShell's generalization of the concept of a current directory that can refer to other types of locations as well, on drives exposed by other PowerShell drive providers, such as the registry provider), you can avoid the problem by using PowerShell commands, if available.

当您调用 .NET 方法时,请确保预先将任何相对路径解析为绝对路径,或者在支持的情况下,另外提供当前的 PowerShell 文件系统location 作为 reference 目录 - 这避免了当前目录不匹配的问题.

When you do call .NET methods, be sure to resolve any relative paths to absolute ones beforehand or, where supported, additionally supply the current PowerShell filesystem location as a reference directory - this avoids the problem of the mismatched current directories.

  • (另一个但次优的选择是每次传递相对路径时首先设置 [Environment]::CurrentDirectory = $PWD.ProviderPath ,但这是笨拙的,如果同一进程中可能存在多个 PowerShell 运行空间.)
  • (Another, but suboptimal option is to first set [Environment]::CurrentDirectory = $PWD.ProviderPath every time a relative path is passed, but that is clumsy and shouldn't be used if there's a chance that multiple PowerShell runspaces exist in the same process.)

下一部分展示了如何将相对 PowerShell 路径安全地传递给 .NET 方法,而底部部分则解决了您问题中的具体问题:如何将任意给定的 PowerShell 路径解析为绝对的本机文件系统路径.

The next section shows how to safely pass relative PowerShell paths to .NET methods, whereas the bottom section solves the specific problem in your question: how to resolve an arbitrary, given PowerShell path to an absolute, native filesystem path.

如前所述,当前目录中的差异要求将绝对路径传递给 .NET 方法,该路径基于 PowerShell 的当前目录.

As stated, the discrepancy in current directories requires that an absolute path be passed to .NET methods, arrived at based on PowerShell's current directory.

示例假设将相对路径 someFile.txt 传递给 .NET 方法 [IO.File]::ReadAllText()

The examples assume relative path someFile.txt to be passed to .NET method [IO.File]::ReadAllText()

注意使用了简单的字符串插值,用/(可以与\互换使用)来连接路径组件;如果当前目录恰好是 root 目录,您将得到 2 个路径分隔符,但这不会影响功能.但是,如果您仍然需要避免这种情况,请改用 Join-Path cmdlet.

Note that simple string interpolation is used, with / (which can be used interchangeably with \) used to join the path components; if the current directory happens to be the root directory, you'll end up with 2 path separators, but that doesn't affect functionality. If you still need to avoid that, however, use the Join-Path cmdlet instead.

  • 最简单,但不完全可靠,通过$PWD(如果当前目录基于 PowerShell 特定驱动器New-PsDrive 或者如果当前位置不是 filesystem 位置):
  • Simplest, but not fully robust, via$PWD (fails if the current directory is based on a PowerShell-specific drive created with New-PsDrive or if the current location is not a filesystem location):
[IO.File]::ReadAllText("$PWD/someFile.txt")

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆