Bash For Loop
21 Июня 2020
|
Терминал
Циклы являются одним из фундаментальных понятий языков программирования. Циклы удобны, когда вы хотите запускать серию команд снова и снова, пока не будет достигнуто определенное условие.
В языках сценариев, таких как Bash, циклы полезны для автоматизации повторяющихся задач.
В скриптах Bash есть три базовых конструкции , и .
Стандартный цикл
Цикл перебирает список элементов и выполняет данный набор команд.
Цикл Bash принимает следующую форму:
Список может быть последовательностью строк, разделенных пробелами, диапазоном чисел, выводом команды, массивом и так далее.
Зацикливание строк
В приведенном ниже примере цикл будет перебирать каждый элемент в списке строк, и переменная будет установлена на текущий элемент:
Цикл выдаст следующий вывод:
Цикл по диапазону номеров
Вы можете использовать выражение последовательности, чтобы указать диапазон чисел или символов, задав начальную и конечную точку диапазона. Выражение последовательности принимает следующую форму:
Вот пример цикла, который перебирает все числа от 0 до 3:
Начиная с Bash 4, также можно указать приращение при использовании диапазонов. Выражение принимает следующую форму:
Вот пример, показывающий, как увеличить на 5:
Цикл на элементах массива
Вы также можете использовать цикл для перебора массива элементов.
В приведенном ниже примере мы определяем массив с именем и выполняем итерацию по каждому элементу массива.
Синтаксис цикла в стиле C
Синтаксис цикла в стиле C принимает следующую форму:
Часть выполняется только один раз , когда начинается цикл. Затем часть оценивается. Если оно ложно, цикл прерывается. Если значение равно true, команды внутри тела цикла выполняются, а часть обновляется.
В следующем примере кода цикл начинается с инициализации и перед каждой итерацией проверяет, является ли . Если true, он печатает текущее значение и на 1 ( ), иначе цикл завершается.
Цикл повторяется 1001 раз и выдает следующий результат:
и заявления
и могут быть использованы для управления для выполнения цикла.
Оператор завершает текущий цикл и передает управление программой к инструкции, следующей за прекращено заявление. Обычно используется для завершения цикла при выполнении определенного условия.
В следующем примере мы используем инструкцию, чтобы завершить выполнение цикла, когда текущий повторяющийся элемент равен «Lithium».
Оператор завершает текущую итерацию цикла и передает управление программой к следующей итерации цикла.
В следующем примере мы перебираем диапазон чисел. Когда текущий элемент с итерацией равен ‘2’, оператор заставит выполнение вернуться к началу цикла и продолжить следующую итерацию:
Примеры цикла for Bash
Переименование файлов с пробелами в имени файла
В следующем примере показано, как переименовать все файлы в текущем каталоге с пробелом в его именах, заменив пробел подчеркиванием:
Давайте разберем код построчно:
- Первая строка создает цикл и перебирает список всех файлов с пробелом в имени. Выражение создает список.
- Вторая строка применяется к каждому элементу списка и перемещает файл в новый, заменяя пробел подчеркиванием ( ). Часть использует расширение параметра оболочки для замены шаблона в параметре на строку.
- указывает на конец сегмента цикла.
Изменение расширения файла
В следующем примере показано, как использовать цикл Bash для переименования всех файлов, заканчивающихся на .jpeg в текущем каталоге, заменив расширение файла с .jpeg на .jpg.
Давайте проанализируем код построчно:
- Первая строка создает цикл и просматривает список всех файлов, заканчивающихся на «.jpeg».
- Вторая строка применяется к каждому элементу списка и перемещает файл в новый, заменяя «.jpeg» на «.jpg». удалить часть «.jpeg» из имени файла, используя расширение параметра оболочки
- указывает на конец сегмента цикла.
Цикл Bash используется для многократного выполнения заданного набора команд в течение фиксированного числа раз.
Оператор цикла со счетчиком (for) в Pascal abc.net
- Синтаксис цикла for:
выглядит так: for := do выглядит так: выглядит так: to | downto
переменная-счетчик должна иметь порядковый тип (целый, символьный или перечислимый);
переменная-счетчик цикла for не должна меняться внутри цикла for;
Новое в Pascal abc.net:
описание переменной цикла в его заголовке:
for var i integer = 1 to 5 do <оператор> |
автоопределение типа при описании:
for var i = 1 to 5 do <оператор> |
Значение переменной цикла после завершения цикла будет не определено (локальная).
Пример: Даны целые числа A и B (A ). Вывести в порядке возрастания все целые числа, расположенные между A и B (не включая сами числа A и B), а также количество N этих чисел.
Решение:
begin var (a, b) = readinteger2('Введите два целых числа. Первое должно быть меньше второго:'); assert(a < b); // проверка действительно ли a < b for var i = (a + 1) to (b - 1) do println(i); println(b - a - 1); // количество чисел end. |
Задание: Даны два целых числа A и B. Выведите квадраты всех целых чисел, расположенных между A и B, в порядке возрастания чисел и включая сами эти числа.
Задание: Дано вещественное число — цена 1 кг конфет. Вывести стоимость 1.2, 1.4, …, 2 кг конфет.
Пример: Используя один цикл, вычислить значение суммы, заданной следующей формулой (N > 0):
Решение:
Begin var n=readInteger('N = '); assert(n>); var x=readReal('X = '); var sum=0.0; var f=-1.0; var num=1.0; for var i=1 to n do begin num*=x; sum+=(x+f*num)i; f*=-1.0; end; writeln(sum) End. |
Задание: Используя один цикл, вычислить значение суммы, заданной следующей формулой (N > 0):
Не забудьте, что использование функции возведения в степень запрещено.
Как работать с последовательностью чисел?
Например, если необходимо как-то обработать последовательность чисел с заданным количеством элементов, то примерный код может быть таким:
begin // предварительные действия N = ReadInteger; // или Read(N); for var i = 1 to N do begin // ввод очередного элемента var b = ReadInteger; //или ReadReal, или Read(b); // обработка очередного элемента end; // вывод результатов обработки end. |
Задание: Дано целое число (N ≥ 0) и последовательность из N целых чисел. Найти количество отрицательных чисел в этой последовательности.
Команда each_with_Index – цикл через массив с использованием индекса и значения
Хотя отлично, что каждая команда проходит через элементы, а each_index – через индексы.
Что делать, если вы хотите прокручивать оба, индексы и элементы.
Именно поэтому у нас есть команда each_with_index, как показано в следующем примере.
В этом примере each_with_index будет проходить через каждый отдельный элемент и хранить как значение элемента, так и значение индекса во время выполнения цикла в двух разных переменных.
# cat iterator3.rb title = title.each_with_index do |element,i| puts "#{i}. #{element}" end
В приведенном выше:
- title – это массив, содержащий три строковых элемента.
- title.each_with_index – Это указывает на то, что нам надо как значения массива, так и индексы
- do … end – это тело цикла (как и другие примеры команд цикла)
- |element, i| – Здесь мы указываем две переменные. Первая переменная (element) будет содержать значение отдельного элемента массива. Вторая переменная i будет содержать значение индексов этого конкретного элемента.
- puts “# {i}. # {element} “- В теле цикла мы используем как отдельный элемент, так и соответствующее значение индекса.
Как видно из следующего вывода, этот пример печатает как индекс, так и значение отдельного элемента массива.
# ruby iterator3.rb 0. The 1. AndreyEx 2. Blogs
Цикл с предусловием (while) в Pascal abc.net
-
Синтаксис цикла while:
while <условие> do // заголовок цикла <оператор> // тело цикла |
::=
Цикл while на блок-схеме
Итерация — однократное повторение тела цикла.
В цикле тело может не выполниться ни разу.
Пример: Вычислить сумму четных чисел от 2 до 20.
Решение:
sum = ; x = 2; while x <= 20 do begin sum += x; x += 2; end; |
Задание: Определите наименьшее натуральное число, квадрат которого больше заданного целого числа. Стандартную функцию извлечения квадратного корня не использовать.
Пример: Даны положительные числа A и B (A ≥ B). На отрезке длины A размещено максимально возможное количество отрезков длины B (без наложений). Не используя операции умножения и деления, найти количество отрезков B, размещенных на отрезке A.
Решение:
Begin var (a,b)=readInteger2; assert(a>=b); var k=; var s=; while s<=a do begin inc(k); s+=b end; writeln(k-1) End. |
Оператор break в цикле while
Оператор предназначен для экстренного выхода из цикла. Обычно используется в условном операторе: при выполнении условия — выход из цикла.
Как работать с последовательностями чисел?
Например, в случае, когда последовательность чисел должна заканчиваться нулем, то примерный код обработки последовательности может быть таким:
begin // ... while True do // бесконечный цикл begin // ввод очередного элемента последовательности var b = ReadInteger; // или ReadReal if b = then break; // выход из цикла при вводе элемента, равного нулю // обработка очередного элемента последовательности end; // вывод результатов end. |
Задание: Дана последовательность целых чисел, признак завершения которой — число (оно не считается элементом последовательности). Вывести номера чётных чисел последовательности (числа нумеровать с 1). Если последовательность не содержит чётных элементов, выводить ничего не нужно.
Цикл foreach
Для обхода массива или коллекции можно применять циклы for:
Синтаксис цикла foreach:
С его помощью можно переписать приведённые примеры обхода массива и коллекции. Получится такой код:
Результат выполнения обоих вариантов будет одинаковым, но конструкция сильно упростилась — теперь не нужно следить за счётчиком итераций. Цикл foreach сам поочерёдно берёт значения из массива/коллекции и помещает их в указанную перед двоеточием переменную.
Важно, чтобы тип переменной, указанной перед двоеточием, совпадал с типом массива/коллекции
Внимание: далее материал повышенной сложности (необходимо знание интерфейсов). На самом деле параметром после двоеточия может быть любой класс, который имплементирует интерфейс Iterable (а все коллекции-наследники java.util.Collection его имплементируют) и реализует метод iterator()
Мы можем даже самостоятельно создать класс, который будет передаваться в качестве параметра
На самом деле параметром после двоеточия может быть любой класс, который имплементирует интерфейс Iterable (а все коллекции-наследники java.util.Collection его имплементируют) и реализует метод iterator(). Мы можем даже самостоятельно создать класс, который будет передаваться в качестве параметра.
Пример такого кода:
Мы объявляем класс MyIterable, в нём создаём массив, по которому будем итерироваться. Реализуем метод iterator(), возвращающий объект интерфейса Iterator, а также hasNext и next. Метод hasNext вызывается перед каждой итерацией и проверяет, есть ли следующий элемент. Если не дошли до конца массива, то hasNext вернёт true.
Когда метод hasNext возвращает true, цикл foreach вызывает метод next, который должен вернуть следующий элемент. В нашем случае он, кроме того, увеличивает на 1 текущую позицию элемента массива для последующей итерации.
Под капотом цикл foreach выглядит как простой while, но такой код будет более громоздким:
Понимание основных элементов сценариев оболочки
По сути, сценарий оболочки представляет собой список команд, которые выполняются последовательно, а также некоторую логику, позволяющую выполнять код только при определённых условиях.
Чтобы понять сложные сценарии оболочки, рекомендуется начать с базовых сценариев.
Ниже показан очень простой скрипт:
Здесь содержатся несколько элементов, которые должны использоваться во всех скриптах. Для начала, есть shebang — это строка #!/bin/bash. Когда скрипт запускается из родительской оболочки, он открывает подоболочку, в которой и выполняются команды, указанные в скрипте.
Эти команды могут быть интерпретированы различными способами. Для того, чтобы понять, как именно они должны интерпретироваться, используется shebang. В примере выше shebang ясно даёт понять, что скрипт должен выполняться оболочкой bash.
Также могут быть указаны другие оболочки. Например, если ваш скрипт содержит код на языке Perl, shebang должен быть #!/usr/bin/perl. Начинать сценарий с shebang является хорошей практикой; если он опущен, код сценария будет выполняться такой же оболочкой, которая используется для запуска скрипта.
Сразу после shebang расположена часть, объясняющая, о чем сценарий. Несколько строк комментариев в начале каждого сценария — хорошая идея. В коротком скрипте часто очевидно, что он делает, но когда сценарий становится длиннее, и по мере того, как всё больше людей вовлекаются в его написание и поддержку, становится менее понятно, что авторы намереваются сделать.
Чтобы избежать такой ситуации, убедитесь, что вы добавили строки комментариев, начиная каждую символом #. Комментарии могут быть не только в первых строках, но и в начале каждого подраздела сценария. Это наверняка поможет, если вы прочитаете свой скрипт через несколько месяцев!
Вы также можете комментировать не только подразделы, но и отдельные строки.
Независимо от того, в какой позиции он используется, всё от символа # и до конца строки является комментарием.
После блока комментариев расположено тело сценария. В вышеуказанном примере это несколько команд, выполняющихся последовательно. Тело сценария оболочки может увеличиваться по мере его развития.
В конце скрипта я включил инструкцию exit 0. Оператор выхода сообщает родительской оболочке, был ли сценарий успешным. Состояние выхода последней команды в сценарии является состоянием выхода самого сценария, если только команда exit 0 не используется в конце сценария.
Полезно знать, что вы можете работать с exit, чтобы сообщить родительской оболочке, как все прошло.
После создания сценария убедитесь, что он может быть выполнен. Самый распространённый способ сделать это — применить к нему бит выполнения. Итак, если имя файла скрипта — hello, используйте команду chmod +x ./hello для того, чтобы сделать его исполняемым.
Сценарий также может быть выполнен в качестве аргумента команды bash. В этом случае введите bash ./hello для запуска скрипта hello. Если сценарий запускается как аргумент команды bash, файл скрипта не обязательно должен быть исполняемым.
По сути, вы можете хранить скрипт в любом месте, но если вы собираетесь хранить его в каталоге, который не включён в переменную $PATH, вам нужно выполнить его с ./ перед именем скрипта.
Введите ./hello для того, чтобы запустить сценарий, или поместите его в стандартный каталог, который включён в переменную $PATH, например, /usr/local/bin.
Также вы можете разместить сценарий в каталоге /bin, после чего в любом месте файловой системы просто ввести имя файла, и сценарий выполнится.
Пример
Командой vi /bin/datetime создадим в каталоге /bin файл с именем datetime. В созданный файл вставим это содержимое:
Сохранив файл, введите chmod +x /bin/datetime, чтобы дать файлу права на выполнение. Перейдите, к примеру, в домашний каталог с помощью команды cd ~ и просто введите datetime.
Перейдите, к примеру, в домашний каталог cd ~ и просто введите datetime.
Команда Until – продолжайте цикл до тех пор, пока оно не будет истинным
Пока это еще один тип команды, чтобы перебирать код.
В команде until команды тела будут выполняться до тех пор, пока условие не будет истинным. т.е. продолжайте цикл, пока условие будет ложным. Когда условие станет истинным, оно остановит цикл.
В следующем примере, если значение счетчика переменных не превышает 5, оно будет продолжать цикл. Когда условие становится истинным (т. е. Когда счетчик больше 5), он прекратит цикл.
# cat until1.rb count = 1 until count > 5 puts "#{count}" " The AndreyEx Blogs" count = count + 1 end
Как видно из приведенного ниже результата, приведенный выше пример выполнил цикл 5 раз, используя команду.
# ruby until1.rb 1 The AndreyEx Blogs 2 The AndreyEx Blogs 3 The AndreyEx Blogs 4 The AndreyEx Blogs 5 The AndreyEx Blogs
Примеры цикла for Bash
Переименование файлов с пробелами в имени файла
В следующем примере показано, как переименовать все файлы в текущем каталоге с пробелом в его именах, заменив пробел подчеркиванием:
Давайте разберем код построчно:
- Первая строка создает цикл и перебирает список всех файлов с пробелом в имени. Выражение создает список.
- Вторая строка применяется к каждому элементу списка и перемещает файл в новый, заменяя пробел подчеркиванием ( ). Часть использует расширение параметра оболочки для замены шаблона в параметре на строку.
- указывает на конец сегмента цикла.
Изменение расширения файла
В следующем примере показано, как использовать цикл Bash для переименования всех файлов, заканчивающихся на .jpeg в текущем каталоге, заменив расширение файла с .jpeg на .jpg.
Давайте проанализируем код построчно:
- Первая строка создает цикл и просматривает список всех файлов, заканчивающихся на «.jpeg».
- Вторая строка применяется к каждому элементу списка и перемещает файл в новый, заменяя «.jpeg» на «.jpg». удалить часть «.jpeg» из имени файла, используя расширение параметра оболочки
- указывает на конец сегмента цикла.
Функция range
Функция range используется при работе со строками цикла for, а также для создания последовательностей чисел. Рассмотрим на примере кода, как эта функция работает с целыми числами:
for number in range(5,10,2) : print("I am number : "+str(number))
Результат:
I am number : 5 I am number : 7 I am number : 9
Для работы функции range указываются 2 или 3 числа:
- Первое число — start — с него функция начинает отсчет.
- Второе число называется stop и обозначает конец выбранного промежутка чисел. В примере это цифра 10, поэтому функция не может показать число больше 10.
- Третье число называется step: это шаг, который делает функция при переборе чисел. Можно не указывать шаг, и тогда в нашем примере функция покажет все числа от 5 до 10.
Заданный пример начинается с 5, к этому числу прибавляется по 2, пока мы не упремся в потолок функции. Так, получается следующая последовательность чисел:
- 5;
- 5+2=7;
- 7+2=9.
Range также можно использовать с отрицательными числами и выполнять вычитание. Например:
for i in range(10, -5, -2): print(i)
Результат:
10 8 6 4 2 0 -2 -4
Ответ 1
Один из способов сделать это:
while read p; do
echo «$p»
done <peptides.txt
Данный способ имеет побочные эффекты, заключающиеся в обрезке ведущих пробелов, интерпретации последовательностей обратной косой черты и пропуске последней строки, если в ней отсутствует завершающий перевод строки. Если это неприемлемо, можно сделать следующее:
while IFS=»» read -r p ||
do
printf ‘%s\n’ «$p»
done < peptides.txt
В исключительных ситуациях, если содержимое считывается из стандартного ввода, можно открыть файл, используя другой дескриптор файла:
while read -u 10 p; do
…
done 10<peptides.txt
Здесь 10 — это просто произвольное число (отличное от 0, 1, 2).
Переменные
Переменная — это метка, которая используется для обозначения определённого места в памяти, которое содержит определённое значение. Переменные могут быть определены статически с помощью NAME=value или динамическим способом. Существует два решения для динамического определения переменной:
- Используйте ключевое слово read в скрипте, чтобы запросить данные у пользователя, запускающего скрипт.
- Используйте подстановку команд, чтобы использовать результат команды и назначить его переменной. Например, команда date +%d-%m-%y показывает текущую дату в формате день-месяц-год. Чтобы сделать это в сценарии, вы можете использовать TODAY=$(date +%d-%m-%y). Для подстановки команд вам просто нужно поместить команду, результат которой вы хотите использовать, между скобками.
В предыдущем разделе о позиционных параметрах вы узнали, как присваивать аргументы переменным при запуске скрипта. В некоторых случаях может быть более эффективно запрашивать информацию, когда вы обнаружите, что чего-то существенного не хватает. Сценарий в ниже показывает, как это сделать.
Листинг 3. Пример скрипта, использующего команду read
В сценарии листинга 3 оператор if… then… else… fi используется для проверки существования аргумента $1. Это делается с помощью test (test — это отдельная команда). Команда test может быть написана двумя способами*: test или . В примере строка if … выполняется, чтобы увидеть тест (проверку) -z $1.
*
-z test проверяет, существует или нет $1. Иначе говоря, строка if проверяет, является ли $1 пустым, что означает, что при запуске этого сценария не было предоставлено никаких аргументов. Если это так, команды после оператора then выполняются.
Обратите внимание, что при написании команды test с квадратными скобками важно использовать пробелы после открывающей скобки и перед закрывающей скобкой, без пробелов команда не будет работать. Обратите внимание, что оператор then следует сразу за test. Это возможно, потому что используется точка с запятой (;)
Точка с запятой является разделителем команд и может заменить новую строку в скрипте
Это возможно, потому что используется точка с запятой (;). Точка с запятой является разделителем команд и может заменить новую строку в скрипте
Обратите внимание, что оператор then следует сразу за test. Это возможно, потому что используется точка с запятой (;)
Точка с запятой является разделителем команд и может заменить новую строку в скрипте.
В операторе then выполняются две команды: команда echo, которая отображает сообщение на экране, и команда read.
Команда read останавливает сценарий, чтобы пользовательский ввод мог быть обработан и сохранен в переменной TEXT. Поэтому read TEXT помещает все введённые пользователем данные в переменную TEXT, которая будет использоваться позже в скрипте.
Следующая часть представлена оператором else. Команды после оператора else выполняются во всех других случаях, что в данном случае означает «иначе, если аргумент был предоставлен». Если это так, то определяется переменная TEXT и ей присваивается текущее значение $1.
Обратите внимание, как определяется переменная: непосредственно после имени переменной стоит знак =, за которым следует $1. Обратите внимание, что вы никогда не должны использовать пробелы при определении переменных
Затем условия if замыкается с помощью оператора fi. После завершения условия if вы точно знаете, что переменная TEXT определена и имеет значение. Предпоследняя строка скрипта считывает значение переменной TEXT и отображает это значение в STDOUT с помощью команды echo
Обратите внимание, что для запроса текущего значения переменной ссылается на имя переменной, начиная со знака $ перед ним
Вы можете попрактиковаться на этом примере при работе с вводом.
- Откройте редактор и создайте файл с именем text. Введите содержимое кода из листинга 3 в этот файл.
- Запишите файл на диск и выполните chmod +x text, чтобы сделать его исполняемым.
- Запустите скрипт, выполнив ./text и без дополнительных аргументов. Вы увидите, что он запрашивает ввод.
- Запустите скрипт, используя «hello» в качестве аргумента (./text hello). Результат отобразит «you have entered the text hello» в STDOUT.
Вложенные циклы
Циклы while и for можно как использовать по отдельности, так и комбинировать. Можно вложить цикл for внутрь внешнего цикла while и наоборот, а также вкладывать циклы одного вида друг в друга.
Вложенные циклы работают по следующей схеме: программа сначала сталкивается с внешним циклом и начинает выполнять его условия. Затем запускается внутренний вложенный цикл, который выполняется до своего завершения. Программа будет завершать внутренний цикл и возвращаться к началу внешнего до тех пор, пока последовательность не будет завершена или другой оператор не нарушит этот процесс.
Вложенный цикл for
Рассмотрим на примере вложенного цикла for, как это работает на практике:
num_list = alpha_list = for number in num_list: print(number) for letter in alpha_list: print(letter)
Результат:
1 a b c 2 a b c 3 a b c
По результату выполнения кода видно, что программа завершает первую итерацию внешнего цикла на цифре 1 и затем запускает завершение внутреннего цикла, печатая a, b, c. Как только внутренний цикл завершен, программа возвращается к началу внешнего цикла и печатает цифру 2, а после снова воспроизводит вложенный цикл.
Вложенный цикл while
Вложенный цикл while выглядит так:
i=1 while i<=3 : print(i,"Outer loop is executed only once") j=1 while j<=3: print(j,"Inner loop is executed until to completion") j+=1 i+=1;
Результат:
1 Outer loop is executed only once 1 Inner loop is executed until to completion 2 Inner loop is executed until to completion 3 Inner loop is executed until to completion 2 Outer loop is executed only once 1 Inner loop is executed until to completion 2 Inner loop is executed until to completion 3 Inner loop is executed until to completion 3 Outer loop is executed only once 1 Inner loop is executed until to completion 2 Inner loop is executed until to completion 3 Inner loop is executed until to completion
Операторы break и continue
И заявления могут быть использованы для управления выполнением цикла While.
Оператор завершает текущий цикл и передает управление программой к команде, следующей за прерванный цикл. Обычно используется для завершения цикла при выполнении определенного условия.
В следующем примере выполнение цикла будет прервано, как только текущий повторяющийся элемент будет равен
Оператор завершает текущую итерацию цикла и передает управление программой к следующей итерации цикла.
В следующем ниже, после того , как текущий итерированным элемент равен по исполнению заявления заставит вернуться к началу цикла и продолжить со следующей итерации.
Использование переменных и входных данных
bash-скрипты — это гораздо больше, чем просто список команд, которые выполняются последовательно. Одна из приятных сторон скриптов заключается в том, что они могут работать с переменными и входными данными, чтобы сделать скрипт гибким. В этом разделе вы узнаете, как с ними работать.
Использование позиционных параметров
При запуске скрипта можно использовать аргументы. Аргумент — это всё, что вы помещаете за командой сценария. Аргументы могут быть использованы для того, чтобы сделать скрипт более гибким. Возьмём команду useradd lisa. В этом примере команда — это useradd, а её аргумент — lisa — указывает, что нужно сделать.
В результате выполнения такой команды должен быть создан пользователь с именем lisa.
В тексте сценария первый аргумент обозначается $1, второй аргумент — $2 и т. д. Листинг 1 показывает, как можно использовать аргументы. Попробуйте запустить этот код, указав в качестве параметров любые имена пользователей.
Листинг 1
Под параметрами подразумевается ввод данных перед запуском скрипта. В данном случае в качестве параметров после имени скрипта argument я указал lisa, lori и bob:
Если вы попытались запустить пример кода, то могли заметить, что его содержимое не идеально. Если вы используете три аргумента при выполнении скрипта из листинга 1, он будет работать отлично. Если используете только два аргумента, третий выводится без значения $3.
Если же используете четыре аргумента, четвёртое значение (которое будет храниться в $4) никогда не отобразится. Итак, если вы хотите использовать аргументы, вам лучше использовать более гибкий подход.
Листинг 2
В Листинге 2 представлены два новых элемента, которые относятся к аргументам:
- $# — это счетчик, который показывает, сколько аргументов было использовано при запуске скрипта.
- $@ — список всех аргументов, которые использовались при запуске скрипта.
Чтобы перечислить аргументы, которые использовались при запуске этого скрипта, используется цикл for. В циклах for команды выполняются до тех пор, пока условие истинно. В этом сценарии условие for i in $@ означает «для каждого аргумента». Каждый раз, когда сценарий проходит цикл, значение из переменной $@ присваивается переменной $i.
Итак, пока есть аргументы, тело сценария выполняется.
Тело цикла for всегда начинается с do и закрывается done, а между этими двумя ключевыми словами перечисляются команды, которые необходимо выполнить. Таким образом, пример сценария будет использовать echo для отображения значения каждого аргумента и останавливаться, когда больше нет доступных аргументов.
Давайте попробуем воспользоваться скриптом из листинга 2 в этом примере:
- Введите vi argument, чтобы создать файл argument и скопируйте содержимое из скрипта листинга 2 в этот файл.
- Сохраните файл и сделайте его исполняемым.
- Запустите команду ./argument a b c. Вы увидите, что отобразятся три строки.
- Запустите команду ./argument a b c d e f. Вы увидите, что помимо a b c отобразятся и d e f.