Bash

替代 wait -n (因為伺服器有舊版本的 bash)

  • December 16, 2018

我想解決以下有關送出已並行化到特定節點的作業的問題。


讓我從解釋我的問題的結構開始

我有兩個非常簡單的 Matlab 腳本

1) 主.m

clear
rng default
P=2;
grid=randn(4,3);
jobs=1;

2) 調頻

sgetasknum_grid=grid(jobs*(str2double(getenv('SGE_TASK_ID'))-1)+1: str2double(getenv('SGE_TASK_ID'))*jobs,:); %jobsx3

result=sgetasknum_grid+1; 

filename = sprintf('result.%d.mat', ID);
save(filename, 'result')

exit

我想做的是:

  • 執行 main.m;
  • 然後,執行 fm 4 次,****每次允許並行執行2 個任務
  • 一切都應該在節點A上執行

這是我實施上述步驟的方法

**1)**我保存main.mf.m進入一個名為My_folder

**2)**我如下創建腳本td.sh並將其保存到文件夾中My_folder

#!/bin/bash -l
#$ -S /bin/bash
#$ -l h_vmem=5G
#$ -l tmem=5G
#$ -l h_rt=480:0:0
#$ -cwd
#$ -j y


#$ -N try

date
hostname

J=4 #number tasks

N=2 #number tasks executed in parallel

export SGE_TASK_ID


SGE_TASK_ID=1
n=0
while [ "$SGE_TASK_ID" -le "$J" ]; do
   if [ "$n" -eq "$N" ]; then
       wait -n  # as soon as one task is done, refill it with another
       n=$(( n - 1 ))
   fi

   printf 'Task ID is %d\n' "$SGE_TASK_ID"

   /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit" &

   SGE_TASK_ID=$(( SGE_TASK_ID + 1 ))
   n=$(( n + 1 ))
done

wait

**3)**我進入終端並輸入ssh username@A, 然後cd /.../My_folder, 然後bash td.sh


**問題:**我收到以下錯誤

td.sh: line 26: wait: -n: invalid option
wait: usage: wait [id]

正如在下面的評論中所注意到的,問題是@A 上的 bash 版本是舊的(-n 選項已添加到 4.3 中的 wait 內置)並且系統管理員無法更新它。可能的最新版本是 bash 4.1。

因此,您能建議一種替換方法wait -n嗎?

在 while 循環中根本不使用 wait 怎麼樣?

while [ "$SGE_TASK_ID" -le "$J" ]; do

   # grep count of matlab processes out of list of user processes
   n = $(ps ux | grep -c "matlab")

   ##  if [ "$n" -le "$N" ]; then
   if [ "$n" -eq "$N" ]; then
       # sleep 1 sec if already max processes started
       sleep 1
       ##  wait -n  # as soon as one task is done, refill it with another
       ##  n=$(( n - 1 ))
   else
       # start another process
       printf 'Task ID is %d\n' "$SGE_TASK_ID"

       /share/.../matlab -nodisplay -nodesktop -nojvm -nosplash -r "main; ID=$SGE_TASK_ID; f; exit" &

       SGE_TASK_ID=$(( SGE_TASK_ID + 1 ))

   fi
   ##  n=$(( n + 1 ))
done

grep 的字元串當然可能會有所不同,具體取決於您正在執行的內容(例如,給出f.m一些更特殊的名稱,然後使用 grep。)

你編寫的那個腳本最好用 gnu parallel 來完成,或者用 -j 選項製作。或者,您可以用 python(或其他語言)重新編寫它。

看著

  • parallel: 一個用於 bash 的工具(這 3 個工具中最容易學習,只做一件事)。
  • make: 有點高級,而且有自己的語言。它用於創建文件。例如,使A.b您需要A.a,並且g.f,當您擁有這些時,請執行z;y;z。您還可以添加有關如何製作A.ag.f. 它將計算出什麼取決於什麼,並以正確的順序建構事物。如果可以,它將並行執行(如果被要求)。
  • python: 一種程式語言,它可以做你的腳本想要做的事情,它可以做 matlab 做的事情。

您還必須考慮其中哪些是/可以安裝的。這樣做可以找出:

type parallel
type make
type python

注意:type不是對您的指示,請鍵入。這是您鍵入的命令。它告訴你每個命令的類型(它在哪裡)。

引用自:https://unix.stackexchange.com/questions/486582