2

我想运行一个脚本的 15 个实例,将 5 个脚本连接在一起,到目前为止,我还没有看到精灵的灰尘。我将问题归结为一个测试用例,主脚本调用从脚本,从脚本又调用 sub_slave 脚本(重现故障不需要管道。)

如果 master.ps1 调用 slave.ps1,则每个后台作业都会在 slave.ps1 调用 sub_slave.ps1 时无限期挂起。如果我注释掉 slave.ps1 中对 sub_slave.ps1 的调用,master.ps1 将运行完成。如果我直接启动 slave.ps1,它会很好地运行对 sub_slave.ps1 的调用。这个问题似乎很棘手,但如果我尝试双链。我在文档中没有看到任何内容说您不能将这些脚本以菊花链方式连接到任意深度,但也许我的阅读不够深入?

你会看到我通过将内容添加到一个简单的文本文件来跟踪脚本的进度。

d:\jobs\master.ps1

$indexes = @(0,1,2)

$initString = "cd $pwd"
$initCmd = [scriptblock]::create($initString)

set-content -path out.txt -value "Master started"
foreach ($index in $indexes)
{
    add-content -path out.txt -value "job  starting"
    start-job -filepath slave.ps1 -InitializationScript $initCmd -ArgumentList @("master index $index originated")
}

add-content -path out.txt -value "master completed"

d:\jobs\slave.ps1

#requires -version 2.0

param (
    [parameter(Mandatory=$false)]
    [string]$message = "slave_originated"
)

begin
{
    Set-StrictMode -version Latest
    add-content -path out.txt -value "slave beginning in $pwd"
}

process
{
    add-content -path out.txt -value "slave processing $message"
    invoke-expression "D:\jobs\sub_slave.ps1 -message $message" 
}

end
{
    add-content -path out.txt -value "slave ending"
}

d:\jobs\sub_slave.ps1 #需要 -version 2.0

param (
    [parameter(Mandatory=$false)]
    [string]$message = "sub_slave originated"
)

begin
{
    Set-StrictMode -version Latest

    add-content -path out.txt -value "sub_slave beginning"
}

process
{
    add-content -path out.txt -value "sub_slave processing $message"
}

end
{
    add-content -path out.txt -value "sub_slave ending"
}

当代码按照编写的方式运行时,没有任何注释,我在 out.txt 中得到了这个:d:\jobs\out.txt

Master started
job  starting
job  starting
job  starting
master completed
slave beginning in D:\jobs
slave processing master index 0 originated
slave beginning in D:\jobs
slave processing master index 1 originated
slave beginning in D:\jobs
slave processing master index 2 originated

请注意,每条告别消息之后的下一个命令是对 sub_slave.ps1 的调用,并且根本不会出现来自 sub_slave.ps1 的消息。系统将挂起,3 个 powershell.exe 进程永远快乐地运行。Get-job 报告 3 个进程仍在运行和 HasMoreData。

我得到的唯一线索是,如果我崩溃转储挂起的进程,我会看到:

Number of exceptions of this type:        2
Exception MethodTable: 79330e98
Exception object: 012610fc
Exception type: System.Threading.ThreadAbortException
Message: <none>
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131530
-----------------

Number of exceptions of this type:        2
Exception MethodTable: 20868118
Exception object: 01870344
Exception type: System.Management.Automation.ParameterBindingException
Message: System error.
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131501
-----------------

也许我遇到了某种参数问题?如果我从 sub_slave.ps1 中删除所有参数,则行为不会改变,所以我有点怀疑,但这是可能的。我对任何想法都持开放态度。

4

2 回答 2

3

您调用 sub_slave.ps1 错误。这:

invoke-expression "D:\jobs\sub_slave.ps1 -message $message" 

应该是这样的:

D:\jobs\sub_slave.ps1 -message $message

该消息正在被评估并成为多个参数。

于 2011-03-04T00:29:02.190 回答
0

只是在这里猜测一下,但是让多个线程/作业写入同一个文件out.txt可能会导致问题。

于 2011-03-04T00:17:02.550 回答