Поиск по сайту:

Как работать с переменными в Bash


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

Переменные 101

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

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

Примеры

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

Мы создадим четыре строковые переменные и одну числовую переменную, this_year:

me=Dave
my_boost=Linux
him=Popeye
his_boost=Spinach
this_year=2019

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

echo $my_name
echo $my_boost
echo $this_year

Давайте используем все наши переменные сразу:

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

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

my_boost=Tequila

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

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

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

Мы поговорим о заключении в кавычки переменных позже. А пока, вот что нужно помнить:

  • Переменная в одинарных кавычках  обрабатывается как буквальная строка, а не как переменная.
  • Переменные в кавычках \ обрабатываются как переменные.
  • Чтобы получить значение, хранящееся в переменной, необходимо указать знак доллара $.
  • Переменная без знака доллара $ представляет собой только имя переменной.

Вы также можете создать переменную, которая берет свое значение из существующей переменной или нескольких переменных. Следующая команда определяет новую переменную с именем drink_of_the_Year и присваивает ей объединенные значения переменных my_boost и this_year:

drink_of-the_Year="$my_boost $this_year"
echo drink_of_the-Year

Как использовать переменные в скриптах

Скрипты были бы полностью парализованы без переменных. Переменные обеспечивают гибкость, которая делает сценарий общим, а не конкретным решением. Чтобы проиллюстрировать разницу, вот скрипт, который подсчитывает файлы в каталоге /dev.

Введите это в текстовый файл, а затем сохраните его как fcnt.sh (для «количества файлов»):

#!/bin/bash

folder_to_count=/dev

file_count=$(ls $folder_to_count | wc -l)

echo $file_count files in $folder_to_count

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

chmod +x fcnt.sh

Введите следующее, чтобы запустить скрипт:

./fcnt.sh

Это печатает количество файлов в каталоге /dev. Вот как это работает:

  • Определена переменная с именем folder_to_count, и она настроена на хранение строки «/dev».
  • Определена еще одна переменная с именем file_count. Эта переменная получает свое значение из подстановки команды. Это командная фраза, заключенная в круглые скобки $ ( ). Обратите внимание, что перед первой скобкой стоит знак доллара $. Эта конструкция $ ( ) оценивает команды в круглых скобках, а затем возвращает их окончательное значение. В этом примере это значение присваивается переменной file_count. Что касается переменной file_count, ей передается значение для хранения; это не связано с тем, как было получено значение.
  • Команда, оцениваемая при подстановке команд, выполняет список файлов ls в каталоге в переменной folder_to_count, для которой задано значение «/dev». Таким образом, скрипт выполняет команду «ls /dev».
  • Вывод этой команды передается команде wc. Параметр -l (счетчик строк) заставляет wc подсчитывать количество строк в выводе команды ls. Поскольку каждый файл указан в отдельной строке, это количество файлов и подкаталогов в каталоге «/dev». Это значение присваивается переменной file_count.
  • В последней строке для вывода результата используется эхо.

Но это работает только для каталога «/dev». Как заставить скрипт работать с любым каталогом? Все, что требуется, это одно небольшое изменение.

Как использовать параметры командной строки в скриптах

Многие команды, такие как ls и wc, принимают параметры командной строки. Они предоставляют информацию команде, поэтому она знает, что вы хотите сделать. Если вы хотите, чтобы ls работал в вашем домашнем каталоге, а также отображал скрытые файлы, вы можете использовать следующую команду, где тильда ~ и -a Параметр (all) — это параметры командной строки:

ls ~ -a

Наши скрипты могут принимать параметры командной строки. Они обозначаются как $1 для первого параметра, $2 для второго и так далее, вплоть до $9 для девятого параметра. (На самом деле, есть и $0, но он зарезервирован для постоянного хранения скрипта.)

Вы можете ссылаться на параметры командной строки в сценарии так же, как и на обычные переменные. Давайте изменим наш скрипт, как показано ниже, и сохраним его под новым именем fcnt2.sh:

#!/bin/bash

folder_to_count=$1

file_count=$(ls $folder_to_count | wc -l)

echo $file_count files in $folder_to_count

На этот раз переменной folder_to_count присваивается значение первого параметра командной строки, $1.

Остальная часть скрипта работает точно так же, как и раньше. Ваш сценарий теперь не конкретное решение, а общий. Вы можете использовать его в любом каталоге, потому что он не жестко закодирован для работы только с «/dev».

Вот как вы делаете скрипт исполняемым:

chmod +x fcnt2.sh

