2015-04-29 3 views
-1

У меня есть .sh, который читается в строках из .txt, которые будут использоваться в качестве параметров для другого сценария оболочки. Каждая из двух строк работает параллельно. В настоящее время: мой текущий код будет читаться во ВСЕХ строках файла (по 2 за один раз) для первого вызова .sh, затем ВСЕ строки для второго вызова .sh, затем ВСЕ для последнего вызова .shПараллельная обработка во время цикла

Проблема: Мне нужно сначала две строки в первом .sh, затем в секундах .sh, затем в последний .sh..THEN цикл назад и процесс со следующими двумя строками HHEEELLLPPP !!! :)

Сейчас:

cat XXXXX.txt | while read line; do 
export step=${line//\"/} 
export step=ExecuteModel_${step//,/_} 
export pov=$line 

$dir"/hpm_ws_client.sh" processCalcScriptOptions "$appName" "$pov" "$layers" "$stages" "" "$stages" "$stages" FALSE > "$dir""/"$step"_ProcessID.log" 
$dir_shell_model"/check_process_status.sh" "$dir" "$step" > "$dir""/""$step""_Monitor.log" & 


$dir"/hpm_ws_client.sh" processCalcScriptOptions "$appName" "$pov" "$layers" "" "" "$stage_final" "" TRUE > "$dir""/""$step""_ProcessID.log" 
$dir"/check_process_status.sh" "$dir" "$step" > "$dir""/""$step""_Monitor.log" & 

$dir"/hpm_ws_client.sh" processGenealogyExecutionPaths "$appName" "$pov" "$layers" "$genPath_01" > "$dir""/""$step""_ProcessID.log" 
$dir"/check_process_status.sh" "$dir" "$step" > "$dir""/""$step""_Monitor.log" & 

if ((++i % 2 == 0)) 
then 
echo "Waiting..." 
wait 
fi 
done 
+3

Очень сложно понять, что вы пытаетесь сделать - можете ли вы упростить его, а также показать файлы (файлы), которые вы пытаетесь прочитать. Мне кажется, что способ сделать это с помощью «GNU Parallel», который может читать 1 или несколько аргументов из одного или нескольких входных файлов и обрабатывать столько за раз, сколько захотите.Вероятно, он удалит все ваши циклы и сделает ваш код в несколько раз меньше - я угадываю около 3-5 строк в целом - и более эффективен и читаем. –

+0

@MarkSetchell, я бы предпочел предположить флаг GNU xargs '-P' задолго до GNU Parallel - гораздо более простая реализация (при использовании с' -0' или '-d $ '\ n'', чтобы избежать связанных с кодированием к совместимости с некоторыми из наихудших бит POSIX), в «явно не ошибках» и «нет очевидных ошибок». –

+0

Тангенциально, что со всеми '' 'экспортом''? При быстром просмотре ни одна из этих переменных не должна экспортироваться, если только требуемые инструменты не требуют их; но, конечно, ничего не нужно экспортировать более одного раза. – tripleee

ответ

0

Ну, это не красиво и, надеюсь, кто-то предложит более изящный способ чтения последовательных пар линий в этих циклах, но одна возможность использует переменную для отслеживания, где вы являются, как

LOCATION=0 
for file in first second last; do 
    LOCATION=$((LOCATION+2)) 
    LINES=$(head -n $LOCATION $file | tail -n 2) 
    # process lines 
+0

@marksetchell благодарит за это, его полезный чтобы понять подходы, которые я мог бы использовать здесь. Я придумал частичное решение, просто используя && между сценариями оболочки и проверкой двух запущенных процессов. Проблема, с которой я сталкиваюсь сейчас, - это то, что вторая работа, которую я запускаю с параметрами (в зависимости от успеха первого), должна выполняться в последовательном порядке. Я думаю, может быть, заявление if? –

+0

Имея числовой индекс, чтобы рассказать вам, сколько строк для чтения * снова * является общим анти-шаблоном. Попробуйте что-то вроде 'во время чтения первого; прочитайте второй; команду что-то «$ first» «$ second»; done tripleee

1

Я не могу видеть, что вы на самом деле пытаетесь сделать, но надеюсь, что один из этих двух синтаксисов помогут - либо чтение две строки в то время, или загрузки параметров в массив в повторном использовании их.

Так что, если ваш file.txt выглядит следующим образом:

line 1 
line 2 
line 3 
line 4 
line 5 
line 6 

Пример 1 - с двумя читает

#!/bin/bash 
while read a && read b; do 
    echo $a, $b 
done < file.txt 

Выход

line 1, line 2 
line 3, line 4 
line 5, line 6 

Пример 2 - с Баш массива

#!/bin/bash 
declare -a params 
while IFS=$'\n' read -r z; do 
    params+=("${z}") 
done < file.txt 

# Now print the elements out 
for ((i=0;i<${#params[@]};i++)) do 
    echo ${params[$i]} 
done 

Выход

line 1 
line 2 
line 3 
line 4 
line 5 
line 6 

Пример 3 - с GNU Parallel

Или, как я предложил в моем комментарии, используйте GNU Parallel как это

parallel -k -L2 echo {1} {2} < file.txt 

Выход

line 1 line 2 
line 3 line 4 
line 5 line 6 

-k, где означает "сохранить вывод в порядке" и -L2 означает "берут 2 строки за один раз от file.txt".

Это имеет то преимущество, что если вы хотите одновременно запускать 8 сценариев одновременно, вы указываете -j 8 на parallel, и работа выполнена.