我有一个脚本,它位于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
找到了一种解决方法,但我想以适当的方式解决此问题。我想念什么?
最佳答案
顺便说一句:可以通过在脚本路径中使用环境变量 Above command doesn't run the script; Instead it's opening the PS command prompt and when exiting it, it opens the script in notepad.$env:ProgramFiles
而不是文字"C:\Program Files\..."
来避免该问题的与报价相关的部分,这会将命令简化为:powershell "& $env:ProgramFiles\Folder\file.ps1 -verbose:$True -restart"
的确,为了执行在PowerShell中带有嵌入式空格的文字路径引用的脚本,必须将这些路径加引号并将引用的路径传递给&
或.
但是,当使用PowerShell's CLI时,使用-File
来执行脚本更加容易,这使得&
不再需要并简化了引用:powershell -File "C:\Program Files\Folder\file.ps1" -Verbose -Restart
从外部调用PowerShell时,从字面上接受(如果删除了语法-File
(如果存在)之后),则按字面意义接受"..."
后面的参数-如果您从PowerShell内部运行命令,它们的方式将不会被解释。例如,从PowerShell外部调用时,powershell -File script.ps1 $env:USERNAME
会将字符串$env:USERNAME
逐字传递给script.ps1
而不是扩展它-如果需要,请使用-Command
。
仅在需要传递PowerShell代码片段时使用-Command
:powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"
您尝试的关键改进是:&
放置在"..."
内,这可防止cmd.exe
在PowerShell看到它之前解释它本身。 '...'
)中,以便PowerShell将路径视为引用的路径。
注意:-Command
是为了清楚起见;在Windows PowerShell中,可以将其省略(如您所做的那样),因为它是默认参数。但是请注意,在PowerShell Core中,默认值现在为-File
。 "..."
字符串传递,但是从概念上讲,这种方式更清晰。
有关详情,请参见下文。
另请注意,-File
和-Command
之间的设置(过程)退出代码的方式有所不同-参见this answer。
至于您尝试了什么:
这意味着您是从cmd.exe
(从命令提示符或批处理文件)中调用的,其中和未包含在&
中的"..."
具有特殊含义:它是命令序列运算符。
也就是说,您的命令等效于以下两个命令,依次执行:powershell
"C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
第一个命令打开一个交互式PowerShell session 。
仅在手动退出后,第二条命令才会执行。
请注意,您的特定症状建议您仅使用"C:\Program Files\Folder\<file.ps1>"
(不带参数)作为第二个命令,该命令的确会打开该脚本文件作为文档进行编辑。
使用参数,将整个双引号字符串解释为文件名,您将获得通常的... is not recognized as an internal or external command,
operable program or batch file.
为了使能够将cmd.exe
传递给被调用的命令,必须用&
括起来,或者在这样的字符串之外,以"..."
进行转义。
但是,仅解决一个问题还不够:rem # !! Still doesn't work
powershell ^& "C:\Program Files\Folder\file.ps1 -verbose:$True -restart"
另一个问题是,当您使用^&
CLI参数时(隐含在您的情况下),PowerShell使用以下逻辑来处理参数:-Command
。
也就是说,通过上述命令,PowerShell尝试执行具有以下逐字内容的字符串:& C:\Program Files\Folder\file.ps1 -verbose:$True -restart
如您所见,脚本文件路径(包含空格)缺少必需的引号。
您有几个选项可提供有关脚本路径的必要报价:
如果您知道您的脚本路径不包含"..."
chars ,请使用嵌入式'
引用:powershell -Command "& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart"
仅需一对外部'...'
字符,您就不必担心"
在到达PowerShell之前无意间先解释了您的参数。
在这种情况下,您也可以省略外部引号,但这会使未加引号的参数容易受到cmd.exe
的不必要解释(尽管在这种情况下很好),并请注意cmd.exe
在'
中没有特殊含义,因此是PowerShell样式的cmd.exe
字符串被'...'
视为未引用:rem # Works, but generally less robust than the above.
powershell -Command ^& 'C:\Program Files\Folder\file.ps1' -Verbose:$true -Restart
如果要确保包含嵌入式cmd.exe
的偶数路径为char。可以正常工作:
使用嵌入式双引号,将'
转义为"
(sic):powershell -Command "& \"C:\Program Files\Folder\file.ps1\" -Verbose:$true -Restart"
不幸的是,这再次使得\"
实例之间的字符串可能受到\"
可能有害的解释。
您可以改为使用cmd.exe
(sic)来解决此问题,但这会使\""
实例之间的字符串经受空格标准化:即,一行中的多个空格被折叠为一个。
在Windows PowerShell中,可以通过使用\""
(sic)避免这种情况,但是请注意,在PowerShell Core中,您将获得与ojit_code相同的行为。rem # The most robust form in Windows PowerShell.
rem # Still subject to whitespace normalization in PowerShell Core.
powershell -Command "& "^""C:\Program Files\Folder\file.ps1"^"" -Verbose:$true -Restart"
关于powershell - 在命令行中使用完整路径和参数运行Powershell命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57441095/