Создание и выполнение скриптов Bash в RHEL

Red Hat Enterprise LinuxBeginner
Практиковаться сейчас

Введение

В этой лабораторной работе вы научитесь создавать и выполнять Bash-скрипты для администрирования системы RHEL. Вы начнете с создания простых скриптов, затем расширите их с помощью системных команд и сделаете их исполняемыми. Лабораторная работа переходит к использованию циклов for для автоматизации задач, таких как сбор информации о системе и фильтрация вывода команд с помощью grep и регулярных выражений. Наконец, вы создадите комплексный скрипт информации о системе RHEL, приобретая практические навыки автоматизации административных задач и использования мощных возможностей оболочки.

Создание и выполнение простого скрипта Bash

На этом шаге вы узнаете, как создать базовый Bash-скрипт и выполнить его. Bash-скрипты — это простые текстовые файлы, содержащие последовательность команд, которые может выполнять оболочка Bash. Они являются мощными инструментами для автоматизации повторяющихся задач и объединения нескольких команд в единую исполняемую единицу.

Сначала вы создадите новый каталог для хранения ваших скриптов. Хорошей практикой является организация ваших файлов, а размещение скриптов в выделенном каталоге помогает поддерживать порядок в вашем домашнем каталоге.

  1. Создайте каталог для ваших скриптов.
    Используйте команду mkdir для создания каталога с именем scripts в вашем каталоге ~/project. Здесь вы будете хранить свои Bash-скрипты.

    mkdir ~/project/scripts

    Прямого вывода от этой команды не будет, если она выполнена успешно.

  2. Создайте свой первый файл Bash-скрипта.
    Перейдите в только что созданный каталог scripts и используйте текстовый редактор nano для создания файла с именем firstscript.sh. Расширение .sh является общепринятым соглашением для скриптов оболочки, хотя и не является строго обязательным.

    cd ~/project/scripts
    nano firstscript.sh

    Внутри редактора nano вы увидите пустой экран.

  3. Добавьте содержимое в свой скрипт.
    Каждый Bash-скрипт должен начинаться со строки "shebang", #!/usr/bin/bash. Эта строка сообщает операционной системе, какой интерпретатор использовать для выполнения скрипта (в данном случае, Bash). После shebang вы добавите простую команду echo для вывода сообщения в терминал.

    Введите следующие строки в редактор nano:

    #!/usr/bin/bash
    echo "Hello, LabEx! This is my first Bash script."

    После ввода содержимого сохраните файл, нажав Ctrl+O, затем Enter для подтверждения имени файла и Ctrl+X для выхода из nano.

    Ваш терминал должен вернуться к приглашению командной строки.

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

    bash firstscript.sh

    Вы должны увидеть вывод вашего скрипта:

    Hello, LabEx! This is my first Bash script.

    Это подтверждает, что ваш скрипт был создан правильно и успешно выполнен.

Улучшение скрипта Bash с помощью системных команд и придание ему исполняемости

