【问题标题】:File path with quotation mark issue of PowershellPowershell带引号问题的文件路径
【发布时间】:2018-05-25 07:04:00
【问题描述】:

我试图编写一个脚本来测试文件路径的可用性。其中一个过程是用户必须输入文件路径或只需将文件拖到 Powershell 命令提示符中。

在这个过程中, 用户将输入文件路径,如 C:\Program Files\7-Zip\7z.exe,该字符串将成为 $filePath 变量的值,该变量将用作Test-Path 命令的参数。

但有时,用户只需将文件拖到 Powershell 命令提示符中,这样字符串就会包含一对引号,就像图片 1 一样。 ("C:\Program Files\7-Zip\7z.exe") Picture 1

然后你会看到,当我尝试使用带有 $filePath 变量的 Test-Path 命令测试路径时,而 $filePath 的值(字符串)包含一对 引号,结果即使路径存在且有效,也将始终为 False。 但是当我使用相同的 Test-Path 命令不使用变量(我的意思是只是将文件路径复制并粘贴到命令中)时,它可以正常工作。

这很奇怪!

我尝试通过键盘将文件路径输入到变量中,而不是将文件拖到 Powershell 命令提示符中。 (不带引号) 然后使用相同的方法测试文件路径(使用变量作为文件路径)。它工作正常。

Picture 2

我不明白。它们不是一回事吗?

什么时候

$filePath = "C:\Program Files\7-Zip\7z.exe"

以下 2 个命令应该有相同的结果!为什么他们不是?

Test-Path -Path $filePath
Test-Path -Path "C:\Program Files\7-Zip\7z.exe"

【问题讨论】:

  • 我认为这种行为是正常的。当变量包含 "Something" 时,就像您在控制台中写 '" Something"' 一样
  • 不是一个完整的骗局,但与您的问题非常相关:stackoverflow.com/q/49817534
  • 文件名/路径不能包含引号 (") 字符。引号用于命令行解析器指定参数(表示参数包含空格)——引号不是参数的一部分。

标签: powershell


【解决方案1】:

在拖放的情况下,如果路径没有空格,它将返回 true 。如果它有一个空格,那么 PowerShell 会在它周围加上引号。在这种情况下,PowerShell 确实将路径视为"C:\Program Files\7-Zip\7z.exe"

你可以做的是像这样使用-replace 运算符 -

Test-Path -path ($filepath -replace '"', "") -PathType Leaf

根据 cmets 中 @Josefz 的建议,您也可以使用 Trim() 方法,例如 -

Test-Path -path ($filepath.Trim('"')) -PathType Leaf

不完全是对您的问题的解释,但您可以将其用作解决方法。

【讨论】:

  • 试试$filePath.Trim('"')而不是-replace
  • @JosefZ - 也可以,但有什么具体原因吗?
  • "如果路径没有空格,它将返回 true" - 不完全是。问题是" 字符,而不是空格。
  • 是的,问题是",当用户将路径拖放到PowerShell控制台并且文件路径包含空格(例如C:\Program Files)时,它就会出现,那么双引号是自动放置。当 OP 拖放到 PoSh 控制台时,他正在谈论类似的问题。我正是这个意思。编辑了答案以使其更有意义。
  • 正确--使用拖放时会添加引号,因为假设文件名将在命令行上使用并且需要作为单个参数进行解析。 (" 字符不是文件名的一部分。)
【解决方案2】:

如果用户键入的文件名包含嵌入的" 字符,则Test-Path 将返回$false。为什么?文件名不能包含" 字符;解析器使用" 字符来指示字符串中的参数包含空格。所以这当然会返回$false

$filePath = '"C:\Program Files\7-Zip\7z.exe"'
Test-Path $filePath

嵌入的" 字符不是文件名的一部分;您需要省略它们以使结果为$true

【讨论】:

  • 是的!当我使用 Read-Host cmdlet 时,它会将我输入的所有内容保存为包含引号“”的字符串。我需要做的就是使用像@Vivek Kumar Singh 所说的 Trim() 方法删除引号
【解决方案3】:

您使用的是哪个版本的 powershell?我得到true 两个命令

PS C:\Users> $filePath = "C:\Program Files\7-Zip\7z.exe"
PS C:\Users> Test-Path -Path $filePath
True
PS C:\Users> Test-Path -Path "C:\Program Files\7-Zip\7z.exe"
True
PS C:\Users> $PSVersionTable.PSVersion
Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      17134  48    

编辑 ----------

知道了,问题是 Read-Host 会按字面意思保存字符串,并带有引号。简单的解决方案是删除引号

PS C:\Users> $filePath = Read-Host -Prompt "enter input"
enter input: "C:\Program Files\7-Zip\7z.exe"
PS C:\Users> $filePath
"C:\Program Files\7-Zip\7z.exe"
PS C:\Users> Test-Path -Path $filePath
False
PS C:\Users> Test-Path -Path $filePath.replace("`"","")
True

【讨论】:

  • 他的文件路径变量包含"C:\Program Files\7-Zip\7z.exe" 而不是C:\Program Files\7-Zip\7z.exe。就像你会写 test-path '"C:"' 这在 powershell 5 中也是错误的
  • @guiwhatsthat test-path '"C:"' 不一定是假的。
  • @PetSerAl 当我像test-path '"C:"' 这样编写命令时,结果将是错误的。什么时候会是真的?你能解释一下吗?
  • @guiwhatsthat New-PSDrive '"C' Variable \ | Out-Null; ${"} = 'Exist'; test-path '"C:"'
  • 是的。这是因为读取主机!谢谢你,兄弟!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
相关资源
最近更新 更多