此问题在此处已有答案:
How can I run a PowerShell script with white spaces in the path from the command line?(5个答案)
两年前关闭。
我有一个位于Program Files
文件夹并接受参数的脚本:verbose
和restart
从其文件夹运行它工作得很好:
powershell ./<file.ps1> -verbose:$True -restart
字符串
尝试使用完整路径运行它是我遇到问题的地方:
powershell & "C:\Program Files\Folder\<file.ps1> -verbose:$True -restart"
型
上面的命令不运行脚本;相反,它打开PS命令提示符,当退出它,它打开记事本中的脚本。
我也试着把每个变量放在一个单独的引号里,但效果不好。
我找到了一个解决方法,使用progra~1
而不是Program Files
,但我想以正确的方式解决这个问题。
我错过了什么?
1条答案
按热度按时间u3r8eeie1#
顺便说一句:问题中与报价相关的部分可以通过在脚本路径中使用环境变量
$env:ProgramFiles
而不是文字"C:\Program Files\..."
来避免,这将使命令简化为:powershell "& $env:ProgramFiles\Folder\file.ps1 -verbose:$True -restart"
个实际上,为了在PowerShell中执行由带有嵌入空格的文字路径引用的脚本,这些路径必须被 * 引用 *,并且引用的路径必须 * 传递给
&
或.
*但是,当使用PowerShell's CLI时,使用
-File
(-f
)执行脚本更简单,这使得&
不必要并简化了引用:字符串
当PowerShell被 * 从外部 * 调用时,**
-File
后面的参数被 * 逐字 *(在删除语法"..."
之后,如果存在的话)-如果您从PowerShell内部运行命令,它们将不会被解释为它们的方式;例如,当从 * 外部 * PowerShell调用时,powershell -File script.ps1 $env:USERNAME
会将字符串$env:USERNAME
* 逐字 * 传递给script.ps1
,而不是扩展它-如果需要,请使用-Command
。仅当需要传递 * PowerShell代码片段 * 和/或参数时才使用
-Command
(-c
)脚本文件参数必须像在 * PowerShell内部一样解释:型
注意:为了能够将 arrays 作为脚本文件参数传递,特别需要
-Command
;参见this answer。您的尝试的关键改进是:
&
被放在"..."
内部,这可以防止cmd.exe
在PowerShell看到它之前解释它。'...'
)中,以便PowerShell将路径视为引号。注意事项:
-Command
是为了清晰起见而使用的;在 Windows PowerShell 中,它可以被省略(就像你做的那样),因为它是 default 参数;但是,请注意,在PowerShell Core 中,默认值现在是-File
。有关这两个PowerShell CLI的全面概述,请参阅this answer。"..."
字符串传递,但这样在概念上更清晰。详情见下文。
还请注意,
-File
和-Command
之间(进程)* 退出代码 * 的设置方式不同-参见this answer。至于你尝试了:
上面的命令不运行脚本;相反,它打开PS命令提示符,当退出它,它打开记事本中的脚本。
这意味着您正在从
cmd.exe
(从命令提示符或批处理文件)调用,其中未包含在"..."
中的&
具有特殊含义:它是 * 命令排序 * 运算符。也就是说,您的命令相当于以下 2 命令,按 * 顺序 * 执行:
型
第一个命令打开一个 * 交互式 * PowerShell会话。只有在您手动退出它之后,第二个命令才会执行。
请注意,您的特定症状表明您只使用了
"C:\Program Files\Folder\<file.ps1>"
,没有参数,作为第二个命令,这确实会将该脚本文件作为 document 打开,以进行 * 编辑 *。... is not recognized as an internal or external command, operable program or batch file.
为了让
cmd.exe
**将&
through 传递给被调用的命令,它必须包含在"..."
中,或者在这样的字符串之外,作为^&
**进行转义。然而,即使解决了这个 * 一个 * 问题是不够的:
型
另一个问题是,当您使用
-Command
CLI参数时,在您的情况下,PowerShell使用以下逻辑来处理参数:"..."
(如果存在)。也就是说,使用上述命令,PowerShell尝试执行具有以下逐字内容的字符串:
型
正如您所看到的,包含空格的脚本文件路径缺少必要的引号。
您有几个选项可以在脚本路径周围提供必要的引号:
如果您知道您的脚本路径 * 不 * 包含
'
字符,请使用 embedded'...'
引号:型
由于只有一个外部的
"
字符对,您不必担心cmd.exe
在到达PowerShell之前无意中解释您的参数。在这种情况下,您也可以 * 省略外部引号,但这会使 unquoted 参数容易受到
cmd.exe
不必要的解释(尽管在这种情况下没有问题),并注意'
在cmd.exe
中没有特殊意义,因此cmd.exe
将PowerShell样式的'...'
字符串视为 unquoted:型
如果您想确保即使路径中嵌入了
'
字符也能正常工作:使用嵌入式 * 双引号,将
"
转义为\"
(原文如此):型
不幸的是,这再次使
\"
示例之间的字符串受到cmd.exe
可能不必要的解释。您可以通过使用
\""
(sic)来解决这个问题,但这会使\""
示例之间的字符串受到 * 空白规范化 * 的影响:也就是说,一行中的多个空格被折叠成一个。在 Windows PowerShell 中,您可以通过使用
"^""
(原文如此)来避免这种情况,但请注意,在PowerShell Core 中,您将获得与\""
相同的行为,但在那里您可以使用""
,它可以稳健地工作。型