Как задать переменную в bash
Перейти к содержимому

Как задать переменную в bash

  • автор:

Как задать переменную в bash

оператор присваивания ( пробельные символы до и после оператора — недопустимы )

Обратите внимание: символ = может использоваться как в качестве оператора присваивания, так и в качестве оператора сравнения, конкретная интерпретация зависит от контекста применения.

Пример 4-2. Простое присваивание

#!/bin/bash # Явные переменные echo # Когда перед именем переменной не употребляется символ '$'? # В операциях присваивания. # Присваивание a=879 echo "Значение переменной \"a\" -- $a." # Присваивание с помощью ключевого слова 'let' let a=16+5 echo "Значение переменной \"a\" теперь стало равным: $a." echo # В заголовке цикла 'for' (своего рода неявное присваивание) echo -n "Значения переменной \"a\" в цикле: " for a in 7 8 9 11 do echo -n "$a " done echo echo # При использовании инструкции 'read' (тоже одна из разновидностей присваивания) echo -n "Введите значение переменной \"a\" " read a echo "Значение переменной \"a\" теперь стало равным: $a." echo exit 0

Пример 4-3. Присваивание значений переменным простое и замаскированное

#!/bin/bash a=23 # Простейший случай echo $a b=$a echo $b # Теперь немного более сложный вариант (подстановка команд). a=`echo Hello!` # В переменную 'a' попадает результат работы команды 'echo' echo $a # Обратите внимание на восклицательный знак (!) в подстанавливаемой команде #+ этот вариант не будет работать при наборе в командной строке, #+ поскольку здесь используется механизм "истории команд" BASH # Однако, в сценариях, механизм истории команд запрещен. a=`ls -l` # В переменную 'a' записывается результат работы команды 'ls -l' echo $a # Кавычки отсутствуют, удаляются лишние пробелы и пустые строки. echo echo "$a" # Переменная в кавычках, все пробелы и пустые строки сохраняются. # (См. главу "Кавычки.") exit 0
# Взято из /etc/rc.d/rc.local R=$(cat /etc/redhat-release) arch=$(uname -m)
Назад К началу Вперед
Переменные и параметры. Введение. Наверх Переменные Bash не имеют типа

13. bash №2: переменные

Когда мы говорим сегодня, мы подразумеваем 26 ноября. Если вы читаете эту тему завтра, то для вас слово сегодня будет означать 27 ноября. То есть, есть слово сегодня и оно может иметь различные значения. Постоянная часть, то есть слово сегодня – называется именем переменной или просто переменной, а та часть, которая меняется – 26 ноября или 27 ноября – называется значением переменной. Без переменных нельзя представить программирование и в bash-е они часто используются. Например, в эмуляторе терминала вы видите надпись user@centos8. Собственно user – это логин текущего пользователя, а centos8 – это имя системы. Если зайти другим пользователем или поменять имя системы, то будут отображаться другие значения.

В bash переменные нужны для нескольких задач. Начнём с так называемых локальных переменных, которые также называются shell variables. Это переменные, которые мы сами создаём и нужны они нам для каких-то своих задач.

Для примера создадим переменную files. Я создаю 3 файла:

touch file1 file2 file3 
files=file1 

Обратите внимание, никаких пробелов, чтобы bash не подумал, что я запускаю программу files. Итак, я создал переменную files и дал ей значение file1. Значение переменной я могу увидеть с помощью команды echo. Echo у нас выводит текст в stdout:

echo Hello World!

и используется во многих задачах, но о нём подробно поговорим в другой раз. Пока что выведем значение переменной c помощью echo:

echo $files

files – имя переменной, а чтобы взять значение нужно перед именем поставить знак доллара. echo нам показал значение file1. Мы можем использовать эту переменную с другими командами, например, чтобы посмотреть:

ls $files rm -i $files

или удалить файл. Но нужно понимать, что значение переменной – просто текст и с файлом он никак не связан. Просто bash превращает переменную в её значение, прежде чем запустить команду. В итоге в терминале получается команда:

rm file1 

