Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 在For循环期间显示进度_Loops_Powershell_Progress - Fatal编程技术网

Loops 在For循环期间显示进度

Loops 在For循环期间显示进度,loops,powershell,progress,Loops,Powershell,Progress,我有一个ForEach循环,我想显示它的进度: 1..254 | ForEach-Object {Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"} #^need to get a progress bar somewhere here^ 在上面的代码中,我尝试过在不同的地方使用write progress,但由于它在1-254之间循环,所以似乎无法正常工作。类似这样的内容 $i

我有一个ForEach循环,我想显示它的进度:

1..254 | ForEach-Object {Test-Connection -ErrorAction SilentlyContinue -count 
1 -TimeToLive 32 "$ipcut.$_"}
#^need to get a progress bar somewhere here^
在上面的代码中,我尝试过在不同的地方使用write progress,但由于它在1-254之间循环,所以似乎无法正常工作。

类似这样的内容

$ipCut ='192.168.1'    ### not included in the original question

$arrTest = 1..254
$all = $arrTest.Count
$i = 0
$arrTest | ForEach-Object {
   Write-Progress -PercentComplete (
       $i*100/$all) -Activity "PINGs completed: $i/$all"  -Status 'Working'
   Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
   $i++
}
参考资料:

Write Progress
cmdlet在Windows窗口中显示进度条 描述正在运行的命令状态的PowerShell命令窗口 或者剧本。您可以选择条形图反映的指示器和 显示在进度条上方和下方的文本

编辑:将上述代码重写为一行很容易:只需用分号(
)而不是换行符分隔特定命令:

$arr=1..254; $all=$arr.Count; $i=0; $arr|ForEach-Object{Write-Progress -PercentComplete ($i*100/$all) -Activity "PINGs completed: $i/$all"  -Status 'Working'; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"; $i++}
或更简单,分别使用硬编码的
1..254
254
而不是
$arr
$all

$i=0; 1..254|ForEach-Object{Write-Progress -PercentComplete ($i*100/254) -Activity "PINGs completed: $i/254"  -Status 'Working'; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"; $i++}

您不能真正添加进度条并将代码保持为单个语句,但您可以通过分号分隔所需的命令,在一行中完成:

1..254 | ForEach-Object -Begin {$i = 0} -Process {Write-Progress -PercentComplete ($i/254*100) -Activity "Tests completed: $i/254" -Status "Testing $ipcut.$_"; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"; $i++}
这使用ForEach对象命令中的
-Begin
块将计数器
$i
初始化为0。根据注释,使用这种方法,我们必须硬编码集合的总数,因为无法从ForEach对象循环中以编程方式确定它,因为每次迭代都处理集合中的单个项。这是一个很大的问题,因为您是在一个数字范围内进行管道传输,如果您是在一个集合中进行管道传输,我们可以使用该集合的
.count
属性来确定总数

然而,同样值得注意的是,使用
写入进度
时,您根本不需要显示进度条。您可以使用它向用户显示一条消息(没有移动进度条),该消息至少仍然显示进度(只是不显示您完成整个作业的距离)。这样做可以将代码简化为:

1..254 | ForEach-Object {Write-Progress -Activity "Testing $ipcut.$_"; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"}
显示了一个可行的解决方案

只需将
Write progress
命令插入现有命令的
ForEach对象
脚本块,就不可能获得进度条,但是:

传递给
ForEach Object
的脚本块无法预先知道将通过管道传递多少对象,这是以百分比表示进度的先决条件

您必须提前确定迭代次数。

如果您想概括这一点,请使用一个函数,如以下(有意保持简单):

再次注意,所有管道输入都是预先收集的

在您的情况下,您可以按如下方式调用它:

1..254 | Invoke-WithProgress {
 Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
}
1..254 | Invoke-WithProgress {
 Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
}