Function 脚本组织(我的所有功能都将我的脚本弄乱)

Function 脚本组织(我的所有功能都将我的脚本弄乱),function,powershell,Function,Powershell,我有一个大脚本,我现在正在使用函数清理它。 但是,我发现把它们都放在剧本的顶端会有点乱。。我必须滚动数百行代码才能看到脚本本身 你们如何保持脚本整洁?是否将函数放在单独的文件中?一种有用的方法是将整个脚本放在函数中: #!/bin/sh main() { # The majority of the code is here } foo() { # auxiliary functions go here } main "$@" # invoke the main function

我有一个大脚本,我现在正在使用函数清理它。 但是,我发现把它们都放在剧本的顶端会有点乱。。我必须滚动数百行代码才能看到脚本本身


你们如何保持脚本整洁?是否将函数放在单独的文件中?

一种有用的方法是将整个脚本放在函数中:

#!/bin/sh

main()
{
  # The majority of the code is here
}

foo()
{
  # auxiliary functions go here
}

main "$@" # invoke the main function
我刚刚注意到这个问题被标记为
powershell
,而上面的例子是针对Bourne的。该技术可能有效,但语法可能不同。

Try#Region和#EndRegion 如果使用脚本编辑器,则可以使用如下区域:

#region Set of functions A

function foo {
    Write-Host "Just a function"
}

function bar {
    return "Just another function"
}

#endregion
当您在PowerGUI脚本编辑器中打开脚本时,区域将被折叠,因此您不必滚动到主逻辑。不过,并非所有脚本编辑器都支持区域标记

尝试点源或导入为模块
另一种方法是将函数外部化到另一个脚本中,并执行所谓的点源
。C:\myfunctions.ps1
或将它们放在一个名为
.psm1
扩展名的模块文件中,并使用
导入模块

另一种可能的解决方案是将函数分解为单独的文件,并将其打包为一个模块。然后,您可以简单地将模块导入主脚本

您最终会得到许多.ps1文件,但它确实使管理(和测试)每个单独的函数变得更加容易

关于如何做到这一点的网络广播(大约1/2英寸):

[http://powershell.com/cs/media/p/8773.aspx][1] [1] :


它还包括一个方便的模块,用于制作模块。

需要注意的一点是范围。这是行不通的:

function main{
    function1
    function2
    function3
 }

function load-functions{
     function function1 {"This is function1"}
     function function2 {"This is function2"}
     function function3 {"This is function3"}
}

load-functions
main
load functions函数将有它自己的作用域,它创建的函数将只存在于它的本地作用域中。当函数完成并释放作用域时,它们将消失

您需要在本地范围内运行这些函数,方法是点源函数,如下所示:
(请注意,点和函数名之间有一个空格。)

如果
main
未在本地作用域中运行,则它将起作用,但如果您向脚本传递参数,则需要这样做才能在脚本作用域中使用
$args

试用模块 我们采用的技术是通过脚本模块加载所有函数。我们创建了一个文件夹来保存所有单独的函数文件,并将它们进一步细分为相应的类别。完成后,我们将创建一个
.psm1
文件,告诉模块要加载什么,然后将模块路径添加到我们的PowerShell配置文件(如果不在默认模块位置)

文件夹结构 .psm1文件 Module-Name.psm1(位于同名文件夹下-必需)

配置文件 Microsoft.PowerShelle_profile.ps1/Microsoft.Powershell_profile.ps1

$LocalLibraries = "C:\Local\Path\On\Disk\"
$env:PSModulePath = $env:PSModulePath + ";$LocalLibraries"
上面的代码意味着您不必将模块存储在与其他模块相同的位置(在我们的案例中很有用,因为我们使用SVN对我们的产品进行版本化,并与我们的团队共享我们的产品)

扼要重述 重述:

  • 将函数文件命名为“func{Verb}-{Namespace}{noon}.ps1”
  • 创建顶层文件夹以保存模块psm1文件
  • 创建子文件夹以分类和保存功能,即实用程序、Active Directory、Exchange等
  • 创建“psm1”文件
  • 可选:将其他模块位置添加到配置文件中
我们在“ps1”文件前面加上“func_2;”前缀,这样当tab完成函数名时,如果与文件位于同一目录中,它就不会混淆。此外,我们在前面添加名称空间(公司缩写等),以便我们的函数名不会与任何其他添加的函数冲突

方便的重新加载功能 在开发过程中可能会用到的另一个有用提示是定义一个别名,在我们的例子中是“reload”,它将强制模块重新加载。这意味着一旦您更改了一个文件,您所要做的就是键入该文件,它将随着您的更改再次被点源化到内存中

# Function to reload Module
Function int_ModuleNameModuleLoad {
    Import-Module Module-Name -Force -WarningAction SilentlyContinue
    Write-Host "Module-Name Reloaded"
}

# Set Aliases
If (-not(Get-Alias "reload" -ErrorAction SilentlyContinue)) {
    New-Alias -Name reload -Value int_ModuleNameModuleLoad -Force
}

我之所以使用“因式”而不是正常的命名结构是因为这个函数位于我们的配置文件中,我认为它是内部的而不是完全的函数。

我希望这能给你一些好的想法,到目前为止,它对我们来说非常有用


-Adam

技术在
powershell
中有效。这是一种很棒的技术,我一直在使用:-)。将主代码保留在文件顶部,并允许在下面定义函数。确保对“main”的调用在所有函数定义之后。我将它与PowerShell和Python一起使用-也可以在其他语言中使用(William提到Bourne Shell)。非常感谢!最后,我将设置和函数拆分为两个单独的文件,并对它们进行点源搜索。谢谢你的帮助!类似的答案也有疑问,非常感谢!最后,我将设置和函数拆分为两个单独的文件,并对它们进行点源搜索。谢谢你的帮助!我刚刚在Windows PowerShell ISE中尝试了#区域提示,并确认它在那里也能正常工作。它们打开时已展开,但可以使用CTRL键折叠+M@RichardEdwards我想这只是V3的一个功能。谢谢!最后,我将设置和函数拆分为两个单独的文件,并对它们进行点源搜索。谢谢你的帮助!谢谢你的提示。这是需要注意的。
# Script Module for Company Functions
Function Get-ScriptDirectory {
    # $MyInvocation is an Automatic variable that contains runtime details and
    # we can use this to get information about where the file is run from.
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}

Get-ChildItem (Get-ScriptDirectory) -Recurse `
    | Where-Object { $_.Name -like "func_*" } `
| %{
    . $_.FullName
}
$LocalLibraries = "C:\Local\Path\On\Disk\"
$env:PSModulePath = $env:PSModulePath + ";$LocalLibraries"
# Function to reload Module
Function int_ModuleNameModuleLoad {
    Import-Module Module-Name -Force -WarningAction SilentlyContinue
    Write-Host "Module-Name Reloaded"
}

# Set Aliases
If (-not(Get-Alias "reload" -ErrorAction SilentlyContinue)) {
    New-Alias -Name reload -Value int_ModuleNameModuleLoad -Force
}