Логический all/any в bash

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

awk -v n=10000 '$2 - p >= n { print; p = $2 }' infile

Выход:

1   176506  C
1   188778  C
1   199878  T
1   259923  H
1   346868  J
1   356882  U
1   396293  L
3
17.10.2019, 16:21
5 ответов

Вы можете поместить его в подоболочку с выходом -при ошибке -(-e):

pids=(1025 3425 6474)
(
    set -e
    for pid in "${pids[@]}"; do
        check "$pid"
    done
)
echo $?

В качестве альтернативы вы можете использовать || exit 1вместо set -e:

.
pids=(1025 3425 6474)
(
    for pid in "${pids[@]}"; do
        check "$pid" || exit 1
    done
)
echo $?
4
27.01.2020, 21:08
$  cat pids | parallel -j0 cat && echo OK!
cat: 23: No such file or directory
cat: 45: No such file or directory
cat: 67: No such file or directory
cat: 89: No such file or directory
cat: '': No such file or directory

$  cat pids | parallel -j0 echo && echo OK!
23
45
67
89

OK!

параллель не останавливается при первой ошибке


$   cat pids | while read pid; do cat \"$pid\" || break; done
cat: '"23"': No such file or directory

$   cat pids | while read pid; do echo \"$pid\" || break; done
"23"
"45"
"67"
"89"
""

только bash :break означает перерыв

(Пустая последняя строка и статус возврата реализованы по-разному)


Или ты это имеешь в виду:

cat pids | while read pid; do cat \"$pid\" || break; done

Я признаю, что это не выводит статус, но это вытекает немного из недостающих спецификаций.

Когда я запускаю цикл с echo, он просто заключает в кавычки строки от файла "pids" до EOF. С catИ ||breakостанавливается с ошибкой "нет файла". Без перерыва печатает много ошибок "нет файла". Так это работает? Теперь я просто добавил && echo OK, потому что эта команда действительно возвращает 0 или 1, что соответствует сообщениям об ошибках.

Файл "pids", конечно же, содержит pid. Конвейерная обработка этого файла имитирует ПОТОК строк с одиночными идентификаторами, который продолжается до тех пор, пока не остановится. Неопределенный, как вы говорите.


Извините, но этот вопрос абсолютно не ясен. Неопределенно запущены разные тесты на разных PID.

Если у вас есть только какие-либо тесты, цикл в порядке.

Если вы имеете в виду это наполовину серьезно, то вы должны организовать свой алгоритм. Разбейте логику на более мелкие шаги. Сделайте это проще для вас и процессора.

Ваше если а, то если б, то если с, то если d, то, ну, тогда ВСЕ ОК может быть на грани ОК для одной экстремальной ситуации. Я не думаю, что у вас есть тот, где этот подход полезен.

-2
27.01.2020, 21:08

Возможно:

parallel -j0 check ::: $pid1 $pid2 $pidN &&
  echo all succeeded
parallel -j0  '! check' ::: $pid1 $pid2 $pidN &&
  echo all failed
parallel -j0 --halt soon,success=1 check ::: $pid1 $pid2 $pidN &&
  echo one succeeded
parallel -j0 --halt soon,fail=1 check ::: $pid1 $pid2 $pidN ||
  echo one failed

Проверка будет выполняться параллельно. Замените soonна now, если вы хотите, чтобы запущенные проверки прекращались, как только мы узнаем результат.

Если у вас есть PID как вывод из канала (по одному на строку):

pid_generator | parallel -j0 check && echo all succeeded

parallelдает одно значение checkи запускает как можно больше checkпараллельно(-j0).

Если на сервере не установлено parallel, запустите это на машине, на которой установленоparallel:

parallel --embed > new_script

Отредактируйтеnew_script(последние 5 строк )и скопируйте скрипт на сервер.

2
27.01.2020, 21:08

Простая функция могла бы проверить каждый аргумент; если что-то не удается, возврат из функции с нулевым кодом, отличным от -:

#!/bin/sh

testall() {
  for test
  do
    sh -c "$test" || return 1
  done
}

С некоторыми примерами тестов:

$ testall "echo 1" "echo 2" "false" && echo all OK
1
2
$ testall "echo 1" "echo 2" "echo 3" && echo all OK
1
2
3
all OK
$ testall && echo all OK
all OK
0
27.01.2020, 21:08

Это не должно быть слишком сложно записать в виде цикла:

pids=(1025 3425 6474)
check_all() {
    for pid in "$@"; do
        if ! check "$pid"; then
            return 1
        fi
    done
}
check_all "${pids[@]}"

Подобно цепочке команд, связанных с &&, функция остановится при первом сбое check.

Хотя обратите внимание, что я заменил ваши переменные PID1, PID2и т. д. одним массивом. Bash может перебирать переменные, имена которых начинаются с определенной строки, но массивы просто удобнее. (Если только эти переменные не поступают извне скрипта через среду, где вы не можете передавать правильные массивы.)

Кроме того, я жестко -закодировал команду checkв цикле здесь. Вы можете передавать разные команды для запуска функции, но это связано с проблемами с разделением слов и обработкой кавычек. (См. здесь и здесь .)

8
27.01.2020, 21:08

Теги

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