PowerShell文件存在性检查返回假阴性
非常简单,我需要使用PowerShell检查用户的主驱动器中是否存在文件。此脚本将在一组机器上执行,因此路径需要是相对的 电流输出:PowerShell文件存在性检查返回假阴性,powershell,Powershell,非常简单,我需要使用PowerShell检查用户的主驱动器中是否存在文件。此脚本将在一组机器上执行,因此路径需要是相对的 电流输出: # Create file named 'foo' in home dir New-Item '~/foo' # Check if the file exists [System.IO.File]::Exists('~/foo') # Returns false 列出该文件表明它确实存在: ls '~/foo' Directory: C:\Users\tom
# Create file named 'foo' in home dir
New-Item '~/foo'
# Check if the file exists
[System.IO.File]::Exists('~/foo')
# Returns false
列出该文件表明它确实存在:
ls '~/foo'
Directory: C:\Users\tom_n
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 20/02/2018 14:13 0 foo
我是不是漏掉了什么明显的东西?我还用一个实际大小的文件对此进行了测试,但也没有用
我非常感谢PowerShell CmdLet为此提供的任何输入,即测试路径:
Test-Path '~/foo'
您可以将Windows文件表示与.NET类一起使用
[System.IO.File]::Exists('.\foo')
我认为问题在于
Exists()
无法解析用~
指定的主目录。尝试使用相对或绝对路径tl;博士:
不要使用~
-使用$HOME
来引用当前用户的主目录,通常在“…”内:
或者,最好使用PowerShell的测试路径
cmdlet:
Test-Path -LiteralPath "$HOME/foo"
注:
*PowerShell和.NET类型可以互换地接受/
和\
作为路径分隔符;考虑到潜在的跨平台兼容性,请选择/
*严格地说,由于“$HOME/foo”
是在参数模式(命令行样式)下传递给测试路径的,因此在这种情况下不需要使用“…”
(尝试编写输出$HOME/foo
),但使用“…”
是一种良好的习惯,因为它适用于更广泛的场景。
PowerShell的~
与Unix上的~
不完全等效(在类似POSIX的shell中),并且可能无法按照您在PowerShell中期望的方式工作:
如[1]所述,~
在PowerShell中指的是由当前位置的驱动器提供商定义的主位置,,它:
- 可能是也可能不是文件系统
- 可以定义也可以不定义
在Windows上,考虑下面的示例,它使用注册表驱动程序提供程序:
Set-location HKCU:\Software
Set-Location ~
这将产生以下错误:
正如您所看到的,由于当前位置位于注册表提供程序的驱动器上,~
被解释为该提供程序对主位置的想法,但碰巧没有定义主位置
另一个关键区别是:
- 在Unix上,
~
是一个shell功能:它必须使用无引号,在这种情况下,在目标命令看到路径之前,shell将它扩展到完整的文本主目录,这样目标命令就可以看到文本路径,而不需要知道~
,事实上,标准实用程序不知道~
,您可以通过对比ls~
(确定)和ls'~'
(尝试列出一个按字面命名的文件/dir~
)来验证这一点
- 在PowerShell中,
~
是PowerShell驱动器提供程序功能:~
按原样传递给驱动器提供程序cmdlet,如Get ChildItem
,它们将~
解释为引用当前驱动器的主位置外部实用程序(例如,Windows上的findstr.exe
)和.NET Framework不遵循此约定,因此将~
解释为文本文件名
相比之下,是Unix的PowerShell等价物~
,具有更大的灵活性:
虽然Unix~
必须取消引号才能扩展到用户的主目录,但PowerShell的自动$home
变量也可以在双引号字符串中引用(作为正常字符串扩展(插值)的一部分)
最后,.NET类型,如[System.IO.File]
本身既不支持~
也不支持$HOME
,但通过使用“$HOME/…”
,PowerShell确保在将路径字符串传递给.NET方法之前将$HOME
替换为实际的文本主目录路径
[1] 而且,关于这个主题的官方帮助主题应该包含关于~
,,
但在撰写本文时,请不要使用测试路径(例如:Test Path~\foo.txt)进行尝试。为什么要进行向下投票?我的说法是正确的。您可以检查:[System.IO.Path]::GetFullPath(“~/asd”),它返回“currentdir/~/asd”。问题还没有解决。我只能猜测,但我想改变的两件事是,看看你是否发现了任何权威性的东西,比如从一开始我认为可能对你没有好处。此外,您的评论实际上为这些方法的工作原理增加了一个前置值。我会把它写进你的答案中。另外,如果OP在*nix意义上使用~的话,那么如果你的当前工作目录恰好是你的主目录,那么当前工作目录才是正确的答案。在任何其他目录中都是错误的。请注意。\Foo可能与~/Foo的路径相同,也可能不同。只有当你的pwd恰好是你的主目录时,它才会是相同的路径。获得一个更像*nix的命令行是Powershell最初的目标之一。关于\foo
,@EBGreen,这一点很好。请注意,~
可能指的是一个不是文件系统位置的位置,因为它相对于当前位置下的PS驱动器提供程序<相比之下,code>$HOME
总是指文件系统中用户的主目录。这应该是上帝的答案。
Set-location HKCU:\Software
Set-Location ~
Set-Location : Home location for this provider is not set. To set the home location, call "(get-psprovider 'Registry').Home = 'path'".
...