如何在多个包含文件的文件夹中自动执行三个bash脚本?

2024-04-18 16:19:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有大量的文件,每个文件都将被解码、排序/最小化,然后放入数据库。每个操作都有自己的bash脚本。这些文件被分类到每日文件中,这些文件位于其连续的每月文件夹中。问题是只有一个数据库,只有一个表(SQLite),因此数据库脚本一次只能在一个文件上运行,而解码和排序可以同时在大约四个文件上执行。你知道吗

对于要排序的文件,必须经过解码过程,对于要放入数据库的文件,必须对其进行解码和排序。这些脚本的运行时间不一样,我相信解码是禁食,然后是输入,然后是排序。你知道吗

每个bash脚本decode.shsort.shsaveintodb.sh循环遍历文件夹中的所有文件并执行其工作。你知道吗

最初我认为有一个主脚本可以执行decode.sh->;sort.sh->;saveintodb.sh 每个文件夹(月)。你知道吗

然而,由于预计这需要几天时间,我想到了这样的事情:

1: decode.sh January
2: sort.sh January,       decode.sh February
3: saveintodb.sh January  sort.sh February        decode.sh March
4:                        saveintodb.sh February  sort.sh March     decode.sh April

等等。。截至12月。你知道吗

然而,我不知道我是如何建立这个,在一个好的方式。我知道我可以并行运行2:中的脚本,但是我不太确定当2:完成时如何自动运行脚本3:的。你知道吗

我也不确定这是否是最好的方法。理想情况下,始终有一个解码脚本、一个排序脚本和一个saveintodb脚本在运行。甚至可能有几个解码和排序脚本(不知道这是否会加快进程,我正在使用一个外部HD)。你知道吗

数据量:1.3 TB

数据类型:文本文件

背景:位置报告(纬度/经度、时间)

抱歉这么长的文字,有什么建议吗?你知道吗


Tags: 文件gt脚本文件夹bash数据库排序sh
3条回答

使用GNU Parallel,它看起来是这样的:

doit() {
  sem  id decode decode.sh $1
  sem  id sort sort.sh $1
  sem  id dbsave saveintodb.sh $1
}
export -f doit
parallel -j4 doit {} ::: Jan Feb Mar ...   

这将确保您一次运行一个解码、排序和saveintodb。如果您只想保护saveintodb:

doit() {
  decode.sh $1
  sort.sh $1
  sem  id dbsave saveintodb.sh $1
}
export -f doit
parallel -j4 doit {} ::: Jan Feb Mar ...

在这里,您将运行4个解码/排序,但只有一个saveintodb。你知道吗

sem是GNU Parallel的一部分。你知道吗

gnupallel是一个通用的并行程序,它使得在同一台机器上或在您有ssh访问权限的多台机器上并行运行作业变得很容易。它通常可以替换for循环。你知道吗

如果有32个不同的作业要在4个CPU上运行,那么并行化的直接方法是在每个CPU上运行8个作业:

Simple scheduling

当一个进程完成时,GNU Parallel会生成一个新进程—保持CPU的活动状态,从而节省时间:

GNU Parallel scheduling

安装

如果您的发行版没有打包GNU Parallel,您可以进行个人安装,这不需要root访问。可以在10秒内完成,方法是:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

有关其他安装选项,请参见http://git.savannah.gnu.org/cgit/parallel.git/tree/README

了解更多信息

查看更多示例:http://www.gnu.org/software/parallel/man.html

观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

浏览教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel

在Linux上,使用crontab(5)来调度各种shell脚本。它们可以并行运行。你知道吗

你也可以研究GNU parallel,但我猜你不需要它。你知道吗

最后,shell脚本可以使用atbatch调度另一个脚本。例如,decode.sh可能以batch -f sort.shat -f sort.sh now + 10 minutes结尾

您可以使用一些更强大的脚本语言,例如Python、Guile、Perl等等。。。。你知道吗

顺便说一句,一定要测试每个脚本(甚至其中的部分)是否成功。使用logger(1)发出日志消息(可能在持续半小时以上的每个步骤或命令之后,以及在每个脚本的开始和结束时)。每天检查日志!你知道吗

最后,我不明白为什么一次只能运行一个数据库脚本。大多数真正的DBMS(PostGreSQL、MonGoDB、MariaDB等…)——但不是sqlite——可以运行(或配置为运行)多个同时访问同一个数据库(当然也可以是不同的数据库)的数据库客户机。阅读有关ACID属性的更多信息。你知道吗

在一些外部USB硬盘上这样做是错误的,因为这样的硬件可靠性有限(而且通常速度很慢)。你应该考虑有一些服务器(也许一个好的桌面可能有这样的角色)。您可能需要一个UPS来避免电源故障。你知道吗

如果这种复杂的处理和处理过的数据对您有一定的价值,您应该升级硬件(得到一台服务器机器,可能带有UPS和ECC RAM,如果数据合适,还有SSD)和软件(使用真正的DBMS,注意故障)。估计故障和/或数据丢失的成本(记住要考虑您的时间)。或许租用一些云计算或存储设备会很有趣(或者简单地说是一个VPS托管的带有备份的Linux系统,你每个月花几十美元或欧元就能买到一个:kimsufiovhrackspaceaws。。。你知道吗

您可以有两个脚本,其中一个具有for循环,并解码、排序和创建一个由另一个脚本用作标志的文件。 另一个脚本将在while循环中检查这些文件,并将它们放入数据库中。 脚本1

function decodeAndSort{
      decode.sh $1
      sort.sh $1
      touch ./tmpDir/$1
}
for month in months
do
    decodeAndSort $month &  # the ampersand is to run in the background
done

脚本2

 array=bla #with names of files
 while [[ $count -lt 12 ]]
 do
    if [[ -e ./tmpDir/${array[$count]} ]] #test file exists
          saveintodb.sh ${array[$count]}
          rm ./tmpDir/${array[$count]}    # clear the flag
          (( count++ ))
    else
        sleep 1 # adjust this as necesary
    fi
 done

相关问题 更多 >