Теперь попробуйте это с несколькими каталогами. Вы можете сначала выполнить «/dev», чтобы убедиться, что вы получите тот же результат, что и раньше. Введите следующее:

./fnct2.sh /dev
./fnct2.sh /etc
./fnct2.sh /bin

Вы получите тот же результат (207 файлов), что и раньше, для каталога «/dev». Это обнадеживает, и вы получаете специфичные для каталога результаты для каждого из других параметров командной строки.

Чтобы сократить сценарий, можно вообще обойтись без переменной folder_to_count и просто ссылаться на $1, как показано ниже:

#!/bin/bash 

file_count=$(ls $1  wc -l) 

echo $file_count files in $1

Работа со специальными переменными

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

Ниже приведены другие специальные предустановленные переменные:

  • $#: сколько параметров командной строки было передано сценарию.
  • $@: все параметры командной строки передаются сценарию.
  • $?: статус завершения последнего запущенного процесса.
  • $$: идентификатор процесса (PID) текущего скрипта.
  • $USER: имя пользователя, выполняющего скрипт.
  • $HOSTNAME: имя хоста компьютера, на котором запущен скрипт.
  • $SECONDS: количество секунд, в течение которых выполнялся скрипт.
  • $RANDOM: возвращает случайное число.
  • $LINENO: возвращает номер текущей строки скрипта.

Вы хотите увидеть их все в одном сценарии, не так ли? Ты можешь! Сохраните следующее как текстовый файл с именем special.sh:

#!/bin/bash

echo "There were $# command line parameters"
echo "They are: $@"
echo "Parameter 1 is: $1"
echo "The script is called: $0"
# any old process so that we can report on the exit status
pwd
echo "pwd returned $?"
echo "This script has Process ID $$"
echo "The script was started by $USER"
echo "It is running on $HOSTNAME"
sleep 3
echo "It has been running for $SECONDS seconds"
echo "Random number: $RANDOM"
echo "This is line number $LINENO of the script"

Введите следующее, чтобы сделать его исполняемым:

chmod +x special.sh

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

Переменные среды

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

Чтобы увидеть активные переменные среды в сеансе Bash, используйте эту команду:

env | less

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

Как экспортировать переменные

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

Сначала сохраните следующее с именем файла script_one.sh:

#!/bin/bash

first_var=alpha
second_var=bravo

# check their values
echo "$0: first_var=$first_var, second_var=$second_var"

export first_var
export second_var

./script_two.sh

# check their values again
echo "$0: first_var=$first_var, second_var=$second_var"

Это создает две переменные, first_var и second_var, и присваивает им некоторые значения. Он выводит их в окно терминала, экспортирует переменные и вызывает script_two.sh. Когда script_two.sh завершается и процесс возвращается к этому сценарию, он снова выводит переменные в окно терминала. Затем вы можете увидеть, изменились ли они.

Второй скрипт, который мы будем использовать, это script_two.sh. Это скрипт, который вызывает script_one.sh. Введите следующее:

#!/bin/bash

# check their values
echo "$0: first_var=$first_var, second_var=$second_var"

# set new values
first_var=charlie
second_var=delta

# check their values again
echo "$0: first_var=$first_var, second_var=$second_var"

Этот второй сценарий печатает значения двух переменных, присваивает им новые значения, а затем снова печатает их.

Чтобы запустить эти сценарии, вы должны ввести следующее, чтобы сделать их исполняемыми:

chmod +x script_one.sh
chmod +x script_two.sh

А теперь введите следующее, чтобы запустить script_one.sh:

./script_one.sh

Вот что нам сообщает вывод:

  • script_one.sh выводит значения переменных: alpha и bravo.
  • script_two.sh выводит значения переменных (альфа и браво) по мере их получения.
  • script_two.sh изменяет их на charlie и delta.
  • script_one.sh распечатывает значения переменных, которые по-прежнему имеют значения alpha и bravo.

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

Как цитировать переменные

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

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

Вот пример:

site_name=How-To Geek

Bash видит пробел перед «Geek» как указание на то, что запускается новая команда. Он сообщает, что такой команды нет, и покидает линию. echo показывает нам, что переменная site_name ничего не содержит — даже текст «How-To».

Попробуйте еще раз, заключив значение в кавычки, как показано ниже:

site_name="How-To Geek"

На этот раз оно распознается как одно значение и правильно назначается переменной site_name.

эхо твой друг

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

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

RELATED: Best Linux Laptops for Developers and Enthusiasts