От того, что я удалил файл, значение переменной никуда не делось:

echo $files

поэтому я могу снова использовать эту переменную:

touch $files

Имя переменной может содержать цифры, но не может начинаться с неё:

file1=file1 1file=file1 (неправильно) 

Также в имени переменной нельзя использовать специальные символы, точку, дефис и всё такое:

file.1=file1 (неправильно) file-1=file (неправильно) 

Но имя можно писать строчными, заглавными и их комбинацией:

pRiFfKi=2007 echo $pRiFfKi

И помните – всё это регистрозависимо. А в значениях переменных можно указывать всё что угодно, но если там есть пробелы и всякие символы – нужно брать значение в кавычки:

info="Some text here" 

Можно при задавании значения переменной использовать значение другой переменной:

myfiles="My files are $files" files="file1 file2 file3" echo $myfiles

Как тут видно, мы указали знак доллара и это воспринялось как значение переменной. Если же мы не хотим, чтобы наши значения обрабатывались, чтобы они были просто текстом, то берём значения в одинарные кавычки:

myfiles='My files are $files' echo $myfiles

либо экранируем знак доллара:

myfiles="My files are \$files" echo $myfiles

Бывает удобно указывать в значении переменной какую-то команду. Для этого нужно начинать значение с символа доллар и указать команду в скобках:

lines=$(tail -5 /etc/passwd | head -2) echo $lines

Либо использовать обратные кавычки:

lines=`tail -5 /etc/passwd | head -2`

но это устаревший метод. Ещё таким образом можно одни команды внедрять в другие, например:

head -2 $(grep -rl bash /etc/ 2> /dev/null)

Кстати, можно использовать tab для дополнения переменных. Так вот, те переменные, которые мы задали, существуют только в текущей bash сессии. Обычно локальные переменные используются во всяких скриптах, которые мы рассмотрим в другой раз, и в обычной работе с терминалом их используют не так часто. Но если вам всё же нужно, чтобы переменная работала и в других окнах, вы можете сохранить её значение в файле ~/.bashrc, как мы это делали для алиасов. Открываем файл:

nano ~/.bashrc 

files=»file1 file2 file3″

и сохраняем. В новых сессиях у нас теперь будет задана эта переменная:

echo $files

В противовес локальным переменным, которые используются в рамках текущей bash сессии или скрипта и не особо-то нужны другим программам, существуют переменные окружения – environment variables. С помощью команды env можно увидеть их список. Как вы заметили, все они указаны заглавными буквами. Такие переменные нужны для передачи каких-то значений различным программам.

Например, есть переменная LANG:

env | grep LANG 

которая указывает язык для запускаемых программ. Сейчас стоит английский и, если я запущу, допустим, firefox, он запустится на английском языке. Если я поменяю значение этой переменной на русский:

LANG=ru_RU.UTF-8 

и запущу firefox через ту же bash сессию – то увижу, что Firefox теперь на русском. То есть, с помощью таких переменных можно настраивать окружение.

Возвращаясь к env, тут есть пара переменных, которые могут нам пригодится в дальнейшем. Например, HOME – указывает на домашнюю директорию текущего пользователя, HOSTNAME на имя системы, USERNAME на имя текущего пользователя и т.п.

Ещё одна примечательная переменная – PATH:

env | grep PATH 

Обратите внимание, что в этой переменной перечислены директории. Опустим директории /home/user/bin и /home/user/.local/bin , так как их у нас пока нет, и зайдём в /usr/bin:

cd /usr/bin 

Здесь у нас огромное количество файлов – всё это исполняемые файлы, то есть программы. В прошлый раз я говорил, что команды, которые запускает bash – это либо алиасы, либо внутренние команды bash, либо внешние команды. Так вот, в переменной PATH перечислены директории, где искать эти внешние программы. То есть, когда я пишу mkdir, bash ищет во всех директориях PATH наличие такого файла и, если находит, запускает.

