如何在另一个bash脚本中增加全局变量



问题,

我想要一个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上可用,但不可移植(。

当然,让脚本通过管道和套接字发送内容可以开始做一些更高级的事情,但这有点过头了。

相关内容

  • 没有找到相关文章

最新更新