问题,
我想要一个bash脚本,它将有一个全局变量,可以从其他bash脚本中递增。
示例:我有一个脚本如下:
#! /bin/bash
export Counter=0
for SCRIPT in /Users/<user>/Desktop/*sh
do
$SCRIPT
done
echo $Counter
该脚本将调用文件夹中的所有其他bash脚本,这些脚本将具有如下内容:
if [ "$Output" = "$Check" ]
then
echo "OK"
((Counter++))
如果它等于"OK",我希望它增加$Counter变量,然后将该值传递回初始批处理脚本,这样我就可以保留该计数器编号,并在末尾有一个总数。
你知道怎么做吗?
环境变量只在一个方向上传播——从父级传播到子级。因此,子进程无法更改其父进程中环境变量集的值。
您可以使用文件系统:
export counter_file=$(mktemp "$HOME/.counter.XXXXXX")
for script in ~user/Desktop/*sh; do "$script"; done
并且,在单独的脚本中:
counter_curr=$(< "$counter_file" )
(( ++counter_curr ))
printf '%sn' "$counter_curr" >"$counter_file"
这在当前不是并发安全的,但您当前编写的父脚本永远不会一次调用多个子脚本。
假设跟踪的值相对较小,一种更简单的方法是使用文件大小作为计数器值的代理。要做到这一点,递增计数器就这么简单:
printf 'n' >>"$counter_file"
在O(1(时间内检查其值——无需打开文件并读取其内容——就像检查文件大小一样简单;使用GNU stat
:
counter=$(stat -f %z "$counter_file")
请注意,如果使用的文件系统(如NFS(没有正确实现O_APPEND
,则可能需要锁定以确保并发安全;请参阅Norman Gray的答案(这要归功于它的灵感(,了解一个有效的实现。
您可以source
其他脚本,这意味着它们不是在子进程中运行,而是在调用脚本中"内联"运行,如下所示:
#! /bin/bash
export counter=0
for script in /Users/<user>/Desktop/*sh
do
source "$script"
done
echo $counter
但正如评论中所指出的,我只建议在您自己控制调用的脚本的情况下使用这种方法。例如,如果它们的exit
或变量相互冲突,可能会发生不好的事情。
如上所述,您无法做到这一点,因为没有任何东西对应于shell脚本的"全局变量"。
正如注释所示,您必须使用文件系统在脚本之间进行通信。
做你所描述的事情的一种简单/粗略的方法是让每个协作脚本在文件中附加一行,"全局计数"就是这个文件的大小:
#! /bin/sh -
echo ping >>/tmp/scriptcountfile
则CCD_ 5是发生的次数。当然,那里有一个潜在的竞争条件,所以下面这样的东西会对这些访问进行排序:
#! /bin/sh -
(
flock -n 9
echo 'do stuff...'
echo ping >>/tmp/stampfile
) 9>/tmp/lockfile
(flock
命令在Linux上可用,但不可移植(。
当然,让脚本通过管道和套接字发送内容可以开始做一些更高级的事情,但这有点过头了。