Так вот, в отличии от локальных переменных, переменные среды передаются дочерним процессам. Например, до этого мы поменяли значение переменной LANG и firefox при запуске прочитал значение этой переменной, потому что она переменная окружения. Мы можем превратить локальную переменную в переменную окружения, чтобы использовать её в дочерних процессах, с помощью команды export. Например:

files=file1 export files 
export files=file1 

Это хорошо видно на примере дочерних bash сессий. Например, создадим локальные переменные test1 и test2:

test1=test1 test2=test2 

Одну из них экспортнём:

export test1 

а другую нет. Тут же можем запустить env и увидеть, что здесь появился test1. Запустив другое окно мы test1 там не найдём, но если запустить дочернюю сессию bash:

bash echo $test1 echo $test2

мы увидим, что у test1 здесь есть значение, а у test2 нет. Потому что дочерние сессии получают только значения переменных окружения. И чтобы задать переменную окружения на постоянно, опять же, нужно редактировать файл.

Мы с вами уже работали с файлом ~/.bashrc, и там можно задать переменную. Но основное предназначение bashrc – настройка алиасов и всяких функций bash для эмулятора терминала. Правильнее говоря, в bashrc задаются настройки bash для интерактивной оболочки, в которой не нужно логиниться – то есть для эмулятора терминала. При запуске он у нас не требует логина и при этом нам нужно с ним вручную работать, то есть интерактивно. То есть, интерактивная оболочка без логина. А, скажем, firefox обычно мы запускаем не через эмулятор терминала, а через лаунчер. И для случаев, когда нам нужно использовать какие-то переменные независимо от эмулятора терминала, то есть независимо от интерактивной оболочки, нам нужен другой файл — ~/.bash_profile. Но, на самом деле, во многих дистрибутивах этот файл при запуске также считывает настройки с ~/.bashrc, из-за чего технически без разницы, где добавлять переменные. Также в каких-то дистрибутивах этот файл обычно называет .profile. Так вот, переменную мы можем создать как в ~/.bashrc, так и в ~/.bash_profile, или вообще создать свой файл со всеми своими алиасами и переменными.

Но я этого делать не буду, просто добавлю свою переменную в ~/.bash_profile:

nano ~/.bash_profile 

Единственное что, этот файл считывается в момент моего логина, а значит недостаточно просто открыть новую bash сессию, нужно перезайти в систему. В этом плане ~/.bashrc удобнее. Ну и если мы хотим, чтобы наши переменные работали не только для нашего пользователя, но и для всех других пользователей, то настраивать эти переменные нужно в файлах /etc/profile и /etc/bashrc. А если мы не хотим зависеть от bash-а, а использовать любую другую оболочку, то лучше указывать в /etc/environment.

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

© Copyright 2021, GNU Linux Pro, CC-BY-SA-4.0. Ревизия 5f665cc2 .

Переменные в Bash

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

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

Как они работают?

Переменная является временным хранилищем для части информации. Для переменных можно выполнить два действия:

  • Установка значения для переменной.
  • Чтение значения переменной.

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

Чтобы прочитать переменную, мы помещаем ее имя (которому предшествует знак $) в любом месте сценария, который нам нужен. Прежде чем Bash интерпретирует (или запускает) каждую строку нашего скрипта, он сначала проверяет, имеются ли какие-либо имена переменных. Для каждой переменной, которую она идентифицировала, она заменяет имя переменной своим значением. Затем он запускает эту строку кода и снова запускает процесс на следующей строке.

Вот несколько быстрых точек синтаксиса. Они будут подробно рассмотрены и продемонстрированы ниже.

  • При указании или чтении переменной мы помещаем знак $ перед именем переменной.
  • При установке переменной мы оставляем знак $.
  • Некоторым людям нравится писать имена переменных в верхнем регистре, чтобы они выделялись. Это ваше предпочтение. Они могут быть все прописными буквами, все строчными буквами или смесью.
  • Переменная может быть размещена в любом месте сценария (или в командной строке, если на то пошло), а при запуске Bash заменит его значением переменной. Это стало возможным, поскольку замена выполняется до запуска команды.

Аргументы командной строки

