Я хотел бы знать, и как bash-скрипт может выполнять задачи, которые необходимо применять одна за другой.

Вот пример, я хотел бы установить на моем CentOS VPS следующие программы.

$ yum update
$ yum install libvpx-devel
$ sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
$ yum install nginx
$ wget https //dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - Chrome_stable
$ mkdir foo
$ mv Chrome_stable foo

Вы понимаете, у меня есть тонны команд, которые я должен делать еженедельно. Итак, мои вопросы таковы, что некоторые установки могут потерпеть неудачу, а другим нужно дождаться завершения одной установки, чтобы продолжить следующую.

Итак, есть ли в любом случае команду bash подождать, пока завершится одна установка / загрузка, прежде чем она перейдет к следующей команде, а также проверить, была ли успешной предыдущая установка перед ее перемещением.

1 ответ1

4

Вам не нужно указывать bash ждать, если выполняемые вами процессы выполняются на переднем плане (что делает все, что вы показываете выше) - он заблокирует ожидание их выхода.

После выхода bash может проверить код возврата и вести себя по-разному в зависимости от этого. Код возврата последнего подпроцесса хранится в $? переменная:

#!/bin/bash

yum update

if [ $? -ne 0 ]; then
    echo "Sorry, yum update had non-zero exit code, why don't we stop here?"
    exit 1
fi

yum install libvpx-devel
...

Обратите внимание, что соглашение Unix состоит в том, что код возврата 0 означает, что процесс завершился успешно, а код возврата чего-либо еще означает, что возникли проблемы. Проблемы могут быть простыми (например, grep не удалось найти искомую строку) или более сложными.

Также обратите внимание, что вы можете использовать && и || операторы для использования кода возврата в одну строку:

yum update && echo "yum succeeded"

yum update || echo "yum failed"

Ответ на вопросы @Contax в комментарии:

Связь между "yum update" и «$?"означает, что каждая запущенная программа имеет код завершения, который возвращается в операционную систему. Как правило, по умолчанию будет 0 (успех), если программа не указывает, но может быть указана в программе (например, "выход 1", показанный в приведенном выше сценарии, устанавливает код выхода этого сценария на 1. В C "return (-1)" в функции main () приведет к тому, что программа будет иметь код завершения -1.) Bash автоматически читает этот код завершения и заполняет его в $? для вашего использования. Просто думайте об этом как о части сантехники - она за стенами, и она заставляет все работать.

Если вам нужно выполнить много задач, да, это утомительно. Вот почему 95% сценариев оболочки там не выполняют никакой проверки ошибок и взрываются впечатляющими модами, когда что-то идет не так :) Вам нужно создать if [ $? -ne 0 ]; then пункт для каждой задачи. Если бы вы были действительно предприимчивы, вы могли бы найти способ обернуть свои исполнения в цикл и повторно использовать код, но это, вероятно, будет больше проблем, чем оно того стоит.

|| Сокращение полезно для компромисса между простотой кода и проверкой ошибок. Как вы заметили, написание предложения if для всего - это PITA, но yum update || exit 1 приведет к тому, что ваш скрипт быстро и незаметно перейдет в состояние сбоя этого процесса. Менее дружелюбно, чем тратить время на распечатку информации и очистку, но лучше, чем продолжать выполнять команды, которые обречены на неудачу из-за неудачного предыдущего шага.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .