如何在Powershell下查找当前目录下是否存在文件?
How to find if a file exists under current directory under Powershell?
题目看起来很简单,我下面用的方法应该可以,但是不行:
PS C:\Users\John.Smith\Downloads> rm .\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
True
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
True
我删除了文件,但它仍然显示文件存在。我发现它正在寻找我的主目录下的文件(即使指定了“.”):
PS C:\Users\John.Smith\Downloads> rm ..\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
False
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
False
这是错误还是什么?我使用的 OS 和 Powershell 版本是:
PS C:\Users\John.Smith\Downloads> (Get-WmiObject -class Win32_OperatingSystem).Caption
Microsoft Windows Server 2012 R2 Standard
PS C:\Users\John.Smith\Downloads> $psversiontable.psversion
Major Minor Build Revision
----- ----- ----- --------
5 1 14409 1005
我自己能想到的一个解决方案是使用pwd
找到当前目录,并检查提供给我的文件是否是相对路径(不是以\或/开头),然后加入当前目录与相对路径,但我认为应该有更简单的方法,你能帮我吗?谢谢
Is this a bug or something?
不,此行为是预期的。
.NET 方法采用相对路径作为参数,将相对于调用进程的 工作目录解析它们 - 并且 powershell.exe
不会更新其当前工作目录在 PowerShell 本身内部的位置之间导航时的目录:
PS C:\Users\John.Smith> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
PS C:\Users\John.Smith> cd Downloads
PS C:\Users\John.Smith\Downloads> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
您可以通过仅传递根文件系统路径来解决它:
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("$PWD\uucode.ps1")
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists('C:\Users\John.Smith\Downloads\uucode.ps1')
... 或者,最好坚持使用 PowerShell 的提供程序 cmdlet - 在 FileSystem
位置时,Test-Path -PathType Leaf
相当于 [File]::Exists()
:
PS C:\Users\John.Smith\Downloads> Test-Path .\uucode.ps1 -PathType Leaf # always correctly resolves path relative to $PWD
如果您希望 PowerShell 始终更新主机应用程序进程的当前工作目录,您可以 do so in the prompt
function
$function:prompt = {
# Need to check that we're in the file system - can't set process directory to a registry path for example
if ($PWD.Provider.Name -eq 'FileSystem') {
[System.IO.Directory]::SetCurrentDirectory($PWD)
}
return "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
}
题目看起来很简单,我下面用的方法应该可以,但是不行:
PS C:\Users\John.Smith\Downloads> rm .\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
True
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
True
我删除了文件,但它仍然显示文件存在。我发现它正在寻找我的主目录下的文件(即使指定了“.”):
PS C:\Users\John.Smith\Downloads> rm ..\uucode.ps1
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("uucode.ps1")
False
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists(".\uucode.ps1")
False
这是错误还是什么?我使用的 OS 和 Powershell 版本是:
PS C:\Users\John.Smith\Downloads> (Get-WmiObject -class Win32_OperatingSystem).Caption
Microsoft Windows Server 2012 R2 Standard
PS C:\Users\John.Smith\Downloads> $psversiontable.psversion
Major Minor Build Revision
----- ----- ----- --------
5 1 14409 1005
我自己能想到的一个解决方案是使用pwd
找到当前目录,并检查提供给我的文件是否是相对路径(不是以\或/开头),然后加入当前目录与相对路径,但我认为应该有更简单的方法,你能帮我吗?谢谢
Is this a bug or something?
不,此行为是预期的。
.NET 方法采用相对路径作为参数,将相对于调用进程的 工作目录解析它们 - 并且 powershell.exe
不会更新其当前工作目录在 PowerShell 本身内部的位置之间导航时的目录:
PS C:\Users\John.Smith> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
PS C:\Users\John.Smith> cd Downloads
PS C:\Users\John.Smith\Downloads> [System.Environment]::CurrentDirectory
C:\Users\John.Smith
您可以通过仅传递根文件系统路径来解决它:
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists("$PWD\uucode.ps1")
PS C:\Users\John.Smith\Downloads> [System.IO.File]::Exists('C:\Users\John.Smith\Downloads\uucode.ps1')
... 或者,最好坚持使用 PowerShell 的提供程序 cmdlet - 在 FileSystem
位置时,Test-Path -PathType Leaf
相当于 [File]::Exists()
:
PS C:\Users\John.Smith\Downloads> Test-Path .\uucode.ps1 -PathType Leaf # always correctly resolves path relative to $PWD
如果您希望 PowerShell 始终更新主机应用程序进程的当前工作目录,您可以 do so in the prompt
function
$function:prompt = {
# Need to check that we're in the file system - can't set process directory to a registry path for example
if ($PWD.Provider.Name -eq 'FileSystem') {
[System.IO.Directory]::SetCurrentDirectory($PWD)
}
return "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
}