Аргументы командной строки обычно используются и просты в работе, поэтому они являются хорошим местом для начала.

Когда мы запускаем программу в командной строке, вы будете знакомы с предоставлением аргументов после нее, чтобы контролировать ее поведение. Например , мы могли бы выполнить команду Ls -l / и т.д. . -l и / etc — оба аргумента командной строки для команды ls . Мы можем сделать подобное с нашими сценариями bash. Для этого мы используем переменные $ 1 для представления первого аргумента командной строки, $ 2 для представления второго аргумента командной строки и т. д. Они автоматически устанавливаются системой, когда мы запускаем наш скрипт, поэтому все, что нам нужно сделать, это обратиться к ним.

Давайте посмотрим на пример mycopy.sh

#!/bin/bash # Простой сценарий копирования cp $1 $2 # Давайте проверим, что копия работала echo Details for $2 ls -lh $2

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

  • Строка 4 — запустите команду cp с первым аргументом командной строки в качестве источника и второго аргумента командной строки в качестве адресата.
  • Строка 8 — запуск эха команды для печати сообщения.
  • Строка 9 — После завершения копирования запустите команду ls для адресата, чтобы убедиться, что она сработала. Мы включили опции l, чтобы показать нам дополнительную информацию и h, чтобы сделать размер читаемым человеком, чтобы мы могли проверить его правильность копирования.

Мы обсудим их использование немного больше в следующей статье.

Другие специальные переменные

Есть несколько других переменных, которые система устанавливает и для вас.

  • $0 — имя скрипта Bash.
  • $1-$9 — Первые 9 аргументов для скрипта Bash. (Как уже упоминалось выше.)
  • $# — Сколько аргументов было передано скрипту Bash.
  • $@ — Все аргументы, предоставленные сценарию Bash.
  • $?— Статус выхода последнего процесса.
  • $$ — Идентификатор процесса текущего скрипта.
  • $USER — имя пользователя, выполняющего скрипт.
  • $HOSTNAME — имя хоста, на котором запущен скрипт.
  • $SECONDS — количество секунд с момента запуска скрипта.
  • $RANDOM — Возвращает другое случайное число каждый раз, когда он упоминается.
  • $LINENO — возвращает текущий номер строки в сценарии Bash.

Если вы введете команду env в командной строке, вы увидите список других переменных, к которым вы также можете обратиться.

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

Настройка собственных переменных

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

Существует несколько способов, которыми могут быть заданы переменные (например, часть выполнения команды), но базовая форма следует этому шаблону:

Это одна из тех областей, где важно форматирование. Обратите внимание, что по обе стороны от знака равенства (=) нет места. Мы также оставляем знак $ с начала имени переменной при настройке.

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

Вот простой пример, иллюстрирующий их использование.

#!/bin/bash # Пример простой переменной myvariable=Hello anothervar=Fred echo $myvariable $anothervar echo sampledir=/etc ls $sampledir

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

  • Строки 4 и 6 — задайте значение двух переменных myvariable и anothervar.
  • Строка 8 — запустить эхо команды, чтобы проверить, что переменные были установлены в соответствии с назначением.
  • Строка 9 — запустите команду echo на этот раз без аргументов. Это хороший способ получить пустую строку на экране, чтобы помочь решить проблему.
  • Строка 11 — установите другую переменную, на этот раз в качестве пути к определенному каталогу.
  • Строка 13 — запустите команду ls, заменив значение переменной sampledir в качестве первого аргумента командной строки.

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

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

Цитаты

В приведенном выше примере мы сохранили все хорошо и просто. Переменные должны были хранить только одно слово. Если мы хотим, чтобы переменные сохраняли более сложные значения, нам нужно использовать кавычки. Это связано с тем, что при обычных условиях Bash использует пространство для определения отдельных элементов.

  • Помните, что команды работают точно так же в командной строке, как и в скрипте.

Поскольку команды работают точно так же в командной строке, как в скрипте, иногда бывает легче экспериментировать в командной строке.

