脚本组织(我的所有功能都混乱了我的脚本)

时间:2012-02-20 14:32:49

标签: function powershell

我有一个大型脚本,我现在正在使用函数进行清理。 但是,我发现将它们放在脚本的顶部会变得有点混乱。我必须滚动过去数百行代码才能进入脚本本身。

你们如何保持脚本整洁?你的功能是否在一个单独的文件中?

5 个答案:

答案 0 :(得分:13)

尝试#Region和#EndRegion

如果您使用PowerGUI脚本编辑器,则可以使用以下区域:

#region Set of functions A

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

function bar {
    return "Just another function"
}

#endregion

当您在PowerGUI脚本编辑器中打开脚本时,区域将被折叠,因此您无需滚动即可转到主逻辑。这也是works in Microsoft ISE.并非所有脚本编辑都尊重区域标签。

尝试点源或导入为模块

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

答案 1 :(得分:9)

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

#!/bin/sh

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

foo()
{
  # auxiliary functions go here
}

main "$@" # invoke the main function

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

答案 2 :(得分:7)

尝试模块

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

文件夹结构

Module-Name\
    Subfolder1\
    Subfolder2\
    ...
    Module-Name.psm1

.psm1文件

Module-Name.psm1(位于具有相同名称的文件夹下面 - 必需)

# 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
}

个人资料档案

Microsoft.PowershellISE_profile.ps1 / Microsoft.Powershell_profile.ps1

$LocalLibraries = "C:\Local\Path\On\Disk\"
$env:PSModulePath = $env:PSModulePath + ";$LocalLibraries"

上述代码意味着您不必将模块存储在与其余模块相同的位置(在我们的案例中很有用,因为我们使用SVN来版本并与我们的团队共享我们的东西)。

小结

回顾一下:

  • 将函数文件命名为“func_ {Verb} - {Namespace} {Noun} .ps1”
  • 创建一个顶级文件夹来保存模块psm1文件
  • 创建子文件夹以对功能进行分类和保留,即实用程序,Active Directory,Exchange等。
  • 创建“psm1”文件
  • 可选:在您的个人资料中添加其他模块位置

我们在“ps1”文件前加上“func_”前缀,这样当tab完成函数名称时,如果在与文件相同的目录中,它就不会混淆。另外,我们在前面添加Namespace(公司名称缩写等),这样我们的函数名称就不会与任何其他添加的函数冲突。

方便的重装功能

在开发过程中可能派上用场的另一个有用的提示是在我们的例子中定义一个别名“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
}

我使用“int_”而不是正常命名结构的原因是,此函数位于我们的配置文件中,我认为它是内部的而不是完整的功能。

我希望这会给你一些好主意,到目前为止它对我们来说很有用!

- 亚当

答案 3 :(得分:4)

要注意的一点是范围。这不起作用:

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函数将拥有自己的作用域,它创建的函数只存在于本地作用域中。当函数完成并且范围被处理掉时,它们将消失。

你需要通过点源这样的功能来运行本地范围内的那些:
(注意点和函数名之间有一个空格。)

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

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

答案 4 :(得分:1)

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

您最终会得到一些.ps1文件,但它确实可以更轻松地管理(和测试)每个单独的功能。

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

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

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

相关问题