Можно ли использовать оператор && в цикле шаблонов команд терминала?

читайте о протоколе NMEA, его основные из них, подробности здесь , а здесь .

каждая строка является кадром протокола :$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W *6A

Где:

 RMC          Recommended Minimum sentence C
 123519       Fix taken at 12:35:19 UTC
 A            Status A=active or V=Void.
 4807.038,N   Latitude 48 deg 07.038' N
 01131.000,E  Longitude 11 deg 31.000' E
 022.4        Speed over the ground in knots
 084.4        Track angle in degrees True
 230394       Date - 23rd of March 1994
 003.1,W      Magnetic Variation
 *6A          The checksum data, always begins with *

Обратите внимание, что в версии 2.3 NMEA появилось новое поле

3
23.09.2019, 19:14
2 ответа

Вы можете использоватьset -e:

(set -e;
for what in \
   cache \
   thumbs;
do my template $what:clear; done)

set -eвызывает выход из оболочки, когда команда завершается с кодом выхода, отличным от -нулевым, и сбой не обрабатывается каким-либо другим образом. В приведенном выше примере вся подоболочка завершает работу в случае сбоя my..., а код выхода подоболочки — это код выхода неудачной команды. Это работает в сценариях оболочки и в командной строке.

Другой подход заключается в использовании дизъюнкции:

for what in \
   cache \
   thumbs; do
    my template $what:clear || break
done

Недостатком этого является требование || breakпосле каждой команды и проглатывание кода выхода, указывающего на сбой; цикл forкаждый раз будет выходить с нулевым кодом выхода. Этого можно избежать, сделав breakнеудачным, что приведет к завершению цикла forс кодом выхода 1 (, что все же не так хорошо, как описанный выше подход подоболочки ):

.
for what in \
   cache \
   thumbs; do
    my template $what:clear || break -1 2>/dev/null
done

(break -1вызывает breakвыход с ненулевым -кодом выхода, а 2>/dev/nullотбрасывает свое сообщение об ошибке ).

Насколько я знаю, вы не можете использовать &&для выхода из цикла, как в && doneили что-то подобное.

5
27.01.2020, 21:11

Нет прямого способа выйти из цикла в случае возникновения ошибки. Очевидным способом является использование цикла whileвместо цикла for, но это не так просто сочетается с итерацией по списку. Вам нужно собрать список в переменную, а затем явно удалить элементы из списка, что делает код намного сложнее.

items=(cache thumbs);
while ((${#items[@]})) && my template "${items[0]}":clear; do shift items; done
((${#items[@]} == 0)) # to check if all the items were processed

Более короткий способ записать это, чем использование оператора if:

for what in cache thumbs; do
  my template "$what":clear || break;
done

Использование логических операторов обычно менее читабельно, чем использование if, но somecommand || fallbackдовольно идиоматично.

Обратите внимание, что цикл forвсегда завершается успешно. Нет удобного способа узнать, вышел ли код раньше (, вы можете проверить, является ли $whatпоследним элементом после цикла, но для этого требуется удобный способ узнать, каким был последний элемент, и он не позволяет вам узнать, был ли успешно обработан последний элемент ).

Это плохо масштабируется для нескольких команд. Вместо этого вы можете включить режим errexit с помощью set -e. Это приводит к тому, что оболочка завершает работу, как только команда терпит неудачу (в простых случаях — детали довольно сложны, но здесь достаточно ). Обратите внимание, что завершается вся оболочка (sub ), а не только содержащий цикл, или содержащая функция, или содержащий сценарий.Чтобы закрыть только часть скрипта, поместите эту часть в подоболочку . Обратите внимание, что модификации переменных не сохраняются в подоболочке.

( set -e;
  for what in cache thumbs; do
    my template "$what":clear;
  done
)
# Here $? is 0 if all the mv commands succeeded and nonzero otherwise
3
27.01.2020, 21:11

Теги

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