Skip to content

Instantly share code, notes, and snippets.

@numbnet
Created July 1, 2021 20:34

Revisions

  1. numbnet created this gist Jul 1, 2021.
    943 changes: 943 additions & 0 deletions manLinuxSettings.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,943 @@
    <div class="tm-page-article__body">
    <article class="tm-page-article__content tm-page-article__content_inner">
    <div class="tm-page-article__head-wrapper">
    <!---->
    <div class="tm-article-snippet tm-page-article__snippet">
    <div class="tm-article-snippet__meta-container">
    <div class="tm-article-snippet__meta">
    <span class="tm-user-info tm-article-snippet__author">
    <a href="/ru/users/ru_vds/" title="ru_vds" class="tm-user-info__userpic">
    <div class="tm-entity-image">
    <img alt="" height="24" loading="lazy" src="//habrastorage.org/r/w32/getpro/habr/avatars/e36/812/d3d/e36812d3de38eb3d479d7a13228717ef.png" width="24" class="tm-entity-image__pic">
    </div>
    </a>
    <span class="tm-user-info__user">
    <a href="/ru/users/ru_vds/" class="tm-user-info__username">ru_vds</a>
    </span>
    </span>

    </div>
    <!---->
    </div>
    <h1 lang="ru" class="tm-article-snippet__title tm-article-snippet__title_h1">
    <span>Bash-скрипты: начало</span>
    </h1>
    <div class="tm-article-snippet__hubs">

    <span class="tm-article-snippet__hubs-item">
    <a href="/ru/hub/linux/" class="tm-article-snippet__hubs-item-link">
    <span>Настройка Linux</span>
    </a>
    </span>
    <span class="tm-article-snippet__hubs-item">
    <a href="/ru/hub/s_admin/" class="tm-article-snippet__hubs-item-link">
    <span>Серверное администрирование</span>
    </a>
    </span>
    </div>
    <div class="tm-article-snippet__labels">
    <div class="tm-article-snippet__label">
    <span>
    Перевод
    </span>
    </div>
    </div>
    <!---->
    <!---->
    </div>
    </div>
    <div class="tm-page-article__origin">
    <a href="https://likegeeks.com/bash-script-easy-guide/" target="_blank" class="tm-page-article__origin-link">
    Автор оригинала:
    <span class="tm-page-article__origin-value">
    Администратор likegeeks.com
    </span>
    </a>
    </div>
    <div lang="ru" class="tm-article-body">
    <div id="post-content-body" class="article-formatted-body article-formatted-body_version-1">
    <div xmlns="http://www.w3.org/1999/xhtml">
    <blockquote>
    <a href="https://habrahabr.ru/company/ruvds/blog/325522/">Bash-скрипты: начало</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/325928/">Bash-скрипты, часть 2: циклы</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/326328/">Bash-скрипты, часть 3: параметры и ключи командной строки</a> <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/326594/">Bash-скрипты, часть 4: ввод и вывод</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/326826/">Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями</a> <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/327248/">Bash-скрипты, часть 6: функции и разработка библиотек</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/327530/">Bash-скрипты, часть 7: sed и обработка текстов</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/327754/">Bash-скрипты, часть 8: язык обработки данных awk</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/327896/">Bash-скрипты, часть 9: регулярные выражения</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/328346/">Bash-скрипты, часть 10: практические примеры</a>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/328436/">Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит</a>
    </blockquote>
    <br>
    Сегодня поговорим о bash-скриптах. Это — <a href="https://ru.wikipedia.org/wiki/%D0%A1%D1%86%D0%B5%D0%BD%D0%B0%D1%80%D0%B8%D0%B9_%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9_%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8">сценарии командной строки</a>, написанные для оболочки bash. Существуют и другие оболочки, например — zsh, tcsh, ksh, но мы сосредоточимся на bash. Этот материал предназначен для всех желающих, единственное условие — умение работать в <a href="https://likegeeks.com/main-linux-commands-easy-guide/">командной строке</a> Linux.<br>
    <br>
    <a href="https://habrahabr.ru/company/ruvds/blog/325522/">
    <img data-src="https://habrastorage.org/files/803/892/bfe/803892bfe548499aa763df324d40fd01.png" src="https://habrastorage.org/r/w1560/files/803/892/bfe/803892bfe548499aa763df324d40fd01.png">
    </a>
    <br>
    <a name="habracut">
    </a>
    <br>
    Сценарии командной строки — это наборы тех же самых команд, которые можно вводить с клавиатуры, собранные в файлы и объединённые некоей общей целью. При этом результаты работы команд могут представлять либо самостоятельную ценность, либо служить входными данными для других команд. Сценарии — это мощный способ автоматизации часто выполняемых действий.<br>
    <br>
    <a href="https://ruvds.com/ru-rub/#order">
    <img data-src="https://habrastorage.org/files/1ba/550/d25/1ba550d25e8846ce8805de564da6aa63.png" src="https://habrastorage.org/r/w1560/files/1ba/550/d25/1ba550d25e8846ce8805de564da6aa63.png">
    </a>
    <br>
    <br>
    Итак, если говорить о командной строке, она позволяет выполнить несколько команд за один раз, введя их через точку с запятой:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-built_in">pwd</span> ; whoami</code>
    </pre>
    <br>
    На самом деле, если вы опробовали это в своём терминале, ваш первый bash-скрипт, в котором задействованы две команды, уже написан. Работает он так. Сначала команда <code>pwd</code> выводит на экран сведения о текущей рабочей директории, потом команда <code>whoami</code>показывает данные о пользователе, под которым вы вошли в систему.<br>
    <br>
    Используя подобный подход, вы можете совмещать сколько угодно команд в одной строке, ограничение — лишь в максимальном количестве аргументов, которое можно передать программе. Определить это ограничение можно с помощью такой команды:<br>
    <br>
    <pre>
    <code class="hljs nginx">
    <span class="hljs-attribute">getconf</span> ARG_MAX</code>
    </pre>
    <br>
    Командная строка — отличный инструмент, но команды в неё приходится вводить каждый раз, когда в них возникает необходимость. Что если записать набор команд в файл и просто вызывать этот файл для их выполнения? Собственно говоря, тот файл, о котором мы говорим, и называется сценарием командной строки.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Как устроены bash-скрипты</font>
    </h2>
    <br>
    Создайте пустой файл с использованием команды <code>touch</code>. В его первой строке нужно указать, какую именно оболочку мы собираемся использовать. Нас интересует <code>bash</code>, поэтому первая строка файла будет такой:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    </code>
    </pre>
    <br>
    В других строках этого файла символ решётки используется для обозначения комментариев, которые оболочка не обрабатывает. Однако, первая строка — это особый случай, здесь решётка, за которой следует восклицательный знак (эту последовательность называют <a href="https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D0%B1%D0%B0%D0%BD%D0%B3_(Unix)">шебанг</a>) и путь к <code>bash</code>, указывают системе на то, что сценарий создан именно для <code>bash</code>.<br>
    <br>
    Команды оболочки отделяются знаком перевода строки, комментарии выделяют знаком решётки. Вот как это выглядит:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    <span class="hljs-comment"># This is a comment</span>
    <span class="hljs-built_in">pwd</span>
    whoami</code>
    </pre>
    <br>
    Тут, так же, как и в командной строке, можно записывать команды в одной строке, разделяя точкой с запятой. Однако, если писать команды на разных строках, файл легче читать. В любом случае оболочка их обработает.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Установка разрешений для файла сценария</font>
    </h2>
    <br>
    Сохраните файл, дав ему имя <code>myscript</code>, и работа по созданию bash-скрипта почти закончена. Сейчас осталось лишь сделать этот файл исполняемым, иначе, попытавшись его запустить, вы столкнётесь с ошибкой <code>Permission denied</code>.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/29f/743/3ec/29f7433ec002900e7518396a814fe351.png">
    </div>
    <br>
    <i>
    <font color="#999999">Попытка запуска файла сценария с неправильно настроенными разрешениями</font>
    </i>
    <br>
    <br>
    Сделаем файл исполняемым:<br>
    <br>
    <pre>
    <code class="hljs nginx">
    <span class="hljs-attribute">chmod</span> +x ./myscript</code>
    </pre>
    <br>
    Теперь попытаемся его выполнить:<br>
    <br>
    <pre>
    <code class="hljs">./myscript</code>
    </pre>
    <br>
    После настройки разрешений всё работает как надо.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/736/e67/1a5/736e671a5ff9a96e10bbb3c7e8ae537a.png">
    </div>
    <br>
    <i>
    <font color="#999999">Успешный запуск bash-скрипта</font>
    </i>
    <br>
    <br>
    <h2>
    <font color="#3AC1EF">Вывод сообщений</font>
    </h2>
    <br>
    Для вывода текста в консоль Linux применяется команда <code>echo</code>. Воспользуемся знанием этого факта и отредактируем наш скрипт, добавив пояснения к данным, которые выводят уже имеющиеся в нём команды:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    <span class="hljs-comment"># our comment is here</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The current directory is:"</span>
    <span class="hljs-built_in">pwd</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user logged in is:"</span>
    whoami</code>
    </pre>
    <br>
    Вот что получится после запуска обновлённого скрипта.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/4d0/173/e3d/4d0173e3ddcad01d0790b6b98dd91315.png">
    </div>
    <br>
    <i>
    <font color="#999999">Вывод сообщений из скрипта</font>
    </i>
    <br>
    <br>
    Теперь мы можем выводить поясняющие надписи, используя команду <code>echo</code>. Если вы не знаете, как отредактировать файл, пользуясь средствами Linux, или раньше не встречались с командой <code>echo</code>, взгляните на <a href="https://likegeeks.com/basic-linux-commands-part2/">этот</a> материал.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Использование переменных</font>
    </h2>
    <br>
    Переменные позволяют хранить в файле сценария информацию, например — результаты работы команд для использования их другими командами.<br>
    <br>
    Нет ничего плохого в исполнении отдельных команд без хранения результатов их работы, но возможности такого подхода весьма ограничены.<br>
    <br>
    Существуют два типа переменных, которые можно использовать в bash-скриптах:<br>
    <br>
    <ul>
    <li>Переменные среды</li>
    <li>Пользовательские переменные</li>
    </ul>
    <br>
    <h2>
    <font color="#3AC1EF">Переменные среды</font>
    </h2>
    <br>
    Иногда в командах оболочки нужно работать с некими системными данными. Вот, например, как вывести домашнюю директорию текущего пользователя:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    <span class="hljs-comment"># display user home</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"Home for the current user is: <span class="hljs-variable">$HOME</span>"</span>
    </code>
    </pre>
    <br>
    Обратите внимание на то, что мы можем использовать системную переменную <code>$HOME</code> в двойных кавычках, это не помешает системе её распознать. Вот что получится, если выполнить вышеприведённый сценарий.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/da0/6b6/4a4/da06b64a489f6a8e16a3ca345f270f82.png">
    </div>
    <br>
    <i>
    <font color="#999999">Использование переменной среды в сценарии</font>
    </i>
    <br>
    <br>
    А что если надо вывести на экран значок доллара? Попробуем так:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"I have <span class="hljs-variable">$1</span> in my pocket"</span>
    </code>
    </pre>
    <br>
    Система обнаружит знак доллара в строке, ограниченной кавычками, и решит, что мы сослались на переменную. Скрипт попытается вывести на экран значение неопределённой переменной <code>$1</code>. Это не то, что нам нужно. Что делать?<br>
    <br>
    В подобной ситуации поможет использование управляющего символа, обратной косой черты, перед знаком доллара:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"I have \$1 in my pocket"</span>
    </code>
    </pre>
    <br>
    Теперь сценарий выведет именно то, что ожидается.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/771/a8a/710/771a8a7102c7a25f1ecd1e739a00de6e.png">
    </div>
    <br>
    <i>
    <font color="#999999">Использование управляющей последовательности для вывода знака доллара</font>
    </i>
    <br>
    <br>
    <h2>
    <font color="#3AC1EF">Пользовательские переменные</font>
    </h2>
    <br>
    В дополнение к переменным среды, bash-скрипты позволяют задавать и использовать в сценарии собственные переменные. Подобные переменные хранят значение до тех пор, пока не завершится выполнение сценария.<br>
    <br>
    Как и в случае с системными переменными, к пользовательским переменным можно обращаться, используя знак доллара:<br>
    <font color="#FFFFFF">TNW-CUS-FMP — промо-код на 10% скидку на наши услуги, доступен для активации в течение 7 дней</font>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    <span class="hljs-comment"># testing variables</span>
    grade=5
    person=<span class="hljs-string">"Adam"</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$person</span> is a good boy, he is in grade <span class="hljs-variable">$grade</span>"</span>
    </code>
    </pre>
    <br>
    Вот что получится после запуска такого сценария.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/3a7/367/14c/3a736714c8f9db68ef8fce923b3cc5e5.png">
    </div>
    <br>
    <i>
    <font color="#999999">Пользовательские переменные в сценарии</font>
    </i>
    <br>
    <br>
    <h2>
    <font color="#3AC1EF">Подстановка команд</font>
    </h2>
    <br>
    Одна из самых полезных возможностей bash-скриптов — это возможность извлекать информацию из вывода команд и назначать её переменным, что позволяет использовать эту информацию где угодно в файле сценария.<br>
    <br>
    Сделать это можно двумя способами.<br>
    <br>
    <ul>
    <li>С помощью значка обратного апострофа «`»</li>
    <li>С помощью конструкции <code>$()</code>
    </li>
    </ul>
    <br>
    Используя первый подход, проследите за тем, чтобы вместо обратного апострофа не ввести одиночную кавычку. Команду нужно заключить в два таких значка:<br>
    <br>
    <pre>
    <code class="hljs bash">mydir=`<span class="hljs-built_in">pwd</span>`</code>
    </pre>
    <br>
    При втором подходе то же самое записывают так:<br>
    <br>
    <pre>
    <code class="hljs mel">mydir=$(<span class="hljs-keyword">pwd</span>)</code>
    </pre>
    <br>
    А скрипт, в итоге, может выглядеть так:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    mydir=$(<span class="hljs-built_in">pwd</span>)
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$mydir</span>
    </code>
    </pre>
    <br>
    В ходе его работы вывод команды <code>pwd</code>будет сохранён в переменной <code>mydir</code>, содержимое которой, с помощью команды <code>echo</code>, попадёт в консоль.<br>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/acc/127/fa3/acc127fa3826130cb82854c74d6fd5f4.png">
    </div>
    <br>
    <i>
    <font color="#999999">Скрипт, сохраняющий результаты работы команды в переменной</font>
    </i>
    <br>
    <br>
    <h2>
    <font color="#3AC1EF">Математические операции</font>
    </h2>
    <br>
    Для выполнения математических операций в файле скрипта можно использовать конструкцию вида <code>$((a+b))</code>:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    var1=$(( 5 + 5 ))
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$var1</span>
    var2=$(( <span class="hljs-variable">$var1</span> * 2 ))
    <span class="hljs-built_in">echo</span> <span class="hljs-variable">$var2</span>
    </code>
    </pre>
    <br>
    <div style="text-align:center;">
    <img src="/img/image-loader.svg" data-src="https://habrastorage.org/getpro/habr/post_images/a3c/9b0/3dc/a3c9b03dcc99367ba2e80f3695282154.png">
    </div>
    <br>
    <i>
    <font color="#999999">Математические операции в сценарии</font>
    </i>
    <br>
    <br>
    <h2>
    <font color="#3AC1EF">Управляющая конструкция if-then</font>
    </h2>
    <br>
    В некоторых сценариях требуется управлять потоком исполнения команд. Например, если некое значение больше пяти, нужно выполнить одно действие, в противном случае — другое. Подобное применимо в очень многих ситуациях, и здесь нам поможет управляющая конструкция <code>if-then</code>. В наиболее простом виде она выглядит так:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-keyword">if</span> команда
    <span class="hljs-keyword">then</span>
    команды
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    А вот рабочий пример:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    <span class="hljs-keyword">if</span> <span class="hljs-built_in">pwd</span>
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"It works"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    В данном случае, если выполнение команды <code>pwd</code>завершится успешно, в консоль будет выведен текст «it works».<br>
    <br>
    Воспользуемся имеющимися у нас знаниями и напишем более сложный сценарий. Скажем, надо найти некоего пользователя в <code>/etc/passwd</code>, и если найти его удалось, сообщить о том, что он существует.<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    user=likegeeks
    <span class="hljs-keyword">if</span> grep <span class="hljs-variable">$user</span> /etc/passwd
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user <span class="hljs-variable">$user</span> Exists"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Вот что получается после запуска этого скрипта.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/395/e17/65e/395e1765efb8d9b3fe1726240357dcc4.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/395/e17/65e/395e1765efb8d9b3fe1726240357dcc4.png">
    </div>
    <br>
    <i>
    <font color="#999999">Поиск пользователя</font>
    </i>
    <br>
    <br>
    Здесь мы воспользовались командой <code>grep</code>для поиска пользователя в файле <code>/etc/passwd</code>. Если команда <code>grep</code>вам незнакома, её описание можно найти <a href="https://likegeeks.com/main-linux-commands-easy-guide/">здесь</a>.<br>
    <br>
    В этом примере, если пользователь найден, скрипт выведет соответствующее сообщение. А если найти пользователя не удалось? В данном случае скрипт просто завершит выполнение, ничего нам не сообщив. Хотелось бы, чтобы он сказал нам и об этом, поэтому усовершенствуем код.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Управляющая конструкция if-then-else</font>
    </h2>
    <br>
    Для того, чтобы программа смогла сообщить и о результатах успешного поиска, и о неудаче, воспользуемся конструкцией <code>if-then-else</code>. Вот как она устроена:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-keyword">if</span> команда
    <span class="hljs-keyword">then</span>
    команды
    <span class="hljs-keyword">else</span>
    команды
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Если первая команда возвратит ноль, что означает её успешное выполнение, условие окажется истинным и выполнение не пойдёт по ветке <code>else</code>. В противном случае, если будет возвращено что-то, отличающееся от нуля, что будет означать неудачу, или ложный результат, будут выполнены команды, расположенные после <code>else</code>.<br>
    <br>
    Напишем такой скрипт:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    user=anotherUser
    <span class="hljs-keyword">if</span> grep <span class="hljs-variable">$user</span> /etc/passwd
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user <span class="hljs-variable">$user</span> Exists"</span>
    <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user <span class="hljs-variable">$user</span> doesn’t exist"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Его исполнение пошло по ветке <code>else</code>.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/9db/c75/b3d/9dbc75b3dba2778a9aa9ff6b77677328.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/9db/c75/b3d/9dbc75b3dba2778a9aa9ff6b77677328.png">
    </div>
    <br>
    <i>
    <font color="#999999">Запуск скрипта с конструкцией if-then-else</font>
    </i>
    <br>
    <br>
    Ну что же, продолжаем двигаться дальше и зададимся вопросом о более сложных условиях. Что если надо проверить не одно условие, а несколько? Например, если нужный пользователь найден, надо вывести одно сообщение, если выполняется ещё какое-то условие — ещё одно сообщение, и так далее. В подобной ситуации нам помогут вложенные условия. Выглядит это так:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-keyword">if</span> команда1
    <span class="hljs-keyword">then</span>
    команды
    <span class="hljs-keyword">elif</span> команда2
    <span class="hljs-keyword">then</span>
    команды
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Если первая команда вернёт ноль, что говорит о её успешном выполнении, выполнятся команды в первом блоке <code>then</code>, иначе, если первое условие окажется ложным, и если вторая команда вернёт ноль, выполнится второй блок кода.<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    user=anotherUser
    <span class="hljs-keyword">if</span> grep <span class="hljs-variable">$user</span> /etc/passwd
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user <span class="hljs-variable">$user</span> Exists"</span>
    <span class="hljs-keyword">elif</span> ls /home
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user doesn’t exist but anyway there is a directory under /home"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    В подобном скрипте можно, например, создавать нового пользователя с помощью команды <code>useradd</code>, если поиск не дал результатов, или делать ещё что-нибудь полезное.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Сравнение чисел</font>
    </h2>
    <br>
    В скриптах можно сравнивать числовые значения. Ниже приведён список соответствующих команд.<br>
    <br>
    <blockquote>
    <code>n1 -eq n2</code>Возвращает истинное значение, если <code>n1</code> равно <code>n2</code>.<br>
    <code>n1 -ge n2</code> Возвращает истинное значение, если <code>n1</code>больше или равно <code>n2</code>.<br>
    <code>n1 -gt n2</code>Возвращает истинное значение, если <code>n1</code> больше <code>n2</code>.<br>
    <code>n1 -le n2</code>Возвращает истинное значение, если <code>n1</code>меньше или равно <code>n2</code>.<br>
    <code>n1 -lt n2</code>Возвращает истинное значение, если n1 меньше <code>n2</code>.<br>
    <code>n1 -ne n2</code>Возвращает истинное значение, если <code>n1</code>не равно <code>n2</code>.</blockquote>
    <br>
    В качестве примера опробуем один из операторов сравнения. Обратите внимание на то, что выражение заключено в квадратные скобки.<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    val1=6
    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$val1</span> -gt 5 ]
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The test value <span class="hljs-variable">$val1</span> is greater than 5"</span>
    <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The test value <span class="hljs-variable">$val1</span> is not greater than 5"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Вот что выведет эта команда.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/bd8/509/59b/bd850959bf5385f0e3a3fa2173fb39a8.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/bd8/509/59b/bd850959bf5385f0e3a3fa2173fb39a8.png">
    </div>
    <br>
    <i>
    <font color="#999999">Сравнение чисел в скриптах</font>
    </i>
    <br>
    <br>
    Значение переменной <code>val1</code>больше чем 5, в итоге выполняется ветвь <code>then</code>оператора сравнения и в консоль выводится соответствующее сообщение.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Сравнение строк</font>
    </h2>
    <br>
    В сценариях можно сравнивать и строковые значения. Операторы сравнения выглядят довольно просто, однако у операций сравнения строк есть определённые особенности, которых мы коснёмся ниже. Вот список операторов.<br>
    <br>
    <blockquote>
    <code>str1 = str2</code> Проверяет строки на равенство, возвращает истину, если строки идентичны.<br>
    s<code>tr1 != str2</code>Возвращает истину, если строки не идентичны.<br>
    <code>str1 &lt; str2</code>Возвращает истину, если <code>str1</code>меньше, чем <code>str2</code>.<br>
    <code>str1 &gt; str2</code> Возвращает истину, если <code>str1</code>больше, чем <code>str2</code>.<br>
    <code>-n str1</code> Возвращает истину, если длина <code>str1</code>больше нуля.<br>
    <code>-z str1</code>Возвращает истину, если длина <code>str1</code>равна нулю.</blockquote>
    <br>
    Вот пример сравнения строк в сценарии:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    user =<span class="hljs-string">"likegeeks"</span>
    <span class="hljs-keyword">if</span> [<span class="hljs-variable">$user</span> = <span class="hljs-variable">$USER</span>]
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The user <span class="hljs-variable">$user</span> &nbsp;is the current logged in user"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    В результате выполнения скрипта получим следующее.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/55c/79a/3f2/55c79a3f28c78c48bcb0560236e09f9c.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/55c/79a/3f2/55c79a3f28c78c48bcb0560236e09f9c.png">
    </div>
    <br>
    <i>
    <font color="#999999">Сравнение строк в скриптах</font>
    </i>
    <br>
    <br>
    Вот одна особенность сравнения строк, о которой стоит упомянуть. А именно, операторы «&gt;» и «&lt;» необходимо экранировать с помощью обратной косой черты, иначе скрипт будет работать неправильно, хотя сообщений об ошибках и не появится. Скрипт интерпретирует знак «&gt;» как команду перенаправления вывода.<br>
    <br>
    Вот как работа с этими операторами выглядит в коде:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    val1=text
    val2=<span class="hljs-string">"another text"</span>
    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$val1</span> \&gt; <span class="hljs-variable">$val2</span> ]
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$val1</span> is greater than <span class="hljs-variable">$val2</span>"</span>
    <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$val1</span> is less than <span class="hljs-variable">$val2</span>"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Вот результаты работы скрипта.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/4cf/2c4/079/4cf2c4079e42367f9e061cfee547e6b0.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/4cf/2c4/079/4cf2c4079e42367f9e061cfee547e6b0.png">
    </div>
    <br>
    <i>
    <font color="#999999">Сравнение строк, выведенное предупреждение</font>
    </i>
    <br>
    <br>
    Обратите внимание на то, что скрипт, хотя и выполняется, выдаёт предупреждение:<br>
    <br>
    <pre>
    <code class="hljs javascript">./myscript: line <span class="hljs-number">5</span>: [: too many <span class="hljs-built_in">arguments</span>
    </code>
    </pre>
    <br>
    Для того, чтобы избавиться от этого предупреждения, заключим <code>$val2</code> в двойные кавычки:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    val1=text
    val2=<span class="hljs-string">"another text"</span>
    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$val1</span> \&gt; <span class="hljs-string">"<span class="hljs-variable">$val2</span>"</span> ]
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$val1</span> is greater than <span class="hljs-variable">$val2</span>"</span>
    <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$val1</span> is less than <span class="hljs-variable">$val2</span>"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Теперь всё работает как надо.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/8e9/cd9/a8f/8e9cd9a8f743b7789841173671cfe26c.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/8e9/cd9/a8f/8e9cd9a8f743b7789841173671cfe26c.png">
    </div>
    <br>
    <i>
    <font color="#999999">Сравнение строк</font>
    </i>
    <br>
    <br>
    Ещё одна особенность операторов «&gt;» и «&lt;» заключается в том, как они работают с символами в верхнем и нижнем регистрах. Для того, чтобы понять эту особенность, подготовим текстовый файл с таким содержимым:<br>
    <br>
    <pre>
    <code class="hljs nginx">
    <span class="hljs-attribute">Likegeeks</span>
    likegeeks</code>
    </pre>
    <br>
    Сохраним его, дав имя <code>myfile</code>, после чего выполним в терминале такую команду:<br>
    <br>
    <pre>
    <code class="hljs lua">
    <span class="hljs-built_in">sort</span> myfile</code>
    </pre>
    <br>
    Она отсортирует строки из файла так:<br>
    <br>
    <pre>
    <code class="hljs nginx">
    <span class="hljs-attribute">likegeeks</span>
    Likegeeks</code>
    </pre>
    <br>
    Команда <code>sort</code>, по умолчанию, сортирует строки по возрастанию, то есть строчная буква в нашем примере меньше прописной. Теперь подготовим скрипт, который будет сравнивать те же строки:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    val1=Likegeeks
    val2=likegeeks
    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$val1</span> \&gt; <span class="hljs-variable">$val2</span> ]
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$val1</span> is greater than <span class="hljs-variable">$val2</span>"</span>
    <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$val1</span> is less than <span class="hljs-variable">$val2</span>"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Если его запустить, окажется, что всё наоборот — строчная буква теперь больше прописной.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/cca/c66/88c/ccac6688ceb2d01f4e906620c8c0244a.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/cca/c66/88c/ccac6688ceb2d01f4e906620c8c0244a.png">
    </div>
    <br>
    <i>
    <font color="#999999">Команда sort и сравнение строк в файле сценария</font>
    </i>
    <br>
    <br>
    В командах сравнения прописные буквы меньше строчных. Сравнение строк здесь выполняется путём сравнения ASCII-кодов символов, порядок сортировки, таким образом, зависит от кодов символов.<br>
    <br>
    Команда <code>sort</code>, в свою очередь, использует порядок сортировки, заданный в настройках системного языка.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Проверки файлов</font>
    </h2>
    <br>
    Пожалуй, нижеприведённые команды используются в bash-скриптах чаще всего. Они позволяют проверять различные условия, касающиеся файлов. Вот список этих команд.<br>
    <br>
    <blockquote>
    <code>-d file</code>Проверяет, существует ли файл, и является ли он директорией.<br>
    <code>-e file</code>Проверяет, существует ли файл.<br>
    <code>-f file</code> Проверяет, существует ли файл, и является ли он файлом.<br>
    <code>-r file</code>Проверяет, существует ли файл, и доступен ли он для чтения.<br>
    <code>-s file П</code>роверяет, существует ли файл, и не является ли он пустым.<br>
    <code>-w file</code>Проверяет, существует ли файл, и доступен ли он для записи.<br>
    <code>-x file</code>Проверяет, существует ли файл, и является ли он исполняемым.<br>
    <code>file1 -nt file2</code> Проверяет, новее ли <code>file1</code>, чем <code>file2</code>.<br>
    <code>file1 -ot file2</code>Проверяет, старше ли <code>file1</code>, чем <code>file2</code>.<br>
    <code>-O file</code> Проверяет, существует ли файл, и является ли его владельцем текущий пользователь.<br>
    <code>-G file</code>Проверяет, существует ли файл, и соответствует ли его идентификатор группы идентификатору группы текущего пользователя.</blockquote>
    <br>
    Эти команды, как впрочем, и многие другие рассмотренные сегодня, несложно запомнить. Их имена, являясь сокращениями от различных слов, прямо указывают на выполняемые ими проверки.<br>
    <br>
    Опробуем одну из команд на практике:<br>
    <br>
    <pre>
    <code class="hljs bash">
    <span class="hljs-meta">#!/bin/bash</span>
    mydir=/home/likegeeks
    <span class="hljs-keyword">if</span> [ -d <span class="hljs-variable">$mydir</span> ]
    <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The <span class="hljs-variable">$mydir</span> directory exists"</span>
    <span class="hljs-built_in">cd</span> $ mydir
    ls
    <span class="hljs-keyword">else</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"The <span class="hljs-variable">$mydir</span> directory does not exist"</span>
    <span class="hljs-keyword">fi</span>
    </code>
    </pre>
    <br>
    Этот скрипт, для существующей директории, выведет её содержимое.<br>
    <br>
    <div style="text-align:center;">
    <img data-src="https://habrastorage.org/getpro/habr/post_images/ab2/2e2/0e7/ab22e20e730bb0c56cef8da5c8d31dba.png" src="https://habrastorage.org/r/w1560/getpro/habr/post_images/ab2/2e2/0e7/ab22e20e730bb0c56cef8da5c8d31dba.png">
    </div>
    <br>
    <i>
    <font color="#999999">Вывод содержимого директории</font>
    </i>
    <br>
    <br>
    Полагаем, с остальными командами вы сможете поэкспериментировать самостоятельно, все они применяются по тому же принципу.<br>
    <br>
    <h2>
    <font color="#3AC1EF">Итоги</font>
    </h2>
    <br>
    Сегодня мы рассказали о том, как приступить к написанию bash-скриптов и рассмотрели некоторые базовые вещи. На самом деле, тема bash-программирования огромна. Эта статья является переводом первой части большой серии из 11 материалов. Если вы хотите продолжения прямо сейчас — вот список оригиналов этих материалов. Для удобства сюда включён и тот, перевод которого вы только что прочли.<br>
    <br>
    <ol>
    <li>
    <a href="https://likegeeks.com/bash-script-easy-guide/">Bash Script Step By Step</a> — здесь речь идёт о том, как начать создание bash-скриптов, рассмотрено использование переменных, описаны условные конструкции, вычисления, сравнения чисел, строк, выяснение сведений о файлах.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/bash-scripting-step-step-part2/">Bash Scripting Part 2, Bash the awesome</a> — тут раскрываются особенности работы с циклами for и while.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/linux-bash-scripting-awesome-guide-part3/">Bash Scripting Part 3, Parameters &amp; options</a> — этот материал посвящён параметрам командной строки и ключам, которые можно передавать скриптам, работе с данными, которые вводит пользователь, и которые можно читать из файлов.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/shell-scripting-awesome-guide-part4/">Bash Scripting Part 4, Input &amp; Output</a> — здесь речь идёт о дескрипторах файлов и о работе с ними, о потоках ввода, вывода, ошибок, о перенаправлении вывода.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/linux-bash-scripting-awesome-guide-part5/">Bash Scripting Part 5, Sighals &amp; Jobs</a> — этот материал посвящён сигналам Linux, их обработке в скриптах, запуску сценариев по расписанию.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/bash-functions/">Bash Scripting Part 6, Functions</a> — тут можно узнать о создании и использовании функций в скриптах, о разработке библиотек.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/sed-linux/">Bash Scripting Part 7, Using sed</a> — эта статья посвящена работе с потоковым текстовым редактором sed.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/awk-command/">Bash Scripting Part 8, Using awk</a> — данный материал посвящён программированию на языке обработки данных awk.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/regex-tutorial-linux/">Bash Scripting Part 9, Regular Expressions</a> — тут можно почитать об использовании регулярных выражений в bash-скриптах.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/write-shell-script/">Bash Scripting Part 10, Practical Examples</a> — здесь приведены приёмы работы с сообщениями, которые можно отправлять пользователям, а так же методика мониторинга диска.<br>
    <br>
    </li>
    <li>
    <a href="https://likegeeks.com/expect-command/">Bash Scripting Part 11, Expect Command</a> — этот материал посвящён средству Expect, с помощью которого можно автоматизировать взаимодействие с интерактивными утилитами. В частности, здесь идёт речь об expect-скриптах и об их взаимодействии с bash-скриптами и другими программами.<br>
    </li>
    </ol>
    <br>
    Полагаем, одно из ценных свойств этой серии статей заключается в том, что она, начинаясь с самого простого, подходящего для пользователей любого уровня, постепенно ведёт к довольно серьёзным темам, давая шанс всем желающим продвинуться в деле создания сценариев командной строки Linux.<br>
    <br>
    Уважаемые читатели! Просим гуру bash-программирования рассказать о том, как они добрались до вершин мастерства, поделиться секретами, а от тех, кто только что написал свой первый скрипт, ждём впечатлений.<br>
    <br>
    <a href="https://ruvds.com/ru-rub/#order">
    <img data-src="https://habrastorage.org/files/1ba/550/d25/1ba550d25e8846ce8805de564da6aa63.png" src="https://habrastorage.org/r/w1560/files/1ba/550/d25/1ba550d25e8846ce8805de564da6aa63.png">
    </a>
    </div>
    </div>
    <div aria-hidden="true" role="dialog" tabindex="-1" class="pswp">
    <div class="pswp__bg">
    </div>
    <div class="pswp__scroll-wrap">
    <div class="pswp__container">
    <div class="pswp__item">
    </div>
    <div class="pswp__item">
    </div>
    <div class="pswp__item">
    </div>
    </div>
    <div class="pswp__ui pswp__ui--hidden">
    <div class="pswp__top-bar">
    <span class="tm-svg-icon__wrapper pswp__button pswp__button--close">
    <svg height="16" width="16" class="tm-svg-img tm-svg-icon">
    <title>Закрыть</title>
    <use xlink:href="/img/megazord-v24.0db12004.svg#close">
    </use>
    </svg>
    </span>
    <div class="pswp__preloader">
    <div class="pswp__preloader__icn">
    <div class="pswp__preloader__cut">
    <div class="pswp__preloader__donut">
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    <div class="tm-article-poll">
    <div class="tm-notice tm-article-poll__notice tm-notice_positive">
    <!---->
    <div class="tm-notice__inner">
    <!---->
    <div class="tm-notice__content">
    <span>Только зарегистрированные пользователи могут участвовать в опросе. <a href="/kek/v1/auth/habrahabr/?back=/ru/company/ruvds/blog/325522/&amp;hl=ru">Войдите</a>, пожалуйста.</span>
    </div>
    </div>
    </div>
    <div class="tm-article-poll__header">Переводить остальные части цикла статей?</div>
    <div class="tm-article-poll__answers">
    <div class="tm-article-poll__answer">
    <div class="tm-article-poll__answer-data">
    <span class="tm-article-poll__answer-percent tm-article-poll__answer-percent_winning">
    96.38%
    </span>
    <span class="tm-article-poll__answer-label">Да!</span>
    <span class="tm-article-poll__answer-votes">
    1303
    </span>
    </div>
    <div class="tm-article-poll__answer-bar">
    <div class="tm-article-poll__answer-progress tm-article-poll__answer-progress_winning" style="width:96.38%;">
    </div>
    </div>
    </div>
    <div class="tm-article-poll__answer">
    <div class="tm-article-poll__answer-data">
    <span class="tm-article-poll__answer-percent">
    3.62%
    </span>
    <span class="tm-article-poll__answer-label">Нет, не нужно</span>
    <span class="tm-article-poll__answer-votes">
    49
    </span>
    </div>
    <div class="tm-article-poll__answer-bar">
    <div class="tm-article-poll__answer-progress" style="width:3.62%;">
    </div>
    </div>
    </div>
    </div>
    <div class="tm-article-poll__stats">
    Проголосовали 1352 пользователя.

    Воздержались 117 пользователей.
    </div>
    </div>
    </div>
    <div class="tm-article-body__tags">
    <div class="tm-article-body__tags-links">
    <span class="tm-article-body__tags-title">Теги:</span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/search/?target_type=posts&amp;order=relevance&amp;q=%5BLinux%5D" class="tm-article-body__tags-item-link">Linux</a>
    </span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/search/?target_type=posts&amp;order=relevance&amp;q=%5BBash%5D" class="tm-article-body__tags-item-link">Bash</a>
    </span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/search/?target_type=posts&amp;order=relevance&amp;q=%5B%D1%81%D1%86%D0%B5%D0%BD%D0%B0%D1%80%D0%B8%D0%B9%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%BD%D0%BE%D0%B9%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8%5D" class="tm-article-body__tags-item-link">сценарий командной строки</a>
    </span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/search/?target_type=posts&amp;order=relevance&amp;q=%5BBash-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%5D" class="tm-article-body__tags-item-link">Bash-скрипт</a>
    </span>
    </div>
    <div class="tm-article-body__tags-links">
    <span class="tm-article-body__tags-title">Хабы:</span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/company/ruvds/blog/" class="tm-article-body__tags-item-link router-link-active">
    Блог компании RUVDS.com
    </a>
    </span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/hub/linux/" class="tm-article-body__tags-item-link">
    Настройка Linux
    </a>
    </span>
    <span class="tm-article-body__tags-item">
    <a href="/ru/hub/s_admin/" class="tm-article-body__tags-item-link">
    Серверное администрирование
    </a>
    </span>
    </div>
    </div>
    </article>
    </div>