繁体   English   中英

如何在 sh 文件中并行运行 shell 脚本命令?

[英]How to run shell script commands in an sh file in parallel?

我正在尝试备份我的数据库服务器中的表。

我有大约200张桌子。 我有一个 shell 脚本,其中包含用于备份每个表的命令,例如:

备份.sh

psql -u username ..... table1 ... file1;
psql -u username ..... table2 ... file2;
psql -u username ..... table3 ... file3;

我可以运行脚本并在我的机器上创建备份。 但是由于有 200 个表,它会按顺序运行命令并且需要大量时间。 我想并行运行备份命令。 我看过他们建议在每个命令之后使用&&或使用nohup命令或wait命令的文章。

但我不想编辑脚本并包含大约 200 个这样的命令。

有什么方法可以并行运行这些 shell 脚本命令列表? nodejs这样的东西吗? 有可能做到吗? 还是我看错了?

脚本中的示例命令:

psql --host=somehost --port=5490 --username=user --dbname=db -c '\copy dbo.tablename TO "/home/username/Desktop/PostgresFiles/tablename.csv" with DELIMITER ","';

您可以利用 xargs 并行运行命令,并控制并发作业的数量。 运行 200 个备份作业可能会使您的数据库不堪重负,并导致性能不佳。

假设您有 backup.sh,每行有一个备份命令

xargs -P5 -I{} bash -c "{}" < backup.sh

应修改 backup.sh 中的命令以允许引用(尽可能使用单引号,escaping 双引号):

psql --host=somehost --port=5490 --username=user --dbname=db -c '\copy dbo.tablename TO \"/home/username/Desktop/PostgresFiles/tablename.csv\" with DELIMITER \",\"';

其中 -P5 控制并发作业的数量。 这将能够处理没有双引号的命令行。 对于上述脚本,您将"\copy..."更改为'\copy...'

更简单的替代方法是使用助手backup-table.sh ,它将采用两个参数(表、文件),并使用

xargs -P5 -I{} backup-table.sh "{}" < tables.txt

并将所有复杂的引用放入 backup-table.sh

doit() {
  table=$1
  psql --host=somehost --port=5490 --username=user --dbname=db -c '\copy dbo.'$table' TO "/home/username/Desktop/PostgresFiles/'$table'.csv" with DELIMITER ","';
}
export -f doit

sql --listtables -n postgresql://user:pass@host:5490/db | parallel -j0 doit

除了单个命令之外,脚本中是否还有其他逻辑? (例如:和if或 output 的处理?)。

如果它只是一个包含脚本列表的文件,您可以为脚本编写一个包装器(或来自 CLI 的循环)EG:

$ cat help.txt
echo 1
echo 2
echo 3

$ while read -r i;do bash -c "$i" &done < help.txt
[1] 18772
[2] 18773
[3] 18774
1
2
3
[1]   Done                    bash -c "$i"
[2]-  Done                    bash -c "$i"
[3]+  Done                    bash -c "$i"

$ while read -r i;do bash -c "$i" &done < help.txt
[1] 18820
[2] 18821
[3] 18822
2
3
1
[1]   Done                    bash -c "$i"
[2]-  Done                    bash -c "$i"
[3]+  Done                    bash -c "$i"

help.txt的每一行都包含一个命令,我运行一个循环,在其中获取每个命令并在 subshell 中运行它。 (这是一个简单的示例,我只是在每个作业的背景下。您可以使用xargs -pparallel之类的东西变得更复杂,但这是一个起点)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM