gpt4 book ai didi

PowerShell 函数从函数加载

转载 作者:行者123 更新时间:2023-12-02 23:18:58 30 4
gpt4 key购买 nike

我有一个包含多个文件的模块,其中包含函数和模块加载器。

示例函数:
Function1.ps1

function Init() {
echo "I am the module initialization logic"
}

function DoStuff() {
echo "Me performing important stuff"
}

模块加载器文件:
Module1.psm1 :

$script:Functions = Get-ChildItem $PSScriptRoot\*.ps1 

function LoadModule {
Param($path)
foreach ($import in @($path)) {
. $import.FullName
}
}

LoadModule script:Functions

Init # function doesn't found

所以我试图从文件 Function1.ps1 加载函数按程序 LoadModule .
调试 LoadModule显示加载的外部函数,但在完成后 LoadModule程序函数变得无法访问,因此脚本在 Init 上失败排。

但是重写了没有 LoadModule的模块加载器功能正常
Module1.psm1 :

Get-ChildItem $PSScriptRoot\*.ps1 | %{
. $import.FullName
}
Init # In this case - all works fine

因此,当我了解从放置在某个隔离范围内的函数加载的文件函数并能够访问它们时,我需要添加一些范围标志。

也许有人知道我应该添加什么来制作函数 Init()可以从 module.pm1 脚本主体访问,但不能从外部访问(不使用 Export-ModuleMember )?

最佳答案

注意:编辑 1,对点源实际作用的说明,包含在末尾。

首先,您将函数和模块的术语和用法混合在一起。扩展名为 .psm1 的模块应使用 Import-Module cmdlet 导入终端。当点源时,比如你在这里做的,你应该只定位包含函数的脚本文件,这些文件是扩展名为 .ps1 的文件。

我对 PowerShell 也比较陌生,遇到了同样的问题。在花了大约一个小时阅读该问题后,我无法找到解决方案,但我发现的很多信息都表明这是一个范围问题。所以我创建了一个测试,使用三个文件。
foo.ps1

function foo {
Write-Output "foo"
}
bar.psm1
function bar {
Write-Output "bar"
}
scoping.ps1
function loader {
echo "dot sourcing file"
. ".\foo.ps1"
foo
echo "Importing module"
Import-Module -Name ".\bar.psm1"
bar
}

foo
bar

loader

foo
bar

pause

让我们来看看这个脚本做了什么。

首先我们定义一个虚拟 loader功能。这不是一个实用的加载器,但它足以测试范围和加载的文件中函数的可用性。此函数 dot 获取包含函数 foo 的 ps1 文件,并使用 Import-Module对于包含功能栏的文件。

接下来,我们调用函数 foobar ,这将产生错误,以便确定两者都不在当前范围内。虽然不是绝对必要的,但这有助于说明他们的缺席。

接下来,我们调用 loader功能。网点采购后 foo.ps1 , 我们看到 foo成功执行,因为 fooloader 的当前范围内功能。使用后 Import-Module对于 bar.psm1 , 我们看到 bar也成功执行了。现在我们退出 loader 的范围函数并返回主脚本。

现在我们看到 foo 的执行失败并出现错误。这是因为我们点源 foo.ps1在函数的范围内。但是,因为我们导入了 bar.psm1 , bar 成功执行。这是因为模块默认导入全局范围。

我们如何使用它来改善您的 LoadModule功能?此功能的主要内容是您需要切换到对导入的函数使用模块。请注意,根据我的测试,您不能 Import-Module 加载程序功能;这仅在您点源加载程序时才有效。
LoadModule.ps1
function LoadModule($Path) {
Get-ChildItem -Path "$Path" -Filter "*.psm1" -Recurse -File -Name| ForEach-Object {
$File = "$Path$_"
echo "Import-Module -Name $File"
Import-Module -Name "$File" -Force
}
}

现在在终端中:
. ".\LoadModule.ps1"
LoadModule ".\"
foo
bar

编辑 1:关于点源的进一步说明

点源相当于将指定文件的内容复制粘贴到形成点源的文件中。执行操作的文件逐字“导入”目标的内容,在继续执行“导入”代码之前不执行任何其他操作。例如
foo.ps1 Write-Output "I am foo"

. ".\bar.ps1"
bar.ps1
Write-Output "I am bar"

有效地
Write-Output "I am foo"
Write-Output "I am bar"

关于PowerShell 函数从函数加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57267958/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com