Created
July 1, 2021 20:34
Revisions
-
numbnet created this gist
Jul 1, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 < str2</code>Возвращает истину, если <code>str1</code>меньше, чем <code>str2</code>.<br> <code>str1 > 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> 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> Вот одна особенность сравнения строк, о которой стоит упомянуть. А именно, операторы «>» и «<» необходимо экранировать с помощью обратной косой черты, иначе скрипт будет работать неправильно, хотя сообщений об ошибках и не появится. Скрипт интерпретирует знак «>» как команду перенаправления вывода.<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> \> <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> \> <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> Ещё одна особенность операторов «>» и «<» заключается в том, как они работают с символами в верхнем и нижнем регистрах. Для того, чтобы понять эту особенность, подготовим текстовый файл с таким содержимым:<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> \> <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 & options</a> — этот материал посвящён параметрам командной строки и ключам, которые можно передавать скриптам, работе с данными, которые вводит пользователь, и которые можно читать из файлов.<br> <br> </li> <li> <a href="https://likegeeks.com/shell-scripting-awesome-guide-part4/">Bash Scripting Part 4, Input & Output</a> — здесь речь идёт о дескрипторах файлов и о работе с ними, о потоках ввода, вывода, ошибок, о перенаправлении вывода.<br> <br> </li> <li> <a href="https://likegeeks.com/linux-bash-scripting-awesome-guide-part5/">Bash Scripting Part 5, Sighals & 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/&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&order=relevance&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&order=relevance&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&order=relevance&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&order=relevance&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>