Когда мы заключим наш контент в кавычки, мы указываем Bash, что содержимое должно рассматриваться как отдельный элемент. Вы можете использовать одинарные кавычки (‘) или двойные кавычки («).

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

Замена команды

Подстановка команд позволяет нам выводить вывод команды или программы (что обычно печатается на экране) и сохранять ее как значение переменной. Для этого мы помещаем его в скобки, которому предшествует знак $.

Подстановка команд хороша и проста, если вывод команды — это одно слово или строка. Если выход идет по нескольким строкам, то новые строки просто удаляются, и весь вывод заканчивается на одной строке.

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

  • Строка 1 — Запустим команду ls . Обычно его выход будет состоять из нескольких строк. Я немного сократил его в приведенном выше примере, чтобы сэкономить место.
  • Строка 4 — Когда мы сохраняем команду переменной myvar, все строки новой строки удаляются , а вывод теперь находится в одной строке.

Когда вы играете с подстановкой команд, рекомендуется проверить ваш результат, а не предполагать, что он будет вести себя определенным образом. Самый простой способ сделать это — просто повторить переменную и посмотреть, что произошло. (После этого вы можете удалить команду эха, когда вы будете счастливы.)

Экспорт переменных

Помните, как в предыдущем разделе мы говорили о сценариях, запущенных в их собственном процессе ? Это вводит явление, известное как область действия, которая влияет на переменные между прочим. Идея состоит в том, что переменные ограничены процессом, в котором они были созданы. Нормальный это не проблема, но иногда, например, сценарий может запускать другой скрипт в качестве одной из его команд. Если мы хотим, чтобы переменная была доступна для второго скрипта, нам нужно экспортировать переменную.

script1.sh

#!/bin/bash # demonstrate variable scope 1. var1=blah var2=foo # Let's verify their current value echo $0 :: var1 : $var1, var2 : $var2 export var1 ./script2.sh # Let's see what they are now echo $0 :: var1 : $var1, var2 : $var2

script2.sh

#!/bin/bash # demonstrate variable scope 2 # Let's verify their current value echo $0 :: var1 : $var1, var2 : $var2 # Let's change their values var1=flop var2=bleh

Теперь давайте запустим его и посмотрим, что произойдет.

Вывод выше может показаться неожиданным. Фактически, когда мы экспортируем переменную, мы говорим Bash, что каждый раз, когда создается новый процесс (для запуска другого скрипта или такого), создайте копию переменной и передайте ее новому процессу. Поэтому, хотя переменные имеют одно и то же имя, они существуют в отдельных процессах и поэтому не связаны друг с другом.

Экспорт переменных — односторонний процесс. Первоначальный процесс может передавать переменные новому процессу, но все, что происходит с копией переменных, не влияет на исходные переменные.

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

Bash-скрипты, часть 3: параметры и ключи командной строки

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

image

Наиболее распространённый способ передачи данных сценариям заключается в использовании параметров командной строки. Вызвав сценарий с параметрами, мы передаём ему некую информацию, с которой он может работать. Выглядит это так:

$ ./myscript 10 20

В данном примере сценарию передано два параметра — «10» и «20». Всё это хорошо, но как прочесть данные в скрипте?

Чтение параметров командной строки

Оболочка bash назначает специальным переменным, называемым позиционными параметрами, введённые при вызове скрипта параметры командной строки:

  • $0 — имя скрипта.
  • $1 — первый параметр.
  • $2 — второй параметр — и так далее, вплоть до переменной $9 , в которую попадает девятый параметр.
#!/bin/bash echo $0 echo $1 echo $2 echo $3

Запустим сценарий с параметрами:

./myscript 5 10 15

Вот что он выведет в консоль.

Вывод параметров, с которыми запущен скрипт

Обратите внимание на то, что параметры командной строки разделяются пробелами.

Взглянем на ещё один пример использования параметров. Тут мы найдём сумму чисел, переданных сценарию:

#!/bin/bash total=$[ $1 + $2 ] echo The first parameter is $1. echo The second parameter is $2. echo The sum is $total.

Запустим скрипт и проверим результат вычислений.

