2017-01-17 2 views
2

Учитывая трубопроводную что-то вроде "A | B | C | D | E", я хочу сделать шаг C обусловливающие результат шага B. Что-то вроде этого:Условный шаг в трубопроводе

A | B | if [ $? -ne 0 ]; then C; else cat; fi | D | E 

Но это, похоже, не работает; C никогда не выполняется независимо от результата B. Я ищу лучшее решение.

Я понимаю, что каждый шаг конвейера работает в собственной подоболочке. Поэтому я не могу передать переменную среды обратно в конвейер. Но этот конвейер находится в среде Gnu Parallel, где многие такие конвейеры работают одновременно, и ни один из них не знает какого-либо уникального значения (они просто обрабатывают поток данных и не нуждаются в источнике, родительский скрипт обрабатывает необходимое разделение). Это означает, что использование временного файла также нецелесообразно, так как нет никакого способа сделать имена файлов уникальными. Даже $$, похоже, не дает мне значения, которое одинаково для каждого из шагов.

+0

Вы можете посмотреть 'set -o pipefail', но более реалистично вам просто нужно разбить свои команды, а не использовать один конвейер. –

ответ

4

Вы не можете сделать конвейер условным, потому что команды выполняются параллельно. Если C не были запущены до выхода B, где выход B должен быть подключен к?

Вы должны сохранить вывод B в переменной или временном файле. Например:

out=$(mktemp) 
trap 'rm "$out"' EXIT 
if A | B > "$out"; then 
    C < "$out" 
else 
    cat "$out" 
fi | D | E 
+0

Это похоже на то, что мне нужно. Благодарю. –

+0

Поместите его в функцию 'export -f' it, и он готов для GNU Parallel –

+0

Вместо' mktemp' и 'trap' вы можете использовать $ PARALLEL_TMP. –

1

Существует логическая невозможность в том, как вы заявляете о проблеме.

Предположим, что труба как A | B. Конвейер существует именно потому, что мы хотим, чтобы B начинал читать с A до окончания A. Поэтому, когда начинается B (что было бы при оценке вашего состояния), A еще не знает, не сработает или не удастся, так что B тоже не может знать.

Что вы можете сделать, есть эхо, как его последняя строка, некоторый тип кода состояния. Затем B может читать со стандартного входа, сохранить вход (как временный файл, в переменную), а затем после получения последней строки проверить статус и затем принять меры.

Другой способ сделать это, конечно, иметь свой собственный выход, а затем, когда он заканчивается, иметь условное значение внутри A (и исключить B из конвейера).

+0

А ... Конечно ... Иногда я теряюсь в деталях. Спасибо, что напомнили мне, как работает трубопровод. –