Каков наиболее краткий способ завершения остальной части конвейера в случае сбоя команды?

Use el interruptor -B:

-B  --ignore-blank-lines  Ignore changes whose lines are all blank.

Para ignorar los espacios en blanco, use los interruptores -by -w:

-b  --ignore-space-change  Ignore changes in the amount of white space.
-w  --ignore-all-space  Ignore all white space.

O simplemente RTM .

EDITAR:

Como-B(y algunos otros interruptores diff)parecen no funcionar (No encontré ninguna información sobre si se informa como error ), debe usar una forma diferente de ignorar líneas en blanco y espacios en blanco.

Sugeriría algo como esto:

[my@pc ~]$ cat file1.txt
2 nodes configured

13 resources configured

[my@pc ~]$ cat file2.txt
2 nodes configured
23 resources configured
[my@pc ~]$ diff <(grep -vE '^\s*$' file1.txt)  <(grep -vE '^\s*$' file2.txt)
2c2
< 13 resources configured
---
> 23 resources configured

2
09.05.2019, 20:16
1 ответ

Я считаю, что это невозможно

Я считаю, что то, о чем вы просите, невозможно напрямую из-за того, как выполняются конвейеры. Оболочка не знает об успехе или неудаче (возвращаемого значения )команды, когда она выполняет «более поздние» команды в конвейере. Он буквально запускает их все одновременно и собирает результаты после.

Есть несколько обходных путей, которые могут помочь.

Обходной путь 1

Выполняйте команды по одной и кэшируйте результаты. Это лучше, потому что более поздние команды абсолютно не будут выполняться, если более ранняя команда не удалась.

Очень короткий пример скрипта:

cache_file=`tempfile`
if command1 > $cache_file ; then
    command2 < $cache_file
fi
rm $cache_file

Обходной путь 2

Выполнить все, но проверить возвращаемые результаты. Это по-прежнему будет запускать все команды, несмотря ни на что, но позволит вам вернуться и найти причину.

Здесь STDERR каждой команды перенаправляется в другой файл с 2>. Затем проверяется PIPESTATUS, чтобы найти код возврата каждой команды.

command1 2> command1_err.log | command2 2> command2_err.log
for result in ${PIPESTATUS[@]} ; do
    if [ $result -ne 0 ] ; then
        echo command failed
    fi
done

Краткий обзор работы конвейеров в оболочке

Чтобы создать конвейер, оболочка выполняет шаги , аналогичные этим:

  1. Каждая труба(|)создается с использованием трубы(). Каждый канал имеет дескриптор чтения и дескриптор записи. Для каждого перенаправления (<,>)он открывает соответствующий файл, получая дескриптор этого файла, используя open().
  2. Оболочка вызывает fork()один раз для каждой команды в канале, чтобы запустить новый процесс.
  3. Каждый дочерний процесс меняет свои дескрипторы STDIN, STDOUT и STDERR на созданные в (1. ).
  4. Предполагая, что команда является внешним двоичным файлом, каждый дочерний процесс затем вызывает exec()для загрузки и запуска двоичного файла.
  5. Затем родительский процесс ожидает завершения дочернего процесса, используя ожидание (), которое также предоставляет возвращаемое значение команды (успех или неудача ).
2
27.01.2020, 22:08

Теги

Похожие вопросы