Как работать с переменными в 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
перед ней. Таким образом, вы можете убедиться, что произойдет то, что вы хотите. Вы также можете обнаружить любые ошибки, которые вы могли допустить в синтаксисе.
Linux Commands | ||
Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc | |
Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | |
Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
RELATED: Best Linux Laptops for Developers and Enthusiasts