На этом шаге вы расширите свой Bash-скрипт, добавив больше системных команд, и узнаете, как сделать скрипт непосредственно исполняемым. Сделав скрипт исполняемым, вы сможете запускать его как любую другую команду, не вызывая явно интерпретатор bash.

  1. Перейдите в каталог ваших скриптов.
    Убедитесь, что вы находитесь в каталоге ~/project/scripts, где вы создали firstscript.sh на предыдущем шаге.

    cd ~/project/scripts
  2. Отредактируйте firstscript.sh, чтобы включить больше системных команд.
    Теперь вы добавите в свой скрипт команды, которые отображают информацию о системе, такую как блочные устройства и свободное место в файловой системе. Это демонстрирует, как скрипты могут автоматизировать сбор данных о системе.

    Откройте firstscript.sh с помощью nano:

    nano firstscript.sh

    Измените содержимое файла, чтобы оно соответствовало следующему. Теперь этот скрипт будет:

    • Выводить заголовок для информации о блочных устройствах.
    • Выполнять lsblk для вывода списка блочных устройств.
    • Выводить заголовок для информации о свободном месте в файловой системе.
    • Выполнять df -h для отображения использования дискового пространства в удобочитаемом формате.
    #!/usr/bin/bash
    echo "Hello, LabEx! This is my first Bash script."
    echo "#####################################################"
    echo "LIST BLOCK DEVICES"
    echo "#####################################################"
    lsblk
    echo "#####################################################"
    echo "FILESYSTEM FREE SPACE STATUS"
    echo "#####################################################"
    df -h

    Сохраните файл, нажав Ctrl+O, затем Enter, и Ctrl+X для выхода из nano.

  3. Сделайте скрипт исполняемым.
    Чтобы запустить скрипт напрямую (например, ./firstscript.sh), вам необходимо предоставить ему права на выполнение. Команда chmod используется для изменения разрешений на файлы. +x добавляет разрешение на выполнение для всех пользователей.

    chmod +x firstscript.sh

    Прямого вывода от этой команды не будет, если она выполнена успешно.

  4. Выполните скрипт напрямую.
    Теперь, когда скрипт исполняемый, вы можете запустить его, указав его путь. Поскольку он находится в вашем текущем каталоге, вы используете ./, за которым следует имя скрипта.

    ./firstscript.sh

    Вы должны увидеть вывод, похожий на этот, объединяющий ваше первоначальное сообщение с выводом lsblk и df -h:

    Hello, LabEx! This is my first Bash script.
    #####################################################
    LIST BLOCK DEVICES
    #####################################################
    NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
    loop0         7:0    0 10.2G  1 loop /
    loop1         7:1    0  200M  1 loop /usr/local/bin
    loop2         7:2    0  200M  1 loop /usr/local/go
    loop3         7:3    0  200M  1 loop /usr/local/java
    loop4         7:4    0  200M  1 loop /usr/local/node
    loop5         7:5    0  200M  1 loop /usr/local/python
    #####################################################
    FILESYSTEM FREE SPACE STATUS
    #####################################################
    Filesystem      Size  Used Avail Use% Mounted on
    overlay          10G  4.0G  6.1G  40% /
    tmpfs            64M     0   64M   0% /dev
    tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
    shm              64M     0   64M   0% /dev/shm
    /dev/loop0       10G  4.0G  6.1G  40% /
    tmpfs           7.8G     0  7.8G   0% /proc/asound
    tmpfs           7.8G     0  7.8G   0% /proc/acpi
    tmpfs           7.8G     0  7.8G   0% /proc/scsi
    tmpfs           7.8G     0  7.8G   0% /sys/firmware

    Точный вывод для lsblk и df -h может незначительно отличаться в зависимости от конкретной среды, но структура и наличие вывода команд должны быть похожими.

Использование циклов For для автоматизации получения имени хоста на серверах RHEL

На этом шаге вы узнаете о циклах for в Bash и о том, как использовать их для автоматизации задач на нескольких серверах. Циклы for — это фундаментальные операторы управления потоком, которые позволяют многократно выполнять блок кода для каждого элемента в списке. Это особенно полезно для эффективного управления несколькими системами.

