Import-Module modulename
我发现了以下我不理解的行为。我的$profile
中有一些功能(具体来说,它们会更改prompt
,因此会更改function prmopt { }
),这些设置会更改我的提示,并且在启动控制台时,如果我将功能(. PromptCustom
)来源完全生效,新的提示将接管。但是,我不希望我的$profile
太大,所以我将五个或五个左右不同的提示移到了模块中,但是当我尝试对其中的任何一个进行点源处理时,什么也没发生。它们只是输出提示内容,但not会接管默认的prompt
。
目标是能够具有根据需要在提示之间切换的多种功能(即,不是一个适用于每个控制台的提示,我只需将function prompt
放在我的$profile
中)。当我将遵循以下模板的功能移动到模块时,它们全部中断,因此我想知道这是否是一个范围问题,以及如何实现在模块中具有多个提示功能的目标,我可以在这些功能之间进行切换而不是被迫将它们保留在我的$profile
中? (编辑:正如@ mklement0所指出的那样更新这个问题,因为它实际上是关于必需的目标的,即提示我可以在两者之间进行切换)。
这里是我的提示函数之一,如果在我的$profile
中定义了此函数,则该函数将作为默认提示perfectly接管,但是如果将其放入模块中则不执行任何操作:
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
函数定义,点源that在调用者的作用域自动中定义了 sourcingprompt
函数,以及shorten-path
函数[1]如果
范围是调用者的当前范围PromptShortenPath
函数在
prompt
函数的出现,交互式提示字符串也按预期更改。相反,如果在[[在模块内部]中定义了PromptShortenPath
函数,则点源表示它的源范围是调用者的] >当前作用域为不受影响
,并且从不看到嵌套的shorten-path
和prompt
函数-因此,交互式提示字符串确实发生了[[not更改。这需要重复:点源化function(与script相对)在shorten-path
和prompt
函数top-level函数隐式地(导出并)将它们都通过Import-Module
导入到调用者的作用域中,并再次,新的prompt
函数在调用者作用域中的出现会更改交互式提示字符串。也可用于模块的替代方法:最简单的解决方案是使用范围说明符 [1]请注意,虽然global:
定义嵌套函数,该说明符直接在全局范围中定义它,而不管哪个范围包含定义。作为有益的副作用,您不必再在调用时点源提示激活功能。# Use a dynamic module to simulate importing the `Set-Prompt` function
# from a (regular, persisted) module.
$null = New-Module {
function Set-Prompt {
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')
}
# Note the `global:` prefix.
Function global: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 ' '
}
}
}
# Now that Set-Prompt is imported, invoke it as you would
# any function, and the embedded `prompt` function will take effect.
Set-Prompt
shorten-path
原则上遵循PowerShell的名词-动词命名约定,但shorten
不在approved verbs列表中。
如果删除外部功能,并在模块路径中以相同名称另存为modulename.psm1,则在文件夹中:
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 ' ' } . prompt
Import-Module modulename
Import-Module modulename