gpt4 book ai didi

PowerShell 在多个提示函数和作用域之间切换

转载 作者:行者123 更新时间:2023-12-02 23:07:05 25 4
gpt4 key购买 nike

我发现了以下我不理解的行为。我的 $profile 中有一些功能(特别是更改我的 prompt ,所以 function prmopt { } )使用更改我的提示的设置,当我启动控制台时,如果我对函数( . PromptCustom )进行点源化,它会完全生效并且新的提示会接管。但是,我不想要我的 $profile太大了,所以我将五个左右不同的提示移到了一个模块中,但是当我尝试对其中任何一个进行点源时,什么都没有发生。他们只是输出提示的样子,但不作为默认值 prompt .

目标是能够根据需要在提示之间切换的多个功能(即不是适用于每个控制台的单个提示,为此我只需将 function prompt 放在我的 $profile 中)。当我将遵循以下模板的函数移动到模块时,它们都会中断,所以我想知道这是否是一个范围问题,以及如何实现在模块中拥有多个提示函数的目标,我可以在这些函数之间切换而不是被迫将它们留在我的$profile ? (编辑:正如@mklement0 指出的那样更新这个问题,因为它实际上是关于所需的目标,即有我可以在它们之间切换的提示)。

这是我的提示函数之一,如果此函数在我的 $profile但如果将其放入模块中,则什么也不做:

function PromptShortenPath {
# https://stackoverflow.com/questions/1338453/custom-powershell-prompts
function shorten-path([string] $path) {
$loc = $path.Replace($HOME, '~')
# remove prefix for UNC paths
$loc = $loc -replace '^[^:]+::', ''
# make path shorter like tabs in Vim,
# handle paths starting with \\ and . correctly
return ($loc -replace '\\(\.?)([^\\])[^\\]*(?=\\)','\$1$2')
}
function prompt {
# our theme
$cdelim = [ConsoleColor]::DarkCyan
$chost = [ConsoleColor]::Green
$cloc = [ConsoleColor]::Cyan

write-host "$([char]0x0A7) " -n -f $cloc
write-host ([net.dns]::GetHostName()) -n -f $chost
write-host ' {' -n -f $cdelim
write-host (shorten-path (pwd).Path) -n -f $cloc
write-host '}' -n -f $cdelim
return ' '
}

if ($MyInvocation.InvocationName -eq "PromptShortenPath") {
"`nWarning: Must dotsource '$($MyInvocation.MyCommand)' or it will not be applied to this session.`n`n . $($MyInvocation.MyCommand)`n"
} else {
. prompt
}
}

最佳答案

Scepticalist's helpful answer为激活您的prompt 提供有效的解决方案导入时的功能。

您问题中用于按需激活功能的方法,稍后通过点源一个功能,其中 prompt函数是嵌套的,如果该函数是从模块中导入的,则基本上不能像编写的那样工作,如下所述; 有关解决方案,请参阅底部 .

至于你尝试了什么 :

. prompt



这没有点源函数的定义 prompt ,它在采购范围内运行该功能。
  • 实际上,它(毫无意义地)打印(一次,作为输出)提示字符串应该是什么,并使函数局部变量在调用者的范围内徘徊。

  • 因此,通过嵌套 prompt PromptShortenPath 中的函数定义定义 prompt 的点源函数与 shorten-path 一起自动在调用者的范围内运行功能[1]
  • 如果您的 PromptShortenPath函数是在模块之外定义的,点源意味着源范围是(非模块)调用者的当前范围,它定义了那里的嵌套函数,并且出现了新的prompt函数,交互式提示字符串按预期更改。
  • 相比之下,如果您的 PromptShortenPath函数定义在模块内部,点源表示源范围是源模块,这意味着调用者的当前范围不受影响,并且永远不会看到嵌套的shorten-pathprompt函数 - 因此,交互式提示字符串不会改变。
  • 这需要重复:点源函数(与脚本相反)在源域域的当前范围内运行函数,而不是在调用者的当前范围内运行;也就是说,从模块中点源函数总是在该模块的当前范围内运行它,该范围与调用者的范围不同且无关(除非调用者恰好是同一模块内的顶级范围)。

  • 相比之下,怀疑论者的解决方案是通过使 shorten-pathprompt functions 模块的顶级函数,隐式(导出和)将它们都导入调用者的范围, Import-Module ,并且,再次出现新的 prompt调用者范围内的函数会更改交互式提示字符串,尽管是在导入时。

    也适用于模块的替代方法:

    最简单的解决方案是使用范围说明符 global: 定义嵌套函数。 ,它直接在全局范围内定义它,而与包含定义的范围无关。

    作为一个有益的副作用,您不再需要在调用时对提示激活函数进行点源。

    请注意,下面的解决方案嵌入了辅助函数 shorten-pathglobal:prompt确保对后者的可用性;另一种方法是定义 shorten-pathglobal:shorten-path也一样,但是没有必要用辅助函数来弄乱全局范围,特别是考虑到可能会发生名称冲突。
    # Use a dynamic module to simulate importing the `Set-Prompt` function
    # from a (regular, persisted) module.
    $null = New-Module {

    function Set-Prompt {

    # Note the `global:` prefix.
    Function global:prompt {
    # Note the *embedded* definition of helper function shorten-path,
    # which makes it available to the enclosing function only and avoids
    # the need to make the helper function global too.
    Function shorten-path([string] $path) {
    $loc = $path.Replace($HOME, '~')
    # remove prefix for UNC paths
    $loc = $loc -replace '^[^:]+::', ''
    # make path shorter like tabs in Vim,
    # handle paths starting with \\ and . correctly
    return ($loc -replace '\\(\.?)([^\\])[^\\]*(?=\\)', '\$1$2')
    }

    # our theme
    $cdelim = [ConsoleColor]::DarkCyan
    $chost = [ConsoleColor]::Green
    $cloc = [ConsoleColor]::Cyan

    Write-Host "$([char]0x0A7) " -n -f $cloc
    Write-Host ([net.dns]::GetHostName()) -n -f $chost
    Write-Host ' {' -n -f $cdelim
    Write-Host (shorten-path (pwd).Path) -n -f $cloc
    Write-Host '}' -n -f $cdelim
    return ' '
    }

    }

    }

    # Now that Set-Prompt is imported, invoke it as you would
    # any function, and the embedded `prompt` function will take effect.
    Set-Prompt

    [1] 请注意,虽然 shorten-path原则上遵循 PowerShell 的名词-动词命名约定 shorten不在 approved verbs 的列表中.

    关于PowerShell 在多个提示函数和作用域之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60659648/

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