Сценарий, который находит сумму переданных ему чисел

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

#!/bin/bash echo Hello $1, how do you do
./myscript Adam

Он выведет то, что мы от него ожидаем.

Сценарий, работающий со строковым параметром

Что если параметр содержит пробелы, а нам надо обрабатывать его как самостоятельный фрагмент данных? Полагаем, если вы освоили предыдущие части этого руководства, ответ вы уже знаете. Заключается он в использовании кавычек.

Если скрипту надо больше девяти параметров, при обращении к ним номер в имени переменной надо заключать в фигурные скобки, например так:

Проверка параметров

Если скрипт вызван без параметров, но для нормальной работы кода предполагается их наличие, возникнет ошибка. Поэтому рекомендуется всегда проверять наличие параметров, переданных сценарию при вызове. Например, это можно организовать так:

#!/bin/bash if [ -n "$1" ] then echo Hello $1. else echo "No parameters found. " fi

Вызовем скрипт сначала с параметром, а потом без параметров.

Вызов скрипта, проверяющего наличие параметров командной строки

Подсчёт параметров

В скрипте можно подсчитать количество переданных ему параметров. Оболочка bash предоставляет для этого специальную переменную. А именно, переменная $# содержит количество параметров, переданных сценарию при вызове.

#!/bin/bash echo There were $# parameters passed.
./myscript 1 2 3 4 5

В результате скрипт сообщит о том, что ему передано 5 параметров.

Подсчёт количества параметров в скрипте

Эта переменная даёт необычный способ получения последнего из переданных скрипту параметров, не требующий знания их количества. Вот как это выглядит:

#!/bin/bash echo The last parameter was $

Вызовем скрипт и посмотрим, что он выведет.

Обращение к последнему параметру

Захват всех параметров командной строки

В некоторых случаях нужно захватить все параметры, переданные скрипту. Для этого можно воспользоваться переменными $* и $@ . Обе они содержат все параметры командной строки, что делает возможным доступ к тому, что передано сценарию, без использования позиционных параметров.

Переменная $* содержит все параметры, введённые в командной строке, в виде единого «слова».

В переменной $@ параметры разбиты на отдельные «слова». Эти параметры можно перебирать в циклах.

Рассмотрим разницу между этими переменными на примерах. Сначала взглянем на их содержимое:

#!/bin/bash echo "Using the \$* method: $*" echo "-----------" echo "Using the \$@ method: $@"

Вот вывод скрипта.

Переменные $* и $@

Как видно, при выводе обеих переменных получается одно и то же. Теперь попробуем пройтись по содержимому этих переменных в циклах для того, чтобы увидеть разницу между ними:

#!/bin/bash count=1 for param in "$*" do echo "\$* Parameter #$count = $param" count=$(( $count + 1 )) done count=1 for param in "$@" do echo "\$@ Parameter #$count = $param" count=$(( $count + 1 )) done

Взгляните на то, что скрипт вывел в консоль. Разница между переменными вполне очевидна.

Разбор переменных $* и $@ в цикле

Переменная $* содержит все переданные скрипту параметры как единый фрагмент данных, в то время как в переменной $@ они представлены самостоятельными значениями. Какой именно переменной воспользоваться — зависит от того, что именно нужно в конкретном сценарии.

Команда shift

Использовать команду shift в bash-скриптах следует с осторожностью, так как она, в прямом смысле слова, сдвигает значения позиционных параметров.

Когда вы используете эту команду, она, по умолчанию, сдвигает значения позиционных параметров влево. Например, значение переменной $3 становится значением переменной $2 , значение $2 переходит в $1 , а то, что было до этого в $1, теряется. Обратите внимание на то, что при этом значение переменной $0 , содержащей имя скрипта, не меняется.

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

#!/bin/bash count=1 while [ -n "$1" ] do echo "Parameter #$count = $1" count=$(( $count + 1 )) shift done

Скрипт задействует цикл while , проверяя длину значения первого параметра. Когда длина станет равна нулю, происходит выход из цикла. После проверки первого параметра и вывода его на экран, вызывается команда shift , которая сдвигает значения параметров на одну позицию.

