假设我在同一个文件夹中有以下powershell脚本:
mainFolder
| - subFolder
| | - MainScript.ps1
| | - SubScript.ps1
字符串
我想从MainScript.ps1
调用SubScript.ps1
,经过一些试验和错误,我发现了两种方法。(注意,我可能会从控制台调用MainScript.ps1
,当前工作目录与两个脚本所在的目录不同)
第一选项
Push-Location $PSScriptRoot
./SubScript param1 param2
Pop-Location $PSScriptRoot
型
二选项
& "$PSScriptRoot/SubScript.ps1" param1 param2
型
这两个选项是完全相等的,还是一个优先于另一个?还有其他更好的方法来调用另一个脚本吗?
正如问题所述,
1条答案
按热度按时间lf5gs5x21#
这两种选择是否完全相同?
否:第一种方法 * 会更改当前位置 *,而第二种方法不会。
也就是说,被调用的脚本可能会将不同的位置视为当前位置,从而改变它使用的任何相对路径的含义。
换句话说:
Push-Location
/PopLocation
技术仅在您必须确保脚本自身的位置(反映在自动$PSScriptRoot
变量中)是当前位置时才是必要的且仅是可取的。$PSScriptRoot
显式地形成完整的路径; Mathias指出,作为使用可扩展(插值)字符串"..."
的替代方案,你可以使用Join-Path
小字符串:字符串
如果您必须更改当前位置,则存在陷阱:
*更改当前位置(无论是通过
Push-Location
还是Set-Location
)**都是 session-global。cmd.exe
使用内部setlocal
命令将批处理文件中当前目录的更改限制为该批处理文件的能力形成对比。在POSIX兼容的shell(如Bash)中,这个问题永远不会出现,因为shell脚本在独立的 * 子进程 * 中执行。Pop-Location
(或使用Set-Location
使用存储先前位置的变量)恢复先前位置,否则最终也会更改脚本的 caller 的当前位置(可能是交互式提示符)。Pop-Location
/Set-Location
命令 * 可能无法执行 *,例如当用户使用Ctrl-C中止脚本或发生致命(脚本终止)时。您可以使用以下习惯用法来防止后者,该习惯用法利用
try
/catch
/finally
语句的finally
块来确保Pop-Location
/Set-Location
被 * 始终 * 调用:型
注意事项:
-Location
参数引入Invoke-Command
小程序来封装上述内容的提议。