Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows PowerShell是如何处理的&引用;在小路上?_Windows_Powershell - Fatal编程技术网

Windows PowerShell是如何处理的&引用;在小路上?

Windows PowerShell是如何处理的&引用;在小路上?,windows,powershell,Windows,Powershell,打开PowerShell终端时,请考虑以下命令序列: 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:\Use

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

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的目录而不是当前目录解释“.”?如何才能让它相对于当前目录解释“.”?

这更像是一个.net问题:

常见的解决方法:

[xml]$xml = cat file.xml
$xml.save("$pwd\file.xml")

Powershell将
视为当前位置。因此,如果您执行
getchilditem-Path“\”
,这将返回当前目录中的所有内容。要获得相对路径,您需要执行以下操作:

Set-Location -Path "Path"
$path = Get-Item -Path "file" | Resolve-Path -Relative
$path
现在将是一个相对路径

正如所述,使用.NET方法引入了问题
.NET的单一进程范围的当前目录通常在设计上[1]与PowerShell的特定于运行空间的目录不同。

这有以下影响:

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

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

    • (另一个次优选项是每次传递相对路径时首先设置
      [Environment]::CurrentDirectory=$PWD.ProviderPath
      ,但这很笨拙,如果同一进程中可能存在多个PowerShell运行空间,则不应使用。)
下一节将介绍如何安全地将相对PowerShell路径传递给.NET方法,而下一节将解决问题中的特定问题:如何将任意给定的PowerShell路径解析为绝对的本机文件系统路径


将已知的相对PowerShell路径安全地传递给.NET方法: 如上所述,当前目录中的差异要求将绝对路径传递给.NET方法,该方法基于PowerShell的当前目录到达

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

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

  • 通过
    $PWD
    (如果当前目录基于使用
    新PsDrive
    创建的特定于PowerShell的驱动器,或者如果当前位置不是文件系统位置,则会失败)最简单,但不完全健壮的
  • 更健壮:通过
    $PWD.ProviderPath
    (将基于PowerShell驱动器的路径解析为底层本机文件系统路径,但如果当前位置不是文件系统位置,则仍可能失败):
  • 完全健壮:通过
    (获取位置-PSProvider文件系统)。ProviderPath
注:上述方法适用于现有路径和不存在路径;如果已知路径存在-例如使用
[IO.File]::ReadAllText()
,而不是使用
[IO.File]::WriteAllText()
-您也可以使用以下选项,但前提是您可以进一步假设当前位置是文件系统位置:

[IO.File]::ReadAllText((Convert-Path -LiteralPath someFile.txt))
不幸的是,
转换路径
解析路径
仅适用于现有路径(从PowerShell Core 7.0.0-preview.3开始);已为不存在的路径提供选择加入

类似地,如果
转换路径
解析路径
支持
-PSProvider
参数以允许显式指定目标提供程序,这将非常有用,因为
获取位置
已经支持此参数-请参阅


将给定的任意PowerShell文件系统路径解析为绝对本机路径: 如果路径存在,请使用
转换路径
将任何PowerShell文件系统路径解析为绝对的文件系统本机路径:

$dir = "./temp"
Convert-Path -LiteralPath $dir
相关的
Resolve-Path
cmdlet提供了类似的功能,但它无法将基于PowerShell特定驱动器(使用
New PsDrive
创建)的路径解析为其底层本机文件系统路径

如果路径不存在(尚未)

在构建于.NET Core之上的PowerShell Core中,您可以使用新的
[IO.Path]::GetFullPath()
重载,该重载接受指定相对路径的引用目录:

$dir = "./temp"
[IO.Path]::GetFullPath($dir, $PWD.ProviderPath)
注意当前位置的本机文件系统路径,
$PWD.ProviderPath
,是如何作为引用目录传递的

警告:如果当前位置可能位于文件系统驱动器以外的驱动器上,请使用
(获取位置-PSProvider filesystem)。ProviderPath
可靠地引用当前文件系统位置(目录)

在Windows PowerShell中,您可以使用
[IO.Path]::Combine()
,但请注意,如果您不希望前缀出现在结果路径中,则必须手动删除前缀
/

$dir = "./temp"
[IO.Path]::Combine($PWD.ProviderPath, $dir -replace '^.[\\/]')

[1] 虽然给定的进程通常只有一个PowerShell运行空间(会话),但一个进程中多个运行空间共存的可能性意味着这是一个概念
$dir = "./temp"
Convert-Path -LiteralPath $dir
$dir = "./temp"
[IO.Path]::GetFullPath($dir, $PWD.ProviderPath)
$dir = "./temp"
[IO.Path]::Combine($PWD.ProviderPath, $dir -replace '^.[\\/]')