Использование команды shift для перебора параметров

Используя команду shift , помните о том, что при каждом её вызове значение переменной $1 безвозвратно теряется.

Ключи командной строки

Ключи командной строки обычно выглядят как буквы, перед которыми ставится тире. Они служат для управления сценариями. Рассмотрим такой пример:

#!/bin/bash echo while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) echo "Found the -b option" ;; -c) echo "Found the -c option" ;; *) echo "$1 is not an option" ;; esac shift done
$ ./myscript –a –b –c –d

И проанализируем то, что он выведет в терминал.

Обработка ключей в скрипте

В этом коде использована конструкция case , которая сверяет переданный ей ключ со списком обрабатываемых скриптом ключей. Если переданное значение нашлось в этом списке, выполняется соответствующая ветвь кода. Если при вызове скрипта будет использован любой ключ, обработка которого не предусмотрена, будет исполнена ветвь «*».

Как различать ключи и параметры

Часто при написании bash-скриптов возникает ситуация, когда надо использовать и параметры командной строки, и ключи. Стандартный способ это сделать заключается в применении специальной последовательности символов, которая сообщает скрипту о том, когда заканчиваются ключи и начинаются обычные параметры.

Эта последовательность — двойное тире (—). Оболочка использует её для указания позиции, на которой заканчивается список ключей. После того, как скрипт обнаружит признак окончания ключей, то, что осталось, можно, не опасаясь ошибок, обрабатывать как параметры, а не как ключи. Рассмотрим пример:

#!/bin/bash while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) echo "Found the -b option";; -c) echo "Found the -c option" ;; --) shift break ;; *) echo "$1 is not an option";; esac shift done count=1 for param in $@ do echo "Parameter #$count: $param" count=$(( $count + 1 )) done

Этот сценарий использует команду break для прерывания цикла while при обнаружении в строке двойного тире.

Вот что получится после его вызова.

Обработка ключей и параметров командной строки

Как видно, когда скрипт, разбирая переданные ему данные, находит двойное тире, он завершает обработку ключей и считает всё, что ещё не обработано, параметрами.

Обработка ключей со значениями

По мере усложнения ваших скриптов, вы столкнётесь с ситуациями, когда обычных ключей уже недостаточно, а значит, нужно будет использовать ключи с некими значениями. Например, вызов сценария в котором используется подобная возможность, выглядит так:

./myscript -a test1 -b -c test2

Скрипт должен уметь определять, когда вместе с ключами командной строки используются дополнительные параметры:

#!/bin/bash while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option";; -b) param="$2" echo "Found the -b option, with parameter value $param" shift ;; -c) echo "Found the -c option";; --) shift break ;; *) echo "$1 is not an option";; esac shift done count=1 for param in "$@" do echo "Parameter #$count: $param" count=$(( $count + 1 )) done

Вызовем этот скрипт в таком виде:

./myscript -a -b test1 -d

Посмотрим на результаты его работы.

Обработка параметров ключей

В данном примере в конструкции case обрабатываются три ключа. Ключ -b требует наличия дополнительного параметра. Так как обрабатываемый ключ находится в переменной $1 , соответствующий ему параметр будет находиться в $2 (тут используется команда shift , поэтому, по мере обработки, всё, что передано сценарию, сдвигается влево). Когда с этим мы разобрались, осталось лишь извлечь значение переменной $2 и у нас будет параметр нужного ключа. Конечно, тут понадобится ещё одна команда shift для того, чтобы следующий ключ попал в $1 .

Использование стандартных ключей

При написании bash-скриптов вы можете выбирать любые буквы для ключей командной строки и произвольно задавать реакцию скрипта на эти ключи. Однако, в мире Linux значения некоторых ключей стали чем-то вроде стандарта, которого полезно придерживаться. Вот список этих ключей:

