Chi*_*ago 168 powershell
我开发了一个PowerShell函数,它执行许多涉及配置SharePoint Team站点的操作.最终,我希望函数将配置站点的URL作为String返回,因此在我的函数结束时,我有以下代码:
$rs = $url.ToString();
return $rs;
Run Code Online (Sandbox Code Playgroud)
调用此函数的代码如下所示:
$returnURL = MyFunction -param 1 ...
Run Code Online (Sandbox Code Playgroud)
所以我期待一个String,但事实并非如此.相反,它是System.Management.Automation.PSMethod类型的对象.为什么它返回该类型而不是String类型?
Goy*_*uix 254
PowerShell具有非常古怪的返回语义 - 至少从更传统的编程角度来看是这样.有两个主要想法可以解决问题:
因此,以下两个脚本块将完全有效地完成相同的操作:
$a = "Hello, World"
return $a
Run Code Online (Sandbox Code Playgroud)
$a = "Hello, World"
$a
return
Run Code Online (Sandbox Code Playgroud)
第二个示例中的$ a变量在管道上保留为输出,如上所述,返回所有输出.实际上,在第二个示例中,您可以完全省略返回,并且您将获得相同的行为(当函数自然完成并退出时,将隐含返回).
如果没有更多的函数定义,我无法说明为什么要获得PSMethod对象.我的猜测是你可能有几行没有被捕获并被放置在输出管道上.
值得注意的是,您可能不需要这些分号 - 除非您在一行上嵌套多个表达式.
您可以在TechNet 上的about_Return页面上阅读有关返回语义的更多信息,或者help return从PowerShell本身调用该命令.
Luk*_*ett 48
PowerShell的这一部分可能是最愚蠢的方面.在函数期间生成的任何无关输出都会污染结果,有时没有输出,然后在某些条件下除了计划的返回值之外还有一些其他计划外输出.
所以,我所做的是从原始函数调用中删除赋值,以便输出在屏幕上结束,然后逐步执行,直到我没有计划在调试器窗口中弹出的内容(使用PS ISE).
甚至像保留外部作用域中的变量之类的东西[boolean]$isEnabled也会导致输出,除非你这样做,否则会烦恼地吐出一个False [boolean]$isEnabled = $false.
另一个好的方法是$someCollection.Add("thing")吐出新的收藏品.
Joh*_*ker 36
使用PowerShell 5,我们现在可以创建类.将函数更改为类不仅可以键入它,而且只返回它之前的对象.这是一个非常简单的例子.
class test_class {
[int]return_what() {
Write-Output "Hello, World!"
return 808979
}
}
$tc = New-Object -TypeName test_class
$tc.return_what()
Run Code Online (Sandbox Code Playgroud)
如果这是一个函数,那么预期的输出就是
Hello World
808979
Run Code Online (Sandbox Code Playgroud)
但是作为一个类,唯一返回的是INT 808979.类是一种保证,它只返回声明的类型或void.
小智 26
作为一种解决方法,我一直在返回数组中你从函数返回的最后一个对象...不是一个很好的解决方案,但它总比没有好:
someFunction {
$a = "hello"
"Function is running"
return $a
}
$b = someFunction
$b = $b[($b.count - 1)] # Or
$b = $b[-1] # Simpler
Run Code Online (Sandbox Code Playgroud)
3lv*_*naz 12
返回之前需要清除输出。尝试使用Out-Null。这就是 powershell 的return工作原理。它返回的不是您想要的变量,而是整个函数的输出。所以你的例子是:
function Return-Url
{
param([string] $url)
. {
$rs = $url.ToString();
return
} | Out-Null
return $rs
}
$result = Return-Url -url "/sf/ask/720031511/"
Write-Host $result
Write-Host $result.GetType()
Run Code Online (Sandbox Code Playgroud)
结果是:
/sf/ask/720031511/
System.String
Run Code Online (Sandbox Code Playgroud)
归功于https://riptutorial.com/powershell/example/27037/how-to-work-with-functions-returns
现有答案是正确的,但有时您实际上并未使用 aWrite-Output或 a明确返回某些内容return,但函数结果中存在一些神秘值。这可能是内置函数的输出,如New-Item
PS C:\temp> function ContrivedFolderMakerFunction {
>> $folderName = [DateTime]::Now.ToFileTime()
>> $folderPath = Join-Path -Path . -ChildPath $folderName
>> New-Item -Path $folderPath -ItemType Directory
>> return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result
Directory: C:\temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/9/2020 4:32 PM 132257575335253136
True
Run Code Online (Sandbox Code Playgroud)
目录创建的所有额外噪音都被收集并在输出中发出。缓解这种情况的简单方法是添加| Out-Null到New-Item语句的末尾,或者您可以将结果分配给一个变量而不使用该变量。它看起来像这样......
PS C:\temp> function ContrivedFolderMakerFunction {
>> $folderName = [DateTime]::Now.ToFileTime()
>> $folderPath = Join-Path -Path . -ChildPath $folderName
>> New-Item -Path $folderPath -ItemType Directory | Out-Null
>> # -or-
>> $throwaway = New-Item -Path $folderPath -ItemType Directory
>> return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result
True
Run Code Online (Sandbox Code Playgroud)
New-Item可能是其中最著名的,但其他包括所有StringBuilder.Append*()方法,以及SqlDataAdapter.Fill()方法。
不看代码很难说。确保您的函数不会返回多个对象,并且您捕获了其他调用产生的任何结果。你得到什么:
@($returnURL).count
Run Code Online (Sandbox Code Playgroud)
无论如何,两个建议:
将对象转换为字符串:
...
return [string]$rs
Run Code Online (Sandbox Code Playgroud)
或者只是用双引号将它括起来,与上面相同但输入更短:
...
return "$rs"
Run Code Online (Sandbox Code Playgroud)
小智 5
卢克对这些场景中函数结果的描述似乎是正确的。我只想了解根本原因,PowerShell 产品团队会对此行为采取一些措施。这似乎很常见,并且花费了我太多的调试时间。
为了解决这个问题,我一直使用全局变量,而不是返回并使用函数调用中的值。
这是关于使用全局变量的另一个问题: Setting a global PowerShell variable from a function 其中全局变量名称是传递给函数的变量
我使用单个结果成员传递一个简单的Hashtable对象,以避免返回疯狂,因为我也想输出到控制台.它通过引用传递.
function sample-loop($returnObj) {
for($i = 0; $i -lt 10; $i++) {
Write-Host "loop counter: $i"
$returnObj.result++
}
}
function main-sample() {
$countObj = @{ result = 0 }
sample-loop -returnObj $countObj
Write-Host "_____________"
Write-Host "Total = " ($countObj.result)
}
main-sample
Run Code Online (Sandbox Code Playgroud)
您可以在我的GitHub项目unpackTunes中看到真实的示例用法
| 归档时间: |
|
| 查看次数: |
448915 次 |
| 最近记录: |