О простоте
«Простой» и «короткий» - это не одно и то же.echo $foo
короче echo "$foo"
, но на самом деле делает гораздо больше: разбивает значение foo
на символы в IFS
, оценивает каждый результат этого разделения как выражение glob и затем объединяет их.
Аналогично, упрощение вашего кода - например, ограничение количества шагов в процессе, через который он проходит - совсем не то же самое, что сделать его на короче.
Увеличение одного куска, оставление других без изменений
if IFS=. read -r major rest <version.txt || [ -n "$major" ]; then
echo "$((major + 1)).$rest" >"version.txt.$$" && mv "version.txt.$$" version.txt
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi
Увеличение основного варианта, отбрасывание других
if IFS=. read -r major rest <version.txt || [ -n "$major" ]; then
echo "$((major + 1))" >"version.txt.$$" && mv "version.txt.$$" "version.txt"
else
echo "ERROR: Unable to read version number from version.txt" >&2
exit 1
fi
Обоснование
Оба из перечисленных выше являются POSIX-совместимыми и избегают использования каких-либо возможностей, не встроенных в оболочку.
IFS=. read -r first second third <input
читает первую строку ввода и разбивает еена .
s в переменные оболочки first
, second
и third
;в частности, столбец third
в этом примере включает в себя все после первых двух, поэтому, если у вас есть a.b.c.d.e.f
, вы получите first=a; second=b; third=d.e.f
- отсюда и название rest
, чтобы прояснить это.См. BashFAQ # 1 для подробного объяснения. $(( ... ))
создает арифметический контекст во всех POSIX-совместимых оболочках.Это полезно только для целочисленной математики, но, так как мы разбиваем части на read
, нам нужна только целочисленная математика.См. http://wiki.bash -hackers.org / syntax / arith_expr - Запись в
version.txt.$$
и переименование, если эта запись успешна, предотвращает оставление version.txt
пустым или поврежденным, если произошел сбойместо между открытым и письмом.(Версия, которая беспокоилась о атаках по символическим ссылкам, использовала бы mktemp
вместо того, чтобы полагаться на $$
для генерации уникального имени временного файла). - Переход к записи только в случае успеха
read
или [ -n "$major" ]
имеет значение true, предотвращает сброс кода версией кода на 1
(путем добавления 1 к пустой строке, которая оценивается в арифметическом контексте как 0), если чтение не удалось.