
Я создаю sh-файл для запуска нескольких команд в фоновом режиме.
В некоторой строке этого файла есть команда для обновления zip-файла, например:
zip -d archive.zip file.txt
Этот file.txt может не быть частью archive.zip всегда. Когда это не так, скрипт оболочки прерывается на этой строке:
zip warning: name not matched
Я хочу, чтобы он продолжался до следующих строк с игнорированием отсутствия этого файла. Как мне это сделать?
решение1
Обычно в скрипте оболочки даже строка, которая генерирует ошибку, не остановит выполнение скрипта оболочки. Он просто перейдет к следующей строке.
Заметным исключением является случай, когда вы установили флаг для выхода из оболочки, если какая-либо подкоманда не срабатывает. Иногда это делается путем добавления "set -e" в верхней части скрипта. Если в вашем скрипте есть что-то подобное, он прервется на любой команде в скрипте, возвращая ошибку. В этом случае у вас есть следующие варианты:
Уберите эту опцию. Это может иметь последствия для остальной части вашего сценария, так что не делайте этого по прихоти.
Отключите опцию для раздела скрипта, в котором вы находитесь, затем включите ее снова, чтобы продолжить:
set +e zip -d archive.zip file.txt set -e
Предоставьте выход для неудачной строки, чтобы оболочка считала команду успешной, даже если что-то не удалось. Это можно сделать многими способами, но один из самых простых — использовать оператор OR:
zip -d archive.zip file.txt || true
Это запустит команду zip, но если она не сработает, то запустит команду true, и родительская оболочка получит код возврата от нее (что, конечно, является успехом). Иногда вы можете увидеть это в написанном виде,
||:
что немного быстрее и сложнее, но не магия;:
просто случайно это встроенная в оболочку команда no-op, которая также вернет код ошибки успеха, хотя ничего не делает.Другой способ сделать это — запустить команду в под-оболочке, окружив ее так,
()
чтобы, хотя команда внутри нее может завершиться неудачей, под-оболочка выполнила свою работу, так что родительский скрипт сset -e
set не умрет. Это неоптимально для одной команды, но может быть полезно, если вы хотите запустить целый набор вещей.
С другой стороны, если вы просто хотите подавить сообщение об ошибке, сгенерированное zip, вы можете перенаправить стандартный поток ошибок в /dev/null с помощью ( 2> /dev/null
), чтобы подавить сгенерированные сообщения (или закрыть его с помощью 2>&-
).