簡體   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