0

所以我有一个 bash 脚本,它在双 for 循环中分叉新进程

for each date "d":
    for each instance "i":
        do-something "d" "i" &
    done
done

在 中do-something,我想增加一个计数器变量。但是,由于它是一个计数器变量,因此累积似乎不起作用。解决这个问题的最佳方法是什么?

4

2 回答 2

0

你可以这样做。当您无法取回值时,增加子外壳/进程中的计数器的主要原因是什么。在调用 do-something 之前递增,然后维护您的计数器。

#!/bin/bash

c=0
do-something ()
{
 echo 'I do some shenzi'
 sleep 20;
}

while : ; do
    while : ; do
        echo "-- Counter == $((++c))" && sleep 5;
        do-something "d" "i"  &
    done
done
于 2015-08-07T19:59:38.997 回答
0

您不能将分叉/后台脚本中的变量传递给他们的父母或兄弟姐妹,所以基本上您需要使用不同的方法。在这里,我将您的计数器存储在文件系统中。

我选择使用 Perl 是因为我想使用它的flock()功能,该功能允许我锁定包含计数器的文件,以便一次由单个进程独占访问 - 这样可以避免多个并行进程之间的竞争条件。

因此,将以下小 Perl 脚本另存为BumpCounter

#!/usr/bin/perl
use strict;
use warnings;
use Fcntl qw(:seek :flock);

# Open counter file /tmp/counter.txt
open my $fh, '+<', '/tmp/counter.txt' or die "Couldn't open file: $!";

# Lock it for exclusive access
flock($fh,LOCK_EX) or die "couldn't get lock: $!\n";

# Read current value
my $cnt=<$fh>;

# Increment value and write back
seek($fh,0,SEEK_SET);
printf $fh ++$cnt;

# Close handle
close $fh;

然后通过运行以下命令使其可执行:

chmod +x BumpCounter

然后在你的do-something脚本里面你会做

# do some work

./BumpCounter

# do some work

要查看计数器的值,只需执行

cat /tmp/counter.txt

do-something要对其进行测试,请将计数器归零,在后台启动 500秒,然后像这样检查计数器:

echo 0 > /tmp/counter.txt
for j in {0..499}; do 
   ./do-something &
done
cat /tmp/counter.txt

500

如果您喜欢这种方法,可以调整脚本以接受参数,以便它可以像这样工作:

./Counter RESET     # reset counter to zero
./Counter READ      # read counter's current value
./Counter +3        # add 3 to counter
./Counter -1        # subtract 1 from counter
于 2015-08-08T10:49:16.540 回答