Для этого упражнения мы продемонстрируем концепцию, используя localhost с разными подходами для имитации работы с несколькими серверами.

  1. Получение имени хоста с помощью локальных команд.
    Прежде чем использовать цикл, давайте посмотрим, как вы обычно получаете имя хоста из локальной системы. Мы будем использовать разные методы, чтобы продемонстрировать концепцию.

    hostname
    hostname -f

    Вы должны увидеть вывод, похожий на этот:

    684791f71c0e35fea6cc1243
    684791f71c0e35fea6cc1243

    Это демонстрирует, что вы можете успешно получить информацию об имени хоста, используя разные опции. Обратите внимание, что в этой среде контейнера все опции имени хоста возвращают один и тот же идентификатор контейнера.

  2. Создание цикла for для автоматизации получения имени хоста с разными опциями.
    Теперь давайте используем цикл for для более эффективного выполнения различных команд имени хоста. Цикл for будет перебирать список опций имени хоста, выполняя команду hostname с каждой опцией.

    for OPTION in "" "-f" "-s"; do
      echo "hostname ${OPTION}:"
      hostname ${OPTION}
      echo ""
    done

    Давайте разберем эту команду:

    • for OPTION in "" "-f" "-s";: Эта часть инициализирует цикл. OPTION — это переменная, которая будет принимать значение каждого элемента в списке (пустая строка, -f, -s) во время каждой итерации.
    • do: Отмечает начало команд, которые будут выполняться в цикле.
    • echo "hostname ${OPTION}:";: Это отображает, какая опция используется.
    • hostname ${OPTION};: Это команда, выполняемая в каждой итерации. ${OPTION} разворачивается в текущее значение переменной OPTION.
    • echo "";: Добавляет пустую строку для лучшей читаемости.
    • done: Отмечает конец цикла.

    Вы должны увидеть вывод, похожий на этот:

    hostname :
    684791f71c0e35fea6cc1243
    
    hostname -f:
    684791f71c0e35fea6cc1243
    
    hostname -s:
    684791f71c0e35fea6cc1243

    Это демонстрирует мощь циклов for в автоматизации повторяющихся задач с разными параметрами.

Создание и выполнение Bash скрипта с циклом For для серверов RHEL

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

  1. Перейдите в каталог ваших скриптов.
    Убедитесь, что вы находитесь в каталоге ~/project/scripts.

    cd ~/project/scripts
  2. Создайте новый скрипт для получения имени хоста.
    Вы создадите скрипт с именем get_hostnames.sh, который содержит цикл for для получения информации об имени хоста, используя разные опции.

    Откройте get_hostnames.sh с помощью nano:

    nano get_hostnames.sh

    Добавьте следующее содержимое в файл:

    #!/usr/bin/bash
    ## This script retrieves hostname information using different options.
    
    for OPTION in "" "-f" "-s"; do
      echo "Getting hostname with option: ${OPTION}"
      hostname ${OPTION}
      echo "------------------------"
    done
    
    exit 0

    Сохраните файл, нажав Ctrl+O, затем Enter, и Ctrl+X для выхода из nano.

    Давайте разберем новые элементы:

    • ## This script...: Строки, начинающиеся с #, являются комментариями. Они игнорируются оболочкой, но полезны для документирования вашего скрипта.
    • echo "Getting hostname with option: ${OPTION}": Эта строка предоставляет обратную связь во время выполнения скрипта, указывая, какая опция в данный момент используется.
    • exit 0: Эта команда явно завершает скрипт с кодом состояния 0, который обычно указывает на успех.
  3. Сделайте скрипт исполняемым.
    Как и на предыдущем шаге, вам нужно предоставить вашему новому скрипту права на выполнение.

    chmod +x get_hostnames.sh

    Прямого вывода от этой команды не будет, если она выполнена успешно.

  4. Выполните скрипт из текущего каталога.
    Запустите скрипт, чтобы проверить его функциональность.

    ./get_hostnames.sh

    Вы должны увидеть вывод, похожий на этот:

    Getting hostname with option:
    684791f71c0e35fea6cc1243
    ------------------------
    Getting hostname with option: -f
    684791f71c0e35fea6cc1243
    ------------------------
    Getting hostname with option: -s
    684791f71c0e35fea6cc1243
    ------------------------
  5. Понимание переменной окружения PATH.
    Переменная окружения PATH — это список каталогов, в которых оболочка ищет исполняемые команды. Когда вы вводите команду, например ls или grep, оболочка ищет в каталогах, перечисленных в PATH, чтобы найти соответствующий исполняемый файл.

    Отобразите вашу текущую переменную PATH:

    echo $PATH

    Вы увидите список каталогов, разделенных двоеточиями. Например:

    /home/labex/.local/bin:/home/labex/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

    Обратите внимание, что ~/project/scripts (или /home/labex/project/scripts) обычно не включается в PATH по умолчанию. Вот почему вам пришлось использовать ./get_hostnames.sh для выполнения вашего скрипта.

  6. Добавление каталога ваших скриптов в PATH (Необязательно, для справки в будущем).
    Хотя это не строго обязательно для этого шага лабораторной работы, общепринятой практикой является добавление личного каталога bin или scripts в ваш PATH, чтобы вы могли запускать свои собственные скрипты из любого места. Вы можете сделать это, добавив строку, например export PATH=$PATH:~/project/scripts, в ваш файл ~/.bashrc или ~/.zshrc. Для этой лабораторной работы мы продолжим выполнять скрипты, указывая их путь.

