我已经加了一点我的解释。 从概念上讲,我正在运行一个脚本,它循环处理,调用使用行内容作为input参数的shell。(FYI:a启动执行,b监视执行)
我不能得到它在串行处理第二,只有所有并行:我需要的是以下
cat filename | while readline export param=$line do ./script1a.sh "param" > process.lg && ./script2b.sh > monitor.log && ##wait for processes to finish, running 2 in parallel in script1.sh ./script2a.sh "param" > process2.log && ./script2b.sh > minitor2.log && ##run each of the 2 in serial for script2.sh ./script3a.sh && ./script3b.sh
我尝试join等待,并尝试了一个if语句包含script2a.sh和script2b.sh将串行运行,但无济于事。
if ((++i % 2 ==0)) then wait fi done #only run two lines at a time, then cycle back through loop
我怎么能得到script2.sh并行运行的脚本1并行?
您没有向我们展示从文件中读取的行是如何被使用的。
如果我正确地理解了你的问题,你想要在两行filename
运行script1
,每个script2
都是并行的,然后在两者都完成的情况下连续运行script2
。
while read first; do echo "$first" | ./script1.sh & read second echo "$second" | ./script1.sh & wait script2.sh & # optionally don't background here? script3.sh done <filename &
while
循环包含两个read
语句,因此每个迭代从filename
读取两行,并将每个行提供给一个单独的script1
实例。 然后wait
两者都完成之后再运行script2
。 我将它背景化以便script3
可以在运行时启动,并且可以在整个while
循环中进行后台运行; 但是您可能实际上并不需要默认背景(如果您将其作为常规前台作业编写,那么开发将会容易得多,如果需要的话,在启动时将其背景化)。
我可以根据你实际上希望你的数据流动的情况考虑一些变化。 这里是针对您最近更新的问题的更新。
export param # is this really necessary? while read param; do # First instance ./script1a.sh "$param" > process.lg && ./script2b.sh > monitor.log & # Second instance read param ./script2a.sh "$param" > process2.log && ./script2b.sh > minitor2.log & # Wait for both to finish wait ./script3a.sh && ./script3b.sh done <filename
如果这仍然没有帮助,也许你应该发表第三个问题,你真正解释你想要什么…
锁定!
如果要并行化script1
和script3
,但需要序列化script2
所有调用,请继续使用:
./script1.sh && ./script2.sh && ./script3.sh &
…但是修改script2
以在别的之前抓住一个锁:
#!/bin/bash exec 3>.lock2 flock -x 3 # ... continue with script2's business here.
请注意,您不得删除此处使用的.lock2
文件,这可能会导致多个进程认为它们同时持有锁。
我不是100%确定你的问题是什么意思,但现在我认为你的意思是在你的内部循环中是这样的:
( # run script1 and script2 in parallel script1 & s1pid=$! # start no more than one script2 using GNU Parallel as a mutex sem --fg script2 # when they are both done... wait $s1pid # run script3 script3 ) & # and do that lot in parallel with previous/next loop iteration
@tripleee如果感兴趣的话,我把以下内容放在一起(注意:我改变了这个帖子的一些变量,所以很抱歉,如果有任何地方的不一致…也出口有他们的原因。我认为有一个比出口更好的方式,但现在作品)
cat input.txt | while read first; do export step=${first//\"/} export stepem=EM_${step//,/_} export steptd=TD_${step//,/_} export stepeg=EG_${step//,/_} echo "$step" | $directory"/ws_client.sh" processOptions "$appName" "$step" "$layers" "$stages" "" "$stages" "$stages" FALSE > "$Folder""/""$stepem""_ProcessID.log" && $dir_model"/check_ status.sh" "$Folder" "$stepem" > "$Folder""/""$stepem""_Monitor.log" & read second export step2=${second//\"/} export stepem2=ExecuteModel_${step2//,/_} export steptd2=TransferData_${step2//,/_} export stepeg2=ExecuteGeneology_${step2//,/_} echo "$step2" | $directory"/ws_client.sh" processOptions "$appName" "$step2" "$layers" "$stages" "" "$stages" "$stages" FALSE > "$Folder""/""$stepem2""_ProcessID.log" && $dir _model"/check _status.sh" "$Folder" "$stepem2" > "$Folder""/""$stepem2""_Monitor.log" & wait $directory"/ws_client.sh" processOptions "$appName" "$step" "$layers" "" "" "$stage_final" "" TRUE > "$appLogFolder""/""$steptd""_ProcessID.log" && $dir _model"/check_status.sh" "$Folder" "$steptd" > "$Folder""/""$steptd""_Monitor.log" && $directory"/ws_client.sh" processOptions "$appName" "$step2" "$layers" "" "" "$stage_final" "" TRUE > "$appLogFolder""/""$steptd2""_ProcessID.log" && $dir _model"/check _status.sh" "$Folder" "$steptd2" > "$Folder""/""$steptd2""_Monitor.log" & wait $directory"/ws_client.sh" processPaths "$appName" "$step" "$layers" "$genPath_01" > "$appLogFolder""/""$stepeg""_ProcessID.log" && $dir _model"/check _status.sh" "$Folder" "$stepeg" > "$Folder""/""$stepeg""_Monitor.log" && $directory"/ws_client.sh" processPaths "$appName" "$step2" "$layers" "$genPath_01" > "$appLogFolder""/""$stepeg2""_ProcessID.log" && $dir_model"/check _status.sh" "$Folder" "$stepeg2" > "$Folder""/""$stepeg2""_Monitor.log" & wait if (( ++i % 2 == 0)) then echo "Waiting..." wait fi
我理解你的问题,如:
你有一个模型列表。 这些模型需要运行。 他们运行后,他们必须转移。 简单的解决方案是:
run_model model1 transfer_result model1 run_model model2 transfer_result model2
但为了使这个更快,我们想要平行化部分。 不幸的是, transfer_result
不能并行化。
run_model model1 run_model model2 transfer_result model1 transfer_result model2
model1
和model2
是从文本文件中读取的。 run_model
可以并行运行,并且你需要2个并行运行的程序。 transfer_result
只能一次运行一个,只有在计算结果后才能传输结果。
这可以这样做:
cat models.txt | parallel -j2 'run_model {} && sem --id transfer transfer_model {}'
run_model {} && sem --id transfer transfer_model {}
将运行一个模型,如果成功传输它。 只有在没有其他传输正在运行的情况下才能启动传输。
parallel -j2
将parallel -j2
运行这两个作业。
如果转移比计算模型短,那么您不应该感到惊讶:转移最多只能与下一次转移交换。 如果转移比运行模型花费的时间更长,您可能会发现模型完全无序转移(例如,您可能会在转移作业2之前看到转移作业10)。 但他们最终都会被转移。
你可以看到这个例子的执行顺序:
seq 10 | parallel -uj2 'echo ran model {} && sem --id transfer "sleep .{};echo transferred {}"'
此解决方案比基于wait
的解决方案更好,因为您可以在model1 + 2正在传输时运行model3。