-a Вывести все объекты.
-c Произвести подсчёт.
-d Указать директорию.
-e Развернуть объект.
-f Указать файл, из которого нужно прочитать данные.
-h Вывести справку по команде.
-i Игнорировать регистр символов.
-l Выполнить полноформатный вывод данных.
-n Использовать неинтерактивный (пакетный) режим.
-o Позволяет указать файл, в который нужно перенаправить вывод.
-q Выполнить скрипт в quiet-режиме.
-r Обрабатывать папки и файлы рекурсивно.
-s Выполнить скрипт в silent-режиме.
-v Выполнить многословный вывод.
-x Исключить объект.
-y Ответить «yes» на все вопросы.

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

Получение данных от пользователя

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

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

Эта команда позволяет принимать введённые данные либо со стандартного ввода (с клавиатуры), либо используя другие дескрипторы файлов. После получения данных, эта команда помещает их в переменную:

#!/bin/bash echo -n "Enter your name: " read name echo "Hello $name, welcome to my program."

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

Обработка пользовательского ввода

При вызове read можно указывать и несколько переменных:

#!/bin/bash read -p "Enter your name: " first last echo "Your data for $last, $first…"

Вот что выведет скрипт после запуска.

Несколько переменных в команде read

Если, вызвав read , не указывать переменную, данные, введённые пользователем, будут помещены в специальную переменную среды REPLY :

#!/bin/bash read -p "Enter your name: " echo Hello $REPLY, welcome to my program.

Использование переменной среды REPLY

Если скрипт должен продолжать выполнение независимо от того, введёт пользователь какие-то данные или нет, вызывая команду read можно воспользоваться ключом -t . А именно, параметр ключа задаёт время ожидания ввода в секундах:

#!/bin/bash if read -t 5 -p "Enter your name: " name then echo "Hello $name, welcome to my script" else echo "Sorry, too slow! " fi

Если данные не будут введены в течение 5 секунд, скрипт выполнит ветвь условного оператора else , выведя извинения.

Ограничение времени на ввод данных

Ввод паролей

Иногда то, что вводит пользователь в ответ на вопрос скрипта, лучше на экране не показывать. Например, так обычно делают, запрашивая пароли. Ключ -s команды read предотвращает отображение на экране данных, вводимых с клавиатуры. На самом деле, данные выводятся, но команда read делает цвет текста таким же, как цвет фона.

#!/bin/bash read -s -p "Enter your password: " pass echo "Is your password really $pass? "

Вот как отработает этот скрипт.

Ввод конфиденциальных данных

Чтение данных из файла

Команда read может, при каждом вызове, читать одну строку текста из файла. Когда в файле больше не останется непрочитанных строк, она просто остановится. Если нужно получить в скрипте всё содержимое файла, можно, с помощью конвейера, передать результаты вызова команды cat для файла, конструкции while , которая содержит команду read (конечно, использование команды cat выглядит примитивно, но наша цель — показать всё максимально просто, ориентируясь на новичков; опытные пользователи, уверены, это поймут).

Напишем скрипт, в котором используется только что описанный подход к чтению файлов.

#!/bin/bash count=1 cat myfile | while read line do echo "Line $count: $line" count=$(( $count + 1 )) done echo "Finished"

Посмотрим на него в деле.

Чтение данных из файла

Тут мы передали в цикл while содержимое файла и перебрали все строки этого файла, выводя номер и содержимое каждой из них.

Итоги

Сегодня мы разобрали работу с ключами и параметрами командной строки. Без этих средств диапазон использования скриптов оказывается чрезвычайно узким. Даже если скрипт написан, что называется, «для себя». Тут же мы рассмотрели подходы к получению данных от пользователя во время выполнения программы — это делает сценарии интерактивными.

В следующий раз поговорим об операциях ввода и вывода.

Уважаемые читатели! Спасибо вам за то, что делитесь опытом в комментариях к предыдущим частям этого цикла материалов. Если вам есть что сказать об обработке всего того, что можно передать в скрипт при запуске или во время его работы, уверены, многим будет интересно об этом почитать.

  • Блог компании RUVDS.com
  • Настройка Linux
  • Серверное администрирование

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *