如何在并行化 bash 脚本中递增变量
How to increment a variable in parallelized bash script
所以我有一个 bash 脚本,它在双 for 循环中分叉新进程
for each date "d":
for each instance "i":
do-something "d" "i" &
done
done
并且在 do-something
中,我想增加一个计数器变量。但是,由于它是一个计数器变量,因此累积似乎不起作用。解决此问题的最佳方法是什么?
你可以这样做。当您无法取回值时,增加子 shell/process 中的计数器的主要原因是什么。在调用 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
您不能将变量从 forked/backgrounded 脚本传递给它们的 parents 或兄弟姐妹,所以基本上您需要使用不同的方法。在这里,我将您的计数器存储在文件系统中。
我选择使用 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
要测试它,请将计数器归零,在后台启动 500 do-something
秒,然后像这样检查计数器:
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
所以我有一个 bash 脚本,它在双 for 循环中分叉新进程
for each date "d":
for each instance "i":
do-something "d" "i" &
done
done
并且在 do-something
中,我想增加一个计数器变量。但是,由于它是一个计数器变量,因此累积似乎不起作用。解决此问题的最佳方法是什么?
你可以这样做。当您无法取回值时,增加子 shell/process 中的计数器的主要原因是什么。在调用 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
您不能将变量从 forked/backgrounded 脚本传递给它们的 parents 或兄弟姐妹,所以基本上您需要使用不同的方法。在这里,我将您的计数器存储在文件系统中。
我选择使用 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
要测试它,请将计数器归零,在后台启动 500 do-something
秒,然后像这样检查计数器:
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