читайте о протоколе 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 появилось новое поле
Вы можете использовать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
или что-то подобное.
Нет прямого способа выйти из цикла в случае возникновения ошибки. Очевидным способом является использование цикла 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