Фильтрация вывода команд с помощью Grep и регулярных выражений в RHEL

На этом шаге вы узнаете, как использовать команду grep с регулярными выражениями для эффективной фильтрации и извлечения конкретной информации из вывода команд и файлов. grep — это мощная утилита для поиска в наборах данных простого текста строк, соответствующих регулярному выражению. Регулярные выражения (regex) — это последовательности символов, определяющие шаблон поиска.

  1. Поиск конкретной информации о пользователях и группах в системных файлах.
    Вы будете использовать grep для поиска информации о пользователе и группе labex из файлов /etc/passwd и /etc/group. Эти файлы хранят информацию об учетных записях пользователей и групп соответственно.

    Сначала давайте найдем запись пользователя labex в /etc/passwd:

    grep "labex" /etc/passwd

    Ожидаемый вывод:

    labex:x:1000:1000::/home/labex:/bin/bash

    Далее найдите запись группы labex в /etc/group:

    grep "labex" /etc/group

    Ожидаемый вывод:

    labex:x:1000:

    Эти команды демонстрируют базовое использование grep для поиска точных совпадений строк.

  2. Фильтрация вывода lscpu с использованием grep и регулярных выражений.
    Команда lscpu отображает информацию об архитектуре процессора. Часто вам нужны только определенные строки из ее обширного вывода. Вы можете использовать grep с регулярным выражением для фильтрации строк, начинающихся с "CPU".

    lscpu | grep '^CPU'

    Давайте разберем эту команду:

    • lscpu: Генерирует информацию о процессоре.
    • |: Это конвейер, который берет стандартный вывод lscpu и передает его в качестве стандартного ввода команде grep.
    • grep '^CPU': Ищет строки, которые начинаются с буквальной строки "CPU". ^ (карет) — это якорь регулярного выражения, который соответствует началу строки.

    Ожидаемый вывод (может незначительно отличаться в зависимости от среды):

    CPU op-mode(s):                     32-bit, 64-bit
    CPU(s):                             4
    CPU family:                         6
  3. Фильтрация файлов конфигурации, игнорируя комментарии и пустые строки.
    Файлы конфигурации часто содержат комментарии (строки, начинающиеся с #) и пустые строки, которые не имеют отношения к фактической конфигурации. Вы можете использовать grep с несколькими шаблонами, чтобы исключить эти строки. Давайте продемонстрируем это с файлом /etc/passwd.

    grep -v '^#' /etc/passwd | head -5

    Давайте разберем эту команду:

    • grep -v '^#' /etc/passwd: Опция -v инвертирует соответствие, то есть выбирает строки, которые не соответствуют шаблону. ^# соответствует строкам, которые начинаются с #. Таким образом, эта часть отфильтровывает строки комментариев.
    • |: Передает вывод первой команды grep следующей команде.
    • head -5: Показывает только первые 5 строк вывода.

    Ожидаемый вывод (показывает записи учетных записей пользователей без комментариев):

    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  4. Поиск конкретных шаблонов в системных файлах.
    Вы можете использовать grep для поиска конкретных шаблонов в различных системных файлах. Давайте поищем записи, связанные с оболочкой, в файле /etc/passwd.

    grep "bash" /etc/passwd

    Ожидаемый вывод (показывает пользователей с оболочкой bash):

    root:x:0:0:root:/root:/bin/bash
    labex:x:1000:1000::/home/labex:/bin/bash

    Эта команда помогает вам идентифицировать пользователей, у которых bash является оболочкой по умолчанию.

Создание скрипта для получения полной информации о системе RHEL

На этом заключительном шаге вы объедините все изученные ранее концепции — написание сценариев Bash, циклы for, ssh для удаленного выполнения и grep с регулярными выражениями для фильтрации — для создания комплексного скрипта, который собирает информацию о системе с нескольких серверов RHEL. Скрипт сохранит собранные данные в отдельные выходные файлы для каждого сервера.

  1. Перейдите в каталог ваших скриптов.
    Убедитесь, что вы находитесь в каталоге ~/project/scripts.

    cd ~/project/scripts
  2. Создайте новый скрипт с именем system_info.sh.
    Этот скрипт будет собирать информацию о системе, используя разные подходы для демонстрации концепций, и перенаправлять вывод в отдельные файлы в вашем каталоге ~/project.

    Откройте system_info.sh с помощью nano:

    nano system_info.sh

    Добавьте следующее содержимое в файл:

    #!/usr/bin/bash
    
    ## Define variables for output directory
    OUT_DIR='/home/labex/project'
    
    ## Loop through different information gathering approaches
    for APPROACH in "basic" "detailed"; do
      OUTPUT_FILE="${OUT_DIR}/output-${APPROACH}.txt"
    
      echo "Gathering ${APPROACH} system information..."
      ## Clear previous output file or create a new one
      > "${OUTPUT_FILE}"
    
      ## Get hostname information
      echo "#### Hostname Information ###" >> "${OUTPUT_FILE}"
      if [ "${APPROACH}" = "basic" ]; then
        hostname >> "${OUTPUT_FILE}"
      else
        hostname -f >> "${OUTPUT_FILE}"
      fi
      echo "" >> "${OUTPUT_FILE}" ## Add a blank line for readability
    
      ## Get CPU information (only lines starting with CPU)
      echo "#### CPU Information ###" >> "${OUTPUT_FILE}"
      lscpu | grep '^CPU' >> "${OUTPUT_FILE}"
      echo "" >> "${OUTPUT_FILE}"
    
      ## Get system users with bash shell
      echo "#### Users with Bash Shell ###" >> "${OUTPUT_FILE}"
      grep "bash" /etc/passwd >> "${OUTPUT_FILE}"
      echo "" >> "${OUTPUT_FILE}"
    
      ## Get system information based on approach
      if [ "${APPROACH}" = "basic" ]; then
        echo "#### Basic System Info ###" >> "${OUTPUT_FILE}"
        uname -r >> "${OUTPUT_FILE}"
      else
        echo "#### Detailed System Info ###" >> "${OUTPUT_FILE}"
        uname -a >> "${OUTPUT_FILE}"
      fi
      echo "" >> "${OUTPUT_FILE}"
    
      echo "Information saved to ${OUTPUT_FILE}"
      echo "-----------------------------------------------------"
    done
    
    echo "Script execution complete."

    Сохраните файл, нажав Ctrl+O, затем Enter, и Ctrl+X для выхода из nano.

    Ключевые элементы этого скрипта:

    • OUT_DIR='/home/labex/project': Переменная используется, чтобы сделать скрипт более гибким и читаемым.
    • OUTPUT_FILE="${OUT_DIR}/output-${APPROACH}.txt": Динамически конструирует имя выходного файла для каждого подхода.
    • > "${OUTPUT_FILE}": Это перенаправляет вывод пустой команды в файл, эффективно очищая его содержимое, если оно существует, или создавая его, если его нет. Это обеспечивает новый файл для каждого запуска.
    • >> "${OUTPUT_FILE}": Это добавляет вывод команды в указанный файл.
    • if [ "${APPROACH}" = "basic" ]; then ... else ... fi: Условные операторы, которые выполняют разные команды в зависимости от используемого подхода.
    • echo "#### Section Header ###": Добавляет четкие заголовки в выходной файл для лучшей организации.
  3. Сделайте скрипт исполняемым.

    chmod +x system_info.sh

    Прямого вывода от этой команды не будет, если она выполнена успешно.

  4. Выполните скрипт system_info.sh.
    Запустите свой комплексный скрипт. Он соберет информацию о системе, используя разные подходы, и сохранит результаты в отдельные файлы.

    ./system_info.sh

    Вы должны увидеть вывод в вашем терминале, указывающий на ход выполнения скрипта:

    Gathering basic system information...
    Information saved to /home/labex/project/output-basic.txt
    -----------------------------------------------------
    Gathering detailed system information...
    Information saved to /home/labex/project/output-detailed.txt
    -----------------------------------------------------
    Script execution complete.
  5. Просмотрите сгенерированные выходные файлы.
    Проверьте содержимое файлов output-basic.txt и output-detailed.txt в вашем каталоге ~/project, чтобы убедиться, что скрипт собрал информацию, как и ожидалось.

    cat ~/project/output-basic.txt
    cat ~/project/output-detailed.txt

    Содержимое каждого файла должно быть примерно таким (фактические значения будут отличаться):

    output-basic.txt:

    #### Hostname Information ###
    684791f71c0e35fea6cc1243
    
    #### CPU Information ###
    CPU op-mode(s):                     32-bit, 64-bit
    CPU(s):                             4
    CPU family:                         6
    
    #### Users with Bash Shell ###
    root:x:0:0:root:/root:/bin/bash
    labex:x:1000:1000::/home/labex:/bin/bash
    
    #### Basic System Info ###
    5.4.0-162-generic

    output-detailed.txt:

    #### Hostname Information ###
    684791f71c0e35fea6cc1243
    
    #### CPU Information ###
    CPU op-mode(s):                     32-bit, 64-bit
    CPU(s):                             4
    CPU family:                         6
    
    #### Users with Bash Shell ###
    root:x:0:0:root:/root:/bin/bash
    labex:x:1000:1000::/home/labex:/bin/bash
    
    #### Detailed System Info ###
    Linux 684791f71c0e35fea6cc1243 5.4.0-162-generic #179-Ubuntu SMP Mon Aug 14 08:51:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

    Этот заключительный скрипт демонстрирует, как вы можете объединить различные функции Bash и команды Linux для создания мощных инструментов автоматизации для задач системного администрирования.

Резюме

В этой лабораторной работе вы изучили основные шаги создания и выполнения сценариев Bash для администрирования системы RHEL. Вы начали с настройки выделенного каталога для скриптов, а затем создали простой скрипт Bash, понимая важность строки shebang и используя команду echo. Вы изучили различные методы выполнения скриптов, включая непосредственное использование интерпретатора bash и путем предоставления им прав на исполнение.

Кроме того, вы улучшили свои навыки написания сценариев, включив системные команды и автоматизируя задачи с помощью циклов for для сбора информации о системе с использованием различных подходов. Вы также узнали, как эффективно фильтровать вывод команд с помощью grep и регулярных выражений, что является важным навыком для анализа системной информации. Наконец, вы применили эти концепции для создания комплексного скрипта информации о системе RHEL, демонстрируя, как объединить различные команды и конструкции написания сценариев для сбора и представления ценных системных данных.