Разработка сценариев bash

шпаргалка по написанию bash скриптов, по ссылке - оригинальная статья на хабре - bash-guide-1.md

Бесплатная книга-сайт на русском, полный гайд
Advanced Bash-Scripting Guide

Введение

BASH — Bourne-Again SHell (что может переводится как «перерожденный шел», или «Снова шел Борна(создатель sh)»), самый популярный командный интерпретатор в юниксоподобных системах, в особенности в GNU/Linux. Ниже приведу ряд встроенных команд, которые мы будем использовать для создания своих скриптов.

break выход из цикла for, while или until
continue выполнение следующей итерации цикла for, while или until
echo вывод аргументов, разделенных пробелами, на стандартное устройство вывода
exit выход из оболочки
export отмечает аргументы как переменные для передачи в дочерние процессы в среде
hash запоминает полные имена путей команд, указанных в качестве аргументов, чтобы не искать их при следующем обращении
kill посылает сигнал завершения процессу
pwd выводит текущий рабочий каталог
read читает строку из ввода оболочки и использует ее для присвоения значений указанным переменным.
return заставляет функцию оболочки выйти с указанным значением
shift перемещает позиционные параметры налево
test вычисляет условное выражение
times выводит имя пользователя и системное время, использованное оболочкой и ее потомками
trap указывает команды, которые должны выполняться при получении оболочкой сигнала
unset вызывает уничтожение переменных оболочки
wait ждет выхода из дочернего процесса и сообщает выходное состояние.

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

Что необходимо знать с самого начала

  1. Любой bash-скрипт должен начинаться со строки:

#!/bin/bash

в этой строке после #! указывается путь к bash-интерпретатору, поэтому если он у вас установлен в другом месте(где, вы можете узнать набрав whereis bash) поменяйте её на ваш путь.

  1. Коментарии начинаются с символа # (кроме первой строки).
  2. В bash переменные не имеют типа(о них речь пойдет ниже)

Переменные и параметры скрипта

Приведу как пример небольшой пример, который мы разберем:

#!/bin/bash #указываем где у нас хранится bash-интерпретатор
#присваиваем переменной parametr1 значение первого параметра скрипта
parametr1=$1
#присваиваем переменной script_name значение имени скрипта
script_name=$0
# команда echo выводит определенную строку, обращение к переменным осуществляется через $имя_переменной.
echo "Вы запустили скрипт с именем $script_name и параметром $parametr1"
# здесь мы видим другие кавычки, разница в том, что в одинарных кавычках не происходит подстановки переменных.
echo 'Вы запустили скрипт с именем $script_name и параметром $parametr1'
#Выход с кодом 0 (удачное завершение работы скрипта)
exit 0

Результат выполнения скрипта:

ite@ite-desktop:~$ ./test.sh qwerty
Вы запустили скрипт с именем ./test.sh и параметром qwerty
Вы запустили скрипт с именем $script_name и параметром $parametr1

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

$DIRSTACK — содержимое вершины стека каталогов
$EDITOR — текстовый редактор по умолчанию
$EUID — Эффективный UID. Если вы использовали программу su для выполнения команд от другого пользователя, то эта переменная содержит UID этого пользователя, в то время как…
$UID — …содержит реальный идентификатор, который устанавливается только при логине.
$FUNCNAME — имя текущей функции в скрипте.
$GROUPS — массив групп к которым принадлежит текущий пользователь
$HOME — домашний каталог пользователя
$HOSTNAME — ваш hostname
$HOSTTYPE — архитектура машины.
$LC_CTYPE — внутренняя переменная, котороя определяет кодировку символов
$OLDPWD — прежний рабочий каталог
$OSTYPE — тип ОС
$PATH — путь поиска программ
$PPID — идентификатор родительского процесса
$SECONDS — время работы скрипта(в сек.)
$# — общее количество параметров переданных скрипту
$* — все аргументы переданыне скрипту(выводятся в строку)
$@ — тоже самое, что и предыдущий, но параметры выводятся в столбик
$! — PID последнего запущенного в фоне процесса
$$ — PID самого скрипта

Условия

Условные операторы, думаю, знакомы практически каждому, кто хоть раз пытался на чем-то писать программы. В bash условия пишутся след. образом (как обычно на примере):

#!/bin/bash
#в переменную source засовываем первый параметр скрипта
source=$1
#в переменную dest засовываем второй параметр скрипта
dest=$2

# в ковычках указываем имена переменных для сравнения. -eq — логическое сравнение обозначающие «равны»
if [[ "$source" -eq "$dest" ]]
# если они действительно равны, то
then
#выводим сообщение об ошибке, т.к. $source и $dest у нас равны
echo "Применик $dest и источник $source один и тот же файл!"
# выходим с ошибкой (1 — код ошибки)
exit 1
# если же они не равны
else
# то выполняем команду cp: копируем источник в приемник
cp $source $dest
echo "Удачное копирование!"
fi #обозначаем окончание условия.

Результат выполнения скрипта:

ite@ite-desktop:~$ ./primer2.sh 1 1
Применик 1 и источник 1 один и тот же файл!

ite@ite-desktop:~$ ./primer2.sh 1 2
Удачное копирование!

Структура if-then-else используется следующим образом:

if <команда или набор команд возвращающих код возврата(0 или 1)>
then
<если выражение после if истино, то выполняется этот блок>
else
<если выражение после if ложно, тот этот>

В качестве команд возвращающих код возврата могут выступать структуры [[ , [ , test, (( )) или любая другая(или несколько) linux-команда.

test — используется для логического сравнения. после выражения, неоьбходима закрывающая скобка «]»
[ — синоним команды test
[[ — расширенная версия «[» (начиная с версии 2.02)(как в примере), внутри которой могут быть использованы || (или), & (и). Долна иметь закрывающуб скобку «]]»
(( )) — математическое сравнение.

для построения многоярусных условий вида:

if ...
then ....
else
if ....
then....
else ....

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

if ..
then ...
elif ...
then ...
elif ...

Условия. Множественный выбор

Если необходимо сравнивать какоую-то одну переменную с большим количеством параметров, то целесообразней использовать оператор case.

#!/bin/bash
echo "Выберите редатор для запуска:"
echo "1 Запуск программы nano"
echo "2 Запуск программы vi"
echo "3 Запуск программы emacs"
echo "4 Выход"
#здесь мы читаем в переменную $doing со стандартного ввода
read doing

case $doing in
1)
/usr/bin/nano # если $doing содержит 1, то запустить nano
;;
2)
/usr/bin/vi # если $doing содержит 2, то запустить vi
;;
3)
/usr/bin/emacs # если $doing содержит 3, то запустить emacs
;;
4)
exit 0
;;
*) #если введено с клавиатуры то, что в case не описывается, выполнять следующее:
echo "Введено неправильное действие"

esac #окончание оператора case.

Результат работы:

ite@ite-desktop:~$ ./menu2.sh
Выберите редатор для запуска:
1 Запуск программы nano
2 Запуск программы vi
3 Запуск программы emacs
4 Выход

После выбор цифры и нажатия Enter запуститься тот редактор, который вы выбрали(если конечно все пути указаны правильно, и у вас установлены эти редакторы :) )

Прведу список логических операторв, которые используются для конструкции if-then-else-fi:

-z # строка пуста
-n # строка не пуста
=, (==) # строки равны
!= # строки неравны
-eq # равно
-ne # неравно
-lt,(< ) # меньше
-le,(<=) # меньше или равно
-gt,(>) #больше
-ge,(>=) #больше или равно
! #отрицание логического выражения
-a,(&&) #логическое «И»
-o,(||) # логическое «ИЛИ»

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

Основы BASH. Часть 2

Циклы. Цикл for-in.

Оператор for-in предназначен для поочередного обращения к значениям перечисленным в списке. Каждое значение поочередно в списке присваивается переменной.
Синтаксис следующий:

for переменная in список_значений  
do  
команды  
done  

Рассмотрим небольшой пример:

#!/bin/bash  
for i in 0 1 2 3 4 #переменной $i будем поочередно присваивать значения от 0 до 4 включительно  
do  
echo "Console number is $i" >> /dev/pts/$i #Пишем в файл /dev/pts/$i(файл виртуального терминала) строку "Console number is $i"  
done #цикл окончен  
exit 0  

После выполнения примера в первых 5 виртуальных консолях(терминалах) появится строка с её номером. В переменную $i поочередно подставляются значения из списка и в цикле идет работа со значением этой переменной

Циклы. Цикл while.

Цикл while сложнее цикла for-in и используется для повторения команд, пока какое-то выражение истинно( код возврата = 0).
Синтаксис оператора следующий:

while выражение или команда возвращающая код возврата  
do  
команды  
done  

Пример работы цикла рассмотрим на следующем примере:

#!/bin/bash  
again=yes #присваиваем значение "yes" переменной again  
while [ "$again" = "yes" ] #Будем выполнять цикл, пока $again будет равно "yes"  
do  
echo "Please enter a name:"  
read name  
echo "The name you entered is $name"  
  
echo "Do you wish to continue?"  
read again  
done  
echo "Bye-Bye"  

А теперь результат работы скрипта:

ite@ite-desktop:~$ ./bash2_primer1.sh  
Please enter a name:  
ite  
The name you entered is ite  
Do you wish to continue?  
yes  
Please enter a name:  
mihail  
The name you entered is mihail  
Do you wish to continue?  
no  
Bye-Bye  

Как видим цикл выполняется до тех пор, пока мы не введем что-то отличное от «yes». Между do и done можно описывать любые структуры, операторы и т.п., все они будут выполнятся в цикле.Но следует быть осторожным с этим циклом, если вы запустите на выполнение в нём какую-либо команду, без изменения переменной выражения, вы можете попасть в бесконечный цикл.

Теперь об условии истинности. После while, как и в условном операторе if-then-else можно вставлять любое выражение или команду, которая возвращает код возврата, и цикл будет исполнятся до тех пор, пока код возврата = 0! Оператор [ аналог команды test, которая проверяет истинность условия, которое ей передали.

Рассмотрим еще один пример, я взял его из книги Advanced Bash Scripting. Уж очень он мне понравился :), но я его немного упростил. В этом примере мы познакомимся с еще одним типом циклов UNTIL-DO. Эта практически полный аналог цикла WHILE-DO, только выполняется пока какое-то выражение ложно.
Вот пример:

#!/bin/bash  
echo "Введите числитель: "  
read dividend  
echo "Введите знаменатель: "  
read divisor  
  
dnd=$dividend #мы будем изменять переменные dividend и divisor,  
#сохраним их знания в других переменных, т.к. они нам  
#понадобятся  
dvs=$divisor  
remainder=1  
  
until [ "$remainder" -eq 0 ]  
do  
let "remainder = dividend % divisor"  
dividend=$divisor  
divisor=$remainder  
done  
  
echo "НОД чисел $dnd и $dvs = $dividend"  

Результат выполнения скрипта:

ite@ite-desktop:~$ ./bash2_primer3.sh  
Введите числитель:  
100  
Введите знаменатель:  
90  
НОД чисел 100 и 90 = 10  

Математические операции

Команда let.
Команда let производит арифметические операции над числами и переменными.
Рассмотрим небольшой пример, в котором мы производим некоторые вычисления над введенными числами:

#!/bin/bash  
echo "Введите a: "  
read a  
echo "Введите b: "  
read b  
  
let "c = a + b" #сложение  
echo "a+b= $c"  
let "c = a / b" #деление  
echo "a/b= $c"  
let "c <<= 2" #сдвигает c на 2 разряда влево  
echo "c после сдвига на 2 разряда: $c"  
let "c = a % b" # находит остаток от деления a на b  
echo "$a / $b. остаток: $c "  

Результат выполнения:

ite@ite-desktop:~$ ./bash2_primer2.sh  
Введите a:  
123  
Введите b:  
12  
a+b= 135  
a/b= 10  
c после сдвига на 2 разряда: 40  
123 / 12. остаток: 3  

Ну вот, как видите ничего сложного, список математических операций стандартный:

+ — сложение
— вычитание
* — умножение
/ — деление
** — возведение в степень
% — модуль(деление по модулю), остаток от деления
let позволяет использовать сокращения арифметических команд, тем самым сокращая кол-во используемых переменных. Например: a = a+b эквивалентно a +=b и т.д

Работа с внешними программами при написании shell-скриптов

Для начала немного полезной теории.

Перенаправление потоков.

В bash (как и многих других оболочках) есть встроенные файловые дескрипторы: 0 (stdin), 1 (stdout), 2 (stderr).
stdout — Стандартный вывод. Сюда попадает все что выводят программы
stdin — Стандартный ввод. Это все что набирает юзер в консоли
stderr — Стандартный вывод ошибок.
Для операций с этими дескрипторами, существуют специальные символы: > (перенаправление вывода), < (перенаправление ввода). Оперировать ими не сложно. Например:

cat /dev/random > /dev/null #перенаправить вывод команды cat /dev/random в /dev/null (абсолютно бесполезная операция :)) )

или

ls -la > listing #записать в файл listing содержание текущего каталога (уже полезней)  

Если есть необходимость дописывать в файл(при использовании «>» он заменятеся), необходимо вместо «>» использовать «>>«

sudo < my_password

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

./program_with_error 2> error_file

цифра 2 перед «>» означает что нужно перенаправлять все что попадет в дескриптор 2(stderr).
Если необходимо заставить stderr писать в stdout, то это можно след. образом:

./program_with_error 2>&1

символ «&» означает указатель на дескриптор 1(stdout)
(Поумолчанию stderr пишет на ту консоль, в котрой работает пользователь(вренее пишет на дисплей)).

2. Конвееры.

Конвеер — очень мощный инструмент для работы с консолью Bash. Синтаксис простой:
команда1 | команда 2 — означает, что вывод команды 1 передастся на ввод команде 2
Конвееры можно группировать в цепочки и выводить с помощью перенаправления в файл, например:

ls -la | grep «hash» |sort > sortilg_list

вывод команды ls -la передается команде grep, которая отбирает все строки, в которых встретится слово hash, и передает команде сортировке sort, которая пишет результат в файл sorting_list. Все довольно понятно и просто.

Чаще всего скрипты на Bash используются в качестве автоматизации каких-то рутинных операций в консоли, отсюда иногда возникает необходимость в обработке stdout одной команды и передача на stdin другой команде, при этом результат выполнения одной команды должен быть неким образом обработан. В этом разделе я постораюсь объяснить основные принципы работы с внешними командами внутри скрипта. Думаю что примеров я привел достаточно и можно теперь писать только основные моменты.

1. Передача вывода в переменную.

Для того чтобы записать в переменную вывод какой-либо команды, достаточно заключить команду в `` ковычки, например

a = ` echo «qwerty» `
echo $a

Результат работы: qwerty

Однако если вы захотите записать в переменную список директорий, то необходимо, должным образом обработать результат для помещения данных в переменную. Рассмотрим небольшой, пример:

LIST=`find /svn/ -type d 2>/dev/null| awk '{FS="/"} {print $4}'| sort|uniq | tr 'n' ' '`  
for ONE_OF_LIST in $LIST  
do  
svnadmin hotcopy /svn/$ONE_OF_LIST /svn/temp4backup/$ONE_OF_LIST  
done  

Здесь мы используем цикл for-do-done для архивирование всех директорий в папке /svn/ с помощью команды svnadmin hotcopy(что в нашем случае не имеет никого значения, просто как пример). Наибольшй интерес вызывает строка: LIST=find /svn/ -type d 2>/dev/null| awk '{FS="/"} {print $4}'| sort|uniq | tr 'n' ' ' В ней переменной LIST присваивается выполнение команды find, обработанной командами awk, sort, uniq,tr(все эти команды мы рассматривать не будем, ибо это отдельная статья). В переменной LIST будут имена всех каталогов в папке /svn/ пгомещенных в одну строку(для того чтобы её стравить циклу.

Лабораторная
работа 10

Цель работы – практическое знакомство
с методами создания и использования
сценариев ОС Linux

  1. Краткие теоретические сведения

    1. Необходимость использования сценариев командной оболочки

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

Хотя внешне командная оболочка очень
похожа на режим командной строки в ОС
Windows, она гораздо мощнее
и способна выполнять самостоятельно
очень сложные программы. Командная
оболочка выполняет программы оболочки,
часто называемые сценариями или
скриптами, которые интерпретируются
во время выполнения. Такой подход
облегчает отладку, потому что можно
выполнять программу построчно и не
тратить время на перекомпиляцию. Но для
задач, которым важно время выполнения
или необходимо интенсивное использование
процессора, командная оболочка оказывается
неподходящей средой.

1.2 Командная оболочка

Командная оболочка — это программа,
которая действует как интерфейс между
пользователем и ОС Linux,
позволяя вводить команды, которые должна
выполнить операционная система. В ОСLinuxвполне может
сосуществовать несколько установленных
командных оболочек, и разные пользователи
могут выбрать ту, которая им больше
нравится. Поскольку ОСLinux— модульная система, можно вставить и
применять одну из множества различных
стандартных командных оболочек. ВLmuxстандартная командная оболочка, всегда
устанавливаемая как /bin/shи входящая в комплект средств проектаGNU, называетсяbash(GNUBourne-AgainSHell). В данной работе
используется оболочкаbashверсии 3, ее функциональные возможности
являются общими для всех командных
оболочек, удовлетворяющих требованиям
стандартаPOSIX.

Рис. 1. Укрупненная архитектура ОС Linux

Каналы и перенаправление

Прежде чем заняться подробностями
программ командной оболочки, необходимо
сказать несколько слов о возможностях
перенаправления ввода и вывода программ
(не только программ командной оболочки)
в ОС Linux.

Перенаправление вывода

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

$ ls-l>lsoutput.txt

сохраняющие вывод команды lsв файле с именемlsoutput.txt.

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

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

$ ps>>lsoutput.txt

добавит вывод команды psв конец заданного файла. В этом примере
и далее знак $ перед командой – приглашение
ОСLinux.

Для перенаправления стандартного потока
ошибок перед оператором > вставьте
номер дескриптора файла, который хотите
перенаправить. Поскольку у стандартного
потока ошибок дескриптор файла 2, укажите
оператор 2>. Часто бывает полезно
скрывать стандартный поток ошибок,
запрещая вывод его на экран.

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

Команда $ kill -HUP 1234 > killout.txt
2>killer.txt

поместит вывод и информацию об ошибке
в разные файлы.

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

$ kill-1 1234 >killerr.txt2>41

поместит свой вывод и стандартный поток
ошибок в один и тот же файл. Обратите
внимание на порядок следования операторов.
Приведенный пример читается как
«перенаправить стандартный вывод в
файл killerr.txt,
а затем перенаправить стандартный поток
ошибок туда же, куда и стандартный
вывод». Если вы нарушите порядок,
перенаправление выполнится не так, как
вы ожидаете.

Поскольку обнаружить результат выполнения
команды killможно с помощью
кода завершения, часто не потребуется
сохранять какой бы то ни было стандартный
вывод или стандартный поток ошибок. Для
того чтобы полностью отбросить любой
вывод, можно использовать универсальную
«мусорную корзину»Linux,
/dev/null,
следующим образом:

$ kill-1 1234 >/dev/null2>fil

Перенаправление ввода

Также как вывод можно перенаправить
ввод. Например $ more<killout.txt

Каналы

Процессы можно соединять с помощью
оператора канала | . Как пример, можно
применить команду sortдля
сортировки вывода командыps.

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

$ ps > psout.txt

$ sort psout.txt > pasoirt.out

Соединение процессов каналом даст более
элегантное решение:

$ ps|sort>pssort.out

При желании увидеть на экране вывод,
разделенный на страницы, можно подсоединить
третий процесс, more:

$ ps|sort|more

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

$ ps-xоcomm|sort|uniq|grep-vsh|more

В ней берется вывод команды ps,
сортируется в алфавитном порядке, из
него извлекаются процессы с помощью
командыuniq, применяется
утилитаgrep-vshдля удаления процесса
с именемshи в завершение
полученный список постранично выводится
на экран. Это более элегантное решение,
чем строка из отдельных команд, каждая
со своими временными файлами.

Соседние файлы в папке ОС 2013 2к ДО

  • #
  • #
  • #
  • #
  • #
  • #
  • #

Shell scripting is an important part of process automation in Linux. Scripting helps you write a sequence of commands in a file and then execute them.

This saves you time because you don’t have to write certain commands again and again. You can perform daily tasks efficiently and even schedule them for automatic execution.

You can also set certain scripts to execute on startup such as showing a particular message on launching a new session or setting certain environment variables.

The applications and uses of scripting are numerous, so let’s dive in.

In this article, you will learn:

  1. What is a bash shell?
  2. What is a bash script and how do you identify it?
  3. How to create your first bash script and execute it.
  4. The basic syntax of shell scripting.
  5. How to see a system’s scheduled scripts.
  6. How to automate scripts by scheduling via cron jobs.

The best way to learn is by practicing. I highly encourage you to follow along using Replit. You can access a running Linux shell within minutes.

Introduction to the Bash Shell

The Linux command line is provided by a program called the shell. Over the years, the shell program has evolved to cater to various options.

Different users can be configured to use different shells. But most users prefer to stick with the current default shell. The default shell for many Linux distros is the GNU Bourne-Again Shell (bash). Bash is succeeded by Bourne shell (sh).

When you first launch the shell, it uses a startup script located in the .bashrc or .bash_profile file which allows you to customize the behavior of the shell.

When a shell is used interactively, it displays a $ when it is waiting for a command from the user. This is called the shell prompt.

[username@host ~]$

If shell is running as root, the prompt is changed to #. The superuser shell prompt looks like this:

[root@host ~]#

Bash is very powerful as it can simplify certain operations that are hard to accomplish efficiently with a GUI. Remember that most servers do not have a GUI, and it is best to learn to use the powers of a command line interface (CLI).

What is a Bash Script?

A bash script is a series of commands written in a file. These are read and executed by the bash program. The program executes line by line.

For example, you can navigate to a certain path, create a folder and spawn a process inside it using the command line.

You can do the same sequence of steps by saving the commands in a bash script and running it. You can run the script any number of times.

How Do You Identify a Bash Script?

File extension of .sh.

By naming conventions, bash scripts end with a .sh. However, bash scripts can run perfectly fine without the sh extension.

Scripts start with a bash bang.

Scripts are also identified with a shebang. Shebang is a combination of bash # and bang !  followed the the bash shell path. This is the first line of the script. Shebang tells the shell to execute it via bash shell. Shebang is simply an absolute path to the bash interpreter.

Below is an example of the shebang statement.

#! /bin/bash

The path of the bash program can vary. We will see later how to identify it.

Execution rights

Scripts have execution rights for the user executing them.

An execution right is represented by x. In the example below, my user has the rwx (read, write, execute) rights for the file test_script.sh

image-98

File colour

Executable scripts appear in a different colour from rest of the files and folders.

In my case, the scripts with execution rights appear as green.

image-99

How to Create Your First Bash Script

Let’s create a simple script in bash that outputs Hello World.

Create a file named hello_world.sh

touch hello_world.sh

Find the path to your bash shell.

which bash

image-100

In my case, the path is /usr/bin/bash and I will include this in the shebang.

Write the command.

We will echo «hello world» to the console.

Our script will look something like this:

#! usr/bin/bash
echo "Hello World"

Edit the file hello_world.sh using a text editor of your choice and add the above lines in it.

Provide execution rights to your user.

Modify the file permissions and allow execution of the script by using the command below:

chmod u+x hello_world.sh

chmod modifies the existing rights of a file for a particular user. We are adding +x to user u.

Run the script.

You can run the script in the following ways:

./hello_world.sh

bash hello_world.sh.

Here’s the output:

Two ways to run scripts

Two ways to run scripts

The Basic Syntax of Bash Scripting

Just like any other programming language, bash scripting follows a set of rules to create programs understandable by the computer. In this section, we will study the syntax of bash scripting.

How to define variables

We can define a variable by using the syntax variable_name=value. To get the value of the variable, add $ before the variable.

#!/bin/bash
# A simple variable example
greeting=Hello
name=Tux
echo $greeting $name

image-104

Tux is also the name of the Linux mascot, the penguin.

Hi, I am Tux.

Hi, I am Tux.

Arithmetic Expressions

Below are the operators supported by bash for mathematical calculations:

Operator Usage
+ addition
subtraction
* multiplication
/ division
** exponentiation
% modulus

Let’s run a few examples.

Note the spaces, these are part of the syntax

Note the spaces, these are part of the syntax

Numerical expressions can also be calculated and stored in a variable using the syntax below:

var=$((expression))

Let’s try an example.

#!/bin/bash

var=$((3+9))
echo $var

image-109

Fractions are not correctly calculated using the above methods and truncated.

For decimal calculations, we can use bc command to get the output to a particular number of decimal places. bc (Bash Calculator) is a command line calculator that supports calculation up to a certain number of decimal points.

echo "scale=2;22/7" | bc

Where scale defines the number of decimal places required in the output.

Getting output to 2 decimal places

Getting output to 2 decimal places

How to read user input

Sometimes you’ll need to gather user input and perform relevant operations.

In bash, we can take user input using the read command.

read variable_name

To prompt the user with a custom message, use the -p flag.

read -p "Enter your age" variable_name

Example:

#!/bin/bash

echo "Enter a numner"
read a

echo "Enter a numner"
read b

var=$((a+b))
echo $var

image-111

Numeric Comparison logical operators

Comparison is used to check if statements evaluate to true or false. We can use the below shown operators to compare two statements:

Operation Syntax Explanation
Equality num1 -eq num2 is num1 equal to num2
Greater than equal to num1 -ge num2 is num1 greater than equal to num2
Greater than num1 -gt num2 is num1 greater than num2
Less than equal to num1 -le num2 is num1 less than equal to num2
Less than num1 -lt num2 is num1 less than num2
Not Equal to num1 -ne num2 is num1 not equal to num2

Syntax:

if [ conditions ]
    then
         commands
fi

Example:

Let’s compare two numbers and find their relationship:

read x
read y

if [ $x -gt $y ]
then
echo X is greater than Y
elif [ $x -lt $y ]
then
echo X is less than Y
elif [ $x -eq $y ]
then
echo X is equal to Y
fi

Output:

image-112

Conditional Statements (Decision Making)

Conditions are expressions that evaluate to a boolean expression (true or false). To check conditions, we can use if, if-else, if-elif-else and nested conditionals.

The structure of conditional statements is as follows:

  • if...then...fi statements
  • if...then...else...fi statements
  • if..elif..else..fi
  • if..then..else..if..then..fi..fi.. (Nested Conditionals)

Syntax:

if [[ condition ]]
then
	statement
elif [[ condition ]]; then
	statement 
else
	do this by default
fi

To create meaningful comparisons, we can use AND -a and OR -o as well.

The below statement translates to: If a is greater than 40 and b is less than 6.

if [ $a -gt 40 -a $b -lt 6 ]

Example: Let’s find the triangle type by reading the lengths of its sides.

read a
read b
read c

if [ $a == $b -a $b == $c -a $a == $c ]
then
echo EQUILATERAL

elif [ $a == $b -o $b == $c -o $a == $c ]
then 
echo ISOSCELES
else
echo SCALENE

fi

Output:

Test case #1

image-113

Test case #2

image-114

Test case #3

image-115

Looping and skipping

For loops allow you to execute statements a specific number of times.

Looping with numbers:

In the example below, the loop will iterate 5 times.

#!/bin/bash

for i in {1..5}
do
    echo $i
done

Looping-with-numbers

Looping with strings:

We can loop through strings as well.

#!/bin/bash

for X in cyan magenta yellow  
do
	echo $X
done

Looping-with-strings

While loop

While loops check for a condition and loop until the condition remains true. We need to provide a counter statement that increments the counter to control loop execution.

In the example below, (( i += 1 )) is the counter statement that increments the value of i.

Example:

#!/bin/bash
i=1
while [[ $i -le 10 ]] ; do
   echo "$i"
  (( i += 1 ))
done

image-153

Reading files

Suppose we have a file sample_file.txt as shown below:

image-151

We can read the file line by line and print the output on the screen.

#!/bin/bash

LINE=1

while read -r CURRENT_LINE
	do
		echo "$LINE: $CURRENT_LINE"
    ((LINE++))
done < "sample_file.txt"

Output:

Lines with line number printed

Lines with line number printed

How to execute commands with back ticks

If you need to include the output of a complex command in your script, you can write the statement inside back ticks.

Syntax:

var= ` commands `

Example: Suppose we want to get the output of a list of mountpoints with tmpfs in their name. We can craft a statement like this: df -h | grep tmpfs.

To include it in the bash script, we can enclose it in back ticks.

#!/bin/bash

var=`df -h | grep tmpfs`
echo $var

Output:

image-118

How to get arguments for scripts from the command line

It is possible to give arguments to the script on execution.

$@ represents the position of the parameters, starting from one.

#!/bin/bash

for x in $@
do
    echo "Entered arg is $x"
done

Run it like this:

./script arg1 arg2

image-155

How to Automate Scripts by Scheduling via cron Jobs

Cron is a job scheduling utility present in Unix like systems. You can schedule jobs to execute daily, weekly, monthly or in a specific time of the day. Automation in Linux heavily relies on cron jobs.

Below is the syntax to schedule crons:

# Cron job example
* * * * * sh /path/to/script.sh

Here, * represent represents minute(s) hour(s) day(s) month(s) weekday(s), respectively.

Below are some examples of scheduling cron jobs.

SCHEDULE SCHEDULED VALUE
5 0 * 8 * At 00:05 in August.
5 4 * * 6 At 04:05 on Sunday.
0 22 * * 1-5 At 22:00 on every day-of-week from Monday through Friday.

You can learn about cron in detail in this blog post.

How to Check Existing Scripts in a System

Using crontab

crontab -l lists the already scheduled scripts for a particular user.

My scheduled scripts

My scheduled scripts

Using the find command

The find command helps to locate files based on certain patterns. As most of the scripts end with .sh, we can use the find script like this:

find . -type f -name "*.sh"
`

Where,

  • . represents the current directory. You can change the path accordingly.
  • -type f indicates that the file type we are looking for is a text based file.
  • *.sh tells to match all files ending with .sh.

image-159

If you are interested to read about the find command in detail, check my other post.

Wrapping up

In this tutorial we learned the basics of shell scripting. We looked into examples and syntax which can help us write meaningful programs.

What’s your favorite thing you learned from this tutorial? Let me know on Twitter!

You can read my other posts here.

Work vector created by macrovector — www.freepik.com

Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Shell scripting is an important part of process automation in Linux. Scripting helps you write a sequence of commands in a file and then execute them.

This saves you time because you don’t have to write certain commands again and again. You can perform daily tasks efficiently and even schedule them for automatic execution.

You can also set certain scripts to execute on startup such as showing a particular message on launching a new session or setting certain environment variables.

The applications and uses of scripting are numerous, so let’s dive in.

In this article, you will learn:

  1. What is a bash shell?
  2. What is a bash script and how do you identify it?
  3. How to create your first bash script and execute it.
  4. The basic syntax of shell scripting.
  5. How to see a system’s scheduled scripts.
  6. How to automate scripts by scheduling via cron jobs.

The best way to learn is by practicing. I highly encourage you to follow along using Replit. You can access a running Linux shell within minutes.

Introduction to the Bash Shell

The Linux command line is provided by a program called the shell. Over the years, the shell program has evolved to cater to various options.

Different users can be configured to use different shells. But most users prefer to stick with the current default shell. The default shell for many Linux distros is the GNU Bourne-Again Shell (bash). Bash is succeeded by Bourne shell (sh).

When you first launch the shell, it uses a startup script located in the .bashrc or .bash_profile file which allows you to customize the behavior of the shell.

When a shell is used interactively, it displays a $ when it is waiting for a command from the user. This is called the shell prompt.

[username@host ~]$

If shell is running as root, the prompt is changed to #. The superuser shell prompt looks like this:

[root@host ~]#

Bash is very powerful as it can simplify certain operations that are hard to accomplish efficiently with a GUI. Remember that most servers do not have a GUI, and it is best to learn to use the powers of a command line interface (CLI).

What is a Bash Script?

A bash script is a series of commands written in a file. These are read and executed by the bash program. The program executes line by line.

For example, you can navigate to a certain path, create a folder and spawn a process inside it using the command line.

You can do the same sequence of steps by saving the commands in a bash script and running it. You can run the script any number of times.

How Do You Identify a Bash Script?

File extension of .sh.

By naming conventions, bash scripts end with a .sh. However, bash scripts can run perfectly fine without the sh extension.

Scripts start with a bash bang.

Scripts are also identified with a shebang. Shebang is a combination of bash # and bang !  followed the the bash shell path. This is the first line of the script. Shebang tells the shell to execute it via bash shell. Shebang is simply an absolute path to the bash interpreter.

Below is an example of the shebang statement.

#! /bin/bash

The path of the bash program can vary. We will see later how to identify it.

Execution rights

Scripts have execution rights for the user executing them.

An execution right is represented by x. In the example below, my user has the rwx (read, write, execute) rights for the file test_script.sh

image-98

File colour

Executable scripts appear in a different colour from rest of the files and folders.

In my case, the scripts with execution rights appear as green.

image-99

How to Create Your First Bash Script

Let’s create a simple script in bash that outputs Hello World.

Create a file named hello_world.sh

touch hello_world.sh

Find the path to your bash shell.

which bash

image-100

In my case, the path is /usr/bin/bash and I will include this in the shebang.

Write the command.

We will echo «hello world» to the console.

Our script will look something like this:

#! usr/bin/bash
echo "Hello World"

Edit the file hello_world.sh using a text editor of your choice and add the above lines in it.

Provide execution rights to your user.

Modify the file permissions and allow execution of the script by using the command below:

chmod u+x hello_world.sh

chmod modifies the existing rights of a file for a particular user. We are adding +x to user u.

Run the script.

You can run the script in the following ways:

./hello_world.sh

bash hello_world.sh.

Here’s the output:

Two ways to run scripts

Two ways to run scripts

The Basic Syntax of Bash Scripting

Just like any other programming language, bash scripting follows a set of rules to create programs understandable by the computer. In this section, we will study the syntax of bash scripting.

How to define variables

We can define a variable by using the syntax variable_name=value. To get the value of the variable, add $ before the variable.

#!/bin/bash
# A simple variable example
greeting=Hello
name=Tux
echo $greeting $name

image-104

Tux is also the name of the Linux mascot, the penguin.

Hi, I am Tux.

Hi, I am Tux.

Arithmetic Expressions

Below are the operators supported by bash for mathematical calculations:

Operator Usage
+ addition
subtraction
* multiplication
/ division
** exponentiation
% modulus

Let’s run a few examples.

Note the spaces, these are part of the syntax

Note the spaces, these are part of the syntax

Numerical expressions can also be calculated and stored in a variable using the syntax below:

var=$((expression))

Let’s try an example.

#!/bin/bash

var=$((3+9))
echo $var

image-109

Fractions are not correctly calculated using the above methods and truncated.

For decimal calculations, we can use bc command to get the output to a particular number of decimal places. bc (Bash Calculator) is a command line calculator that supports calculation up to a certain number of decimal points.

echo "scale=2;22/7" | bc

Where scale defines the number of decimal places required in the output.

Getting output to 2 decimal places

Getting output to 2 decimal places

How to read user input

Sometimes you’ll need to gather user input and perform relevant operations.

In bash, we can take user input using the read command.

read variable_name

To prompt the user with a custom message, use the -p flag.

read -p "Enter your age" variable_name

Example:

#!/bin/bash

echo "Enter a numner"
read a

echo "Enter a numner"
read b

var=$((a+b))
echo $var

image-111

Numeric Comparison logical operators

Comparison is used to check if statements evaluate to true or false. We can use the below shown operators to compare two statements:

Operation Syntax Explanation
Equality num1 -eq num2 is num1 equal to num2
Greater than equal to num1 -ge num2 is num1 greater than equal to num2
Greater than num1 -gt num2 is num1 greater than num2
Less than equal to num1 -le num2 is num1 less than equal to num2
Less than num1 -lt num2 is num1 less than num2
Not Equal to num1 -ne num2 is num1 not equal to num2

Syntax:

if [ conditions ]
    then
         commands
fi

Example:

Let’s compare two numbers and find their relationship:

read x
read y

if [ $x -gt $y ]
then
echo X is greater than Y
elif [ $x -lt $y ]
then
echo X is less than Y
elif [ $x -eq $y ]
then
echo X is equal to Y
fi

Output:

image-112

Conditional Statements (Decision Making)

Conditions are expressions that evaluate to a boolean expression (true or false). To check conditions, we can use if, if-else, if-elif-else and nested conditionals.

The structure of conditional statements is as follows:

  • if...then...fi statements
  • if...then...else...fi statements
  • if..elif..else..fi
  • if..then..else..if..then..fi..fi.. (Nested Conditionals)

Syntax:

if [[ condition ]]
then
	statement
elif [[ condition ]]; then
	statement 
else
	do this by default
fi

To create meaningful comparisons, we can use AND -a and OR -o as well.

The below statement translates to: If a is greater than 40 and b is less than 6.

if [ $a -gt 40 -a $b -lt 6 ]

Example: Let’s find the triangle type by reading the lengths of its sides.

read a
read b
read c

if [ $a == $b -a $b == $c -a $a == $c ]
then
echo EQUILATERAL

elif [ $a == $b -o $b == $c -o $a == $c ]
then 
echo ISOSCELES
else
echo SCALENE

fi

Output:

Test case #1

image-113

Test case #2

image-114

Test case #3

image-115

Looping and skipping

For loops allow you to execute statements a specific number of times.

Looping with numbers:

In the example below, the loop will iterate 5 times.

#!/bin/bash

for i in {1..5}
do
    echo $i
done

Looping-with-numbers

Looping with strings:

We can loop through strings as well.

#!/bin/bash

for X in cyan magenta yellow  
do
	echo $X
done

Looping-with-strings

While loop

While loops check for a condition and loop until the condition remains true. We need to provide a counter statement that increments the counter to control loop execution.

In the example below, (( i += 1 )) is the counter statement that increments the value of i.

Example:

#!/bin/bash
i=1
while [[ $i -le 10 ]] ; do
   echo "$i"
  (( i += 1 ))
done

image-153

Reading files

Suppose we have a file sample_file.txt as shown below:

image-151

We can read the file line by line and print the output on the screen.

#!/bin/bash

LINE=1

while read -r CURRENT_LINE
	do
		echo "$LINE: $CURRENT_LINE"
    ((LINE++))
done < "sample_file.txt"

Output:

Lines with line number printed

Lines with line number printed

How to execute commands with back ticks

If you need to include the output of a complex command in your script, you can write the statement inside back ticks.

Syntax:

var= ` commands `

Example: Suppose we want to get the output of a list of mountpoints with tmpfs in their name. We can craft a statement like this: df -h | grep tmpfs.

To include it in the bash script, we can enclose it in back ticks.

#!/bin/bash

var=`df -h | grep tmpfs`
echo $var

Output:

image-118

How to get arguments for scripts from the command line

It is possible to give arguments to the script on execution.

$@ represents the position of the parameters, starting from one.

#!/bin/bash

for x in $@
do
    echo "Entered arg is $x"
done

Run it like this:

./script arg1 arg2

image-155

How to Automate Scripts by Scheduling via cron Jobs

Cron is a job scheduling utility present in Unix like systems. You can schedule jobs to execute daily, weekly, monthly or in a specific time of the day. Automation in Linux heavily relies on cron jobs.

Below is the syntax to schedule crons:

# Cron job example
* * * * * sh /path/to/script.sh

Here, * represent represents minute(s) hour(s) day(s) month(s) weekday(s), respectively.

Below are some examples of scheduling cron jobs.

SCHEDULE SCHEDULED VALUE
5 0 * 8 * At 00:05 in August.
5 4 * * 6 At 04:05 on Sunday.
0 22 * * 1-5 At 22:00 on every day-of-week from Monday through Friday.

You can learn about cron in detail in this blog post.

How to Check Existing Scripts in a System

Using crontab

crontab -l lists the already scheduled scripts for a particular user.

My scheduled scripts

My scheduled scripts

Using the find command

The find command helps to locate files based on certain patterns. As most of the scripts end with .sh, we can use the find script like this:

find . -type f -name "*.sh"
`

Where,

  • . represents the current directory. You can change the path accordingly.
  • -type f indicates that the file type we are looking for is a text based file.
  • *.sh tells to match all files ending with .sh.

image-159

If you are interested to read about the find command in detail, check my other post.

Wrapping up

In this tutorial we learned the basics of shell scripting. We looked into examples and syntax which can help us write meaningful programs.

What’s your favorite thing you learned from this tutorial? Let me know on Twitter!

You can read my other posts here.

Work vector created by macrovector — www.freepik.com

Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

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

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

Основы скриптов

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

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

Простейший пример скрипта для командной оболочки Bash:

#!/bin/bash
echo "Hello world"

bash1

Утилита echo выводит строку, переданную ей в параметре на экран. Первая строка особая, она задает программу, которая будет выполнять команды. Вообще говоря, мы можем создать скрипт на любом другом языке программирования и указать нужный интерпретатор, например, на python:

#!/usr/bin/env python
print("Hello world")

Или на PHP:

#!/usr/bin/env php
echo "Hello world";

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

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

Чтобы сделать файл исполняемым в linux выполните:

chmod ugo+x файл_скрипта

Теперь выполняем нашу небольшую первую программу:

./файл_скрипта

bash

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

Переменные в скриптах

Написание скриптов на Bash редко обходится без сохранения временных данных, а значит создания переменных. Без переменных не обходится ни один язык программирования и наш примитивный язык командной оболочки тоже.

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

Например, объявим переменную string:

string="Hello world"

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

Чтобы вывести значение переменной используется символ $. Например:

echo $string

Модифицируем наш скрипт:

#!/bin/bash
string1="hello "
string2=world
string=$string1$string2
echo $string

И проверяем:

./script

Hello world

Bash не различает типов переменных так, как языки высокого уровня, например, С++, вы можете присвоить переменной как число, так и строку. Одинаково все это будет считаться строкой. Оболочка поддерживает только слияние строк, для этого просто запишите имена переменных подряд:

#!/bin/bash
string1="hello "
string2=world
string=$string1$string2 and me
string3=$string1$string2" and me"
echo $string3

bash2

Проверяем:

./script

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

Переменные и вывод команд

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

$(команда)

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

date

echo $(date)

bash3

Понимаете? Напишем скрипт, где будет выводиться hello world и дата:

#!/bin/bash
string1="hello world "
string2=$(date)
string=$string1$string2
echo $string

bash4

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

Параметры скрипта

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

Переменная с именем 1 содержит значение первого параметра, переменная 2, второго и так далее. Этот bash скрипт выведет значение первого параметра:

#!/bin/bash
echo $1

bash6

bash5

Управляющие конструкции в скриптах

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

В Bash для проверки условий есть команда Синтаксис ее такой:

if команда_условие
then
команда
else
команда
fi

Эта команда проверяет код завершения команды условия, и если 0 (успех) то выполняет команду или несколько команд после слова then, если код завершения 1 выполняется блок else, fi означает завершение блока команд.

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

[[ параметр1 оператор параметр2 ]]

Для сравнения используются уже привычные нам операторы <,>,=,!= и т д. Если выражение верно, команда вернет 0, если нет — 1. Вы можете немного протестировать ее поведение в терминале. Код возврата последней команды хранится в переменной $?:

bash7

Теперь объединением все это и получим скрипт с условным выражением:

#!/bin/bash
if [[ $1 > 2 ]]
then
echo $1" больше 2"
else
echo $1" меньше 2 или 2"
fi

bash8

bash9

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

Циклы в скриптах

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

Первым рассмотрим цикл for. Вот его синтаксис:

for переменная in список
do
команда
done

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

Например, переберем пять цифр:

#!/bin/bash
for index in 1 2 3 4 5
do
echo $index
done

bash10

bash11

Или вы можете перечислить все файлы из текущей директории:

for file in $(ls -l); do echo "$file"; done

bash12

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

Второй цикл, который мы рассмотрим — это цикл while, он выполняется пока команда условия возвращает код 0, успех. Рассмотрим синтаксис:

while команда условие
do
команда
done

Рассмотрим пример:

#!/bin/bash
index=1
while [[ $index < 5 ]]
do
echo $index
let "index=index+1"
done

bash14

bash13

Как видите, все выполняется, команда let просто выполняет указанную математическую операцию, в нашем случае увеличивает значение переменной на единицу.

Хотелось бы отметить еще кое-что. Такие конструкции, как while, for, if рассчитаны на запись в несколько строк, и если вы попытаетесь их записать в одну строку, то получите ошибку. Но тем не менее это возможно, для этого там, где должен быть перевод строки ставьте точку с запятой «;». Например, предыдущий цикл можно было выполнить в виде одной строки:

index=1; while [[ $index < 5 ]]; do echo $index; let "index=index+1"; done;

Все очень просто я пытался не усложнять статью дополнительными терминами и возможностями bash, только самое основное. В некоторых случаях, возможно, вам понадобиться сделать gui для bash скрипта, тогда вы можете использовать такие программы как zenity или kdialog, с помощью них очень удобно выводить сообщения пользователю и даже запрашивать у него информацию.

Выводы

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

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

Глубокое погружение в сценарии Bash, которые помогут вам автоматизировать задачи

[Обновлено 2021–02-18. Код изменен на Gist и добавлены ссылки]

Вступление

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

В этой статье мы рассмотрим базовые сценарии Bash для начинающих и создадим простые исполняемые сценарии.

Давайте погрузимся в сценарии Bash!

Table of Contents
· Introduction
· Setting Things Up
  ∘ Mac
  ∘ The bin directory
· VSCode Extensions
· Getting Started
  ∘ Shebang
  ∘ Comment
· Variables
  ∘ Variable assignment
  ∘ Environment variables
  ∘ Internal variables
  ∘ Assigning the command output to a variable
  ∘ Built-in commands
· Tests
  ∘ if statement
  ∘ Spaces Matter
  ∘ Test file expressions
  ∘ Test string expressions
  ∘ Test integer expressions
  ∘ Double parentheses
· How To Use if/else and if/elif/else Statements
· Double Brackets
· How To Use for Loops
  ∘ Using a for loop to rename files
· How To Use Parameters
· How To Accept User Input
· Brace Expansion Using Ranges
· How To Use While Loops
· What Are Exit Status/Return Codes?
  ∘ Checking the exit status
· How To Connect Commands
  ∘ Logical operators and the command exit status
  ∘ Exit command
  ∘ Logical AND (&&)
  ∘ Logical OR (||)
  ∘ The semicolon
  ∘ Pipe |
· Functions
  ∘ Function parameters
· Variable Scope
  ∘ Local variables
· Function Exit Status
· Checklist
· Conclusion
  ∘ Newsletter
  ∘ References

Настройка вещей

Mac

Вы можете проверить свою версию Bash:

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)
Copyright (C) 2007 Free Software Foundation, Inc.

Давайте обновим версию Bash:

$ brew install bash

Вы можете перечислить все найденные экземпляры исполняемых файлов.

$ which -a bash
/usr/local/bin/bash
/bin/bash

Давайте проверим только что установленную версию:

$ /usr/local/bin/bash --version
GNU bash, version 5.0.18(1)-release (x86_64-apple-darwin19.5.0)
Copyright (C) 2019 Free Software Foundation, Inc.
...

Давайте узнаем, какую версию Bash вы используете:

$ which bash
/usr/local/bin/bash
# or
$ type bash
bash is /usr/local/bin/bash

Если это не сработает, вам нужно экспортировать путь Bash в свой ~/.bashrc (или ~/.zshrc для пользователей Zsh).

export PATH="/usr/local/bin:$PATH"

Откройте новую вкладку терминала или перезапустите терминал и проверьте версию Bash.

$ bash --version
GNU bash, version 5.0.18(1)-release (x86_64-apple-darwin19.5.0)
Copyright (C) 2019 Free Software Foundation, Inc.
...

Добавьте /usr/local/bin/bash в /etc/shells в качестве доверенной оболочки.

$ vim /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/bash

Проверьте версию Bash в сценарии Bash. Мы узнаем, как запустить этот скрипт позже.

#!/usr/local/bin/bash
echo $BASH_VERSION

Попался Mac
Mac использует Zsh в качестве оболочки по умолчанию. Например, echo $BASH_VERSION не будет работать на терминале. Он работает из сценария оболочки, если вы используете #!/bin/bash.

Запуск Linux на Mac
Вы можете использовать Multipass для запуска Ubuntu на Mac / Windows. Эта статья поможет вам начать работу. Альтернатива — использование Docker и использование образов Linux.

Каталог bin

Давайте создадим каталог и добавим путь к файлу конфигурации терминала (.bashrc, .zshrc). Сделав это, вы можете запустить свой сценарий как myscript, а не как ./myscript.

В своем домашнем каталоге создайте каталог bin:

$ mkdir bin

Добавьте путь к этому каталогу в файле конфигурации вашего терминала. (либо .bashrc, либо .zshrc)

export PATH="$PATH:$HOME/bin"

Перезагрузите файл конфигурации:

# for .zshrc
$ . ~/.zshrc 
# or
$ source ~/.zshrc
# for .bashrc
$ . ~/.bashrc
# or
$ source ~/.bashrc

Мы будем создавать все наши скрипты в этом bin каталоге.

Совет по многопроходности
Вы можете подключить локальный каталог к ​​своему Многопроходному экземпляру и экспортировать PATH в ~/.bashrc.

Расширения VSCode

Если вы используете VSCode, я рекомендую расширения shellcheck [2] и shell-format [3]. shellcheck добавляет линтер для сценариев оболочки для Bash, Zsh и sh. shell-format — это формат документа shellscript.

Начиная

Расширение .sh используется по соглашению, но оно не обязательно. Создайте файл с именем myscript:

$ cd ~/bin
# create a empty file
$ > myscript
# or
$ touch myscript

Затем добавьте следующее:

Нам нужно сделать файл исполняемым. В терминале:

$ chmod 755 myscript

Если вы добавили каталог bin в файл конфигурации вашего терминала (~/.bashrc или ~/.zshrc), вы можете запустить его как:

$ myscript
Welcome to Shell Scripting.

Шебанг

Синтаксис #! в начале сценария указывает на интерпретатор для выполнения в операционных системах UNIX / Linux.

#!/bin/bash
echo "I use the newest bash interpreter."
---
#!/bin/csh
echo "use csh interpreter."
---
#!/bin/ksh
echo "use ksh interpreter."
---
#!/bin/zsh
echo "use zsh interpreter."

Используйте один из выходов из which -a bash. Если ваш Bash отсутствует в каталоге /bin, вы также можете использовать #!/usr/bin/env bash.

Комментарий

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

#!/bin/bash
# This is a bash comment.
echo "Hi"

Переменные

Переменные Bash чувствительны к регистру, и использование их имен в верхнем регистре является соглашением. Но вы можете использовать имя в нижнем регистре или смешивать регистры. Имя переменной может содержать только буквы (a-z или A-Z); числа (0-9); или символ подчеркивания (_), начинающийся с буквы. Не начинайте их с цифры и без пробелов до и после символа =.

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

# valid
FIRSTLETTERS="ABC"
FIRST_THREE_LETTERS="ABC"
firstThreeLetters="ABC"
MY_SHELL="bash"
my_another_shell="my another shell"
My_Shell="My shell"
# Invalid
3LETTERS="ABC"
first-three-letters="ABC"
[email protected]@Letters="ABC"
ABC = "ABC "
MY_SHELL = "bash"
My-SHELL="bash"
1MY_SHELL="My shell"

Если вы используете буквы до / после переменной, используйте {}:

Назначение переменной

Двойные кавычки сохраняют буквальное значение внутри кавычек, за исключением $, ` и . Знак доллара и обратная кавычка сохраняют свое особое значение в двойных кавычках, а обратная косая черта является escape-символом.

Одиночные кавычки сохраняют буквальное значение внутри кавычек.

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

Информация о переменных среды Linux хранится в системе. Глобальные переменные также называются переменными среды.

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

$ env
# or
$ printenv

Вы можете использовать эти переменные в своем скрипте:

#!/bin/bash
echo $SHELL, $USER, $HOME 
# /bin/zsh, shinokada, /Users/shinokada

Внутренние переменные

Существуют зарезервированные переменные оболочки Bourne, зарезервированные переменные Bash и специальные переменные Bash. [1]

Назначение вывода команды переменной

Вы можете использовать $(command) для сохранения вывода команды в переменной. Например, вы можете вывести ls -l:

#!/bin/bash
# file name ex1
LIST=$(ls -l)
echo "File information: $LIST"

Запустите его в своем терминале (не забудьте сделать файл исполняемым).

$ ex1
File information total 40
-rwxr-xr-x  1 shinokada  staff   272 Oct 27 08:52 ex1
-rwxr-xr-x  1 shinokada  staff     0 Oct 26 14:14 ex2
...

Следующее позволит сохранить время и дату, имя пользователя и время безотказной работы системы в файле журнала. > — это одна из переадресаций, при которой файл будет перезаписан. Вы можете использовать >> для добавления результатов в файл.

#!/bin/bash
DATE=$(date -u) # date and time, -u option gives the UTC
WHO=$(whoami) # user name
UPTIME=$(uptime) # shows how long the system has been running
echo "Today is $DATE. You are $WHO. Uptime info: $UPTIME" > logfile

Встроенные команды

Встроенные команды оболочки — это команды, которые можно запускать в оболочке. Вы можете найти встроенные команды:

$ compgen -b | sort
-
.
:
[
alias
autoload
bg
bindkey
break
...

Вы можете использовать type, чтобы найти тип команды:

$ type cd
cd is a shell builtin

Команда which возвращает путь к файлу. Работает только для исполняемых программ:

$ which ls
/usr/bin/ls

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

# no response
$ which cd
$ which umask
$ which alert

Вы можете найти более подробную информацию о builtin от man builtin:

$ man builtin
BUILTIN(1)  BSD General Commands Manual
NAME
     builtin, !, %, ., :, @, {, }, alias, alloc, bg, bind, bindkey,
     break, breaksw, builtins, case, cd, chdir, command, complete, 
     continue, default, dirs, do, done, echo, echotc, elif, else, end, 
     ....

Тесты

Команда test выполняет множество проверок и сравнений, и вы можете использовать ее с операторами if.

оператор if

Ключевое слово then следует после оператора if:

if [ condition-for-test ]
then
  command
  ...
fi

Вы можете использовать if и then в одной строке, используя ; для завершения оператора if:

if [ condition-for-test ]; then
  command
  ...
fi

(Подробнее об операторе if будет рассказано позже.)

Как правило, сравнение работает с двойными кавычками и одинарными кавычками, когда переменная представляет собой одно слово:

Одиночные кавычки не работают в некоторых случаях:

Без двойных кавычек у вас может возникнуть проблема:

В первом тесте есть четыре аргумента: два аргумента из $VAR1, у которого есть "my" и "var", а затем = и "my var".

Короче говоря, всегда используйте двойные кавычки.

Пространства имеют значение

Если у вас нет пробелов до и после символа =, выражение рассматривается как одно слово, а затем оно рассматривается как true.

Помните, что между [ и именем переменной и оператором равенства, = или == должен быть пробел. Если вы пропустите любое из этих пробелов, вы можете увидеть ошибку типа ‘unary operator expected’ or missing `]’.

# correct, a space before and after = sign
if [ $VAR2 = 1 ]; then
    echo "$VAR2 is 1."
else
    echo "It's not 1."
fi
# wrong, no space before and after = sign
if [ $VAR2=1 ]; then
    echo "$VAR2 is 1."
else
    echo "It's not 1."
fi

Выражения из тестового файла

В таблице ниже показаны выражения для тестирования файлов.

Вы можете найти все параметры, используя man test.

Команда test возвращает статус выхода 0, если выражение равно true, и статус 1, если выражение равно false.

Проверить строковые выражения

В таблице ниже показаны выражения для проверки строк.

#!/bin/bash
STRING=""
if [ -z "$STRING" ]; then
  echo "There is no string." >&2 
  exit 1
fi
# Output
# There is no string.

>&2 перенаправляет сообщение об ошибке в стандартную ошибку: прочтите статус выхода для exit 1.

Проверить целочисленные выражения

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

Двойные скобки

Вы можете использовать двойные круглые скобки ((... )) для арифметического расширения и вычисления.

Как использовать операторы if / else и if / elif / else

Ниже приведены примеры операторов if...else и if...elif...else.

Оператор if/else имеет следующую структуру:

if [ condition-is-true ]
then
  command A
else
  command B
fi
# or
if [ condition-is-true ]; then
  command A
else
  command B
fi

Пример:

Оператор if/elif/else имеет следующую структуру:

if [ condition-is-true ]
then
  command A
elif [ condition-is-true ]
then
  command B
else
  command C
fi
# or
if [ condition-is-true ]; then
  command A
elif [ condition-is-true ]; then
  command B
else
  command C
fi

Пример:

Двойные скобки

Если переменная представляет собой одно слово, команда условно-составных двойных скобок [[ condition-for-test ]] не требует двойных кавычек; но одинарная скобка [ condition-for-test ] требует двойной кавычки для переменной. Но рекомендуется использовать двойные кавычки.

Двойной кронштейн имеет дополнительные функции по сравнению с одинарным кронштейном. Вы можете использовать логические &&, || и =~ для регулярного выражения.

Как использовать для петель

Цикл for используется для перебора последовательности и имеет следующую структуру:

for VARIABLE_NAME in ITEM_1 ITEM_N
do
  command A
done

Пример:

Вы можете использовать переменную следующим образом:

Использование цикла for для переименования файлов

#!/bin/bash
IMGS=$(ls *png)
DATE=$(date +%F)
for IMGin $IMGS
do
  echo "Renaming ${IMG} to ${DATE}-${IMG}"
  mv ${IMG} ${DATE}-${IMG}
done

Знак + в +%F сигнализирует об определяемом пользователем формате, а %F показывает полную дату. Для получения дополнительных сведений о date используйте man date.

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

Сценарий Bash может принимать несколько аргументов, как показано ниже:

$ scriptname param1 param2 param3

От param1 до param3 называются позиционными параметрами. Вы можете использовать $0, $1, $2 и т. Д. (Часто мы используем ${1}, ${2} и т. Д.) Для вывода параметров. Например:

#!/bin/bash
echo "'$0' is $0"
echo "'$1' is $1"
echo "'$2' is $2"
echo "'$3' is $3"

Выходы:

$ ex1 param1 param2 param3
'$0' is /Users/shinokada/bin/ex1
'$1' is param1
'$2' is param2
'$3' is param3

$0 выводит имя файла, включая путь.

Чтобы получить доступ ко всем параметрам, вы можете использовать [email protected].

#!/bin/bash
for PET in [email protected]
do
  echo "My pet is: $PET"
done

Используя этот скрипт:

$ ex1 cat dog gorilla
My pet is: cat
My pet is: dog
My pet is: gorilla

Как принять ввод пользователя

Пользовательский ввод называется STDIN. Вы можете использовать команду read с опцией -p (приглашение) для чтения пользовательского ввода. Он выведет строки приглашения. Параметр -r не позволяет экранировать символы обратной косой черты.

read -rp "PROMPT" VARIABLE

Пример:

#!/bin/bash
read -rp "Enter your programming languages: " PROGRAMMES
echo "Your programming languages are: "
for PROGRAMME in $PROGRAMMES; do
    echo "$PROGRAMME "
done

Запускаем скрипт:

$ ex1                     
Enter your programming languages: python js rust 
Your programming languages are: 
python 
js 
rust

Расширение скобок с использованием диапазонов

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

$ echo {0..3}
$ echo {a..d}
# output: 
# 0 1 2 3
# a b c d

Вы можете использовать это расширение скобок в for циклах:

#!/bin/bash
for i in {0..9}; 
do 
  touch file_"$i".txt; 
done

Это создаст разные имена файлов с разным временем модификации.

$ ls -al
-rw-r--r--    1 shinokada  staff      0 Jan 27 08:25 file_0.txt
-rw-r--r--    1 shinokada  staff      0 Jan 27 08:25 file_1.txt
-rw-r--r--    1 shinokada  staff      0 Jan 27 08:25 file_2.txt
-rw-r--r--    1 shinokada  staff      0 Jan 27 08:25 file_3.txt
-rw-r--r--    1 shinokada  staff      0 Jan 27 08:25 file_4.txt
...

Как использовать циклы while

Пока выражение равно true, цикл while продолжает выполнять строки кода.

#!/bin/bash
i=1
while [ $i -le 5 ]; do
  echo $i
  ((i++))
done

Выход:

1
2
3
4
5

Что такое статус выхода / коды возврата?

Каждая команда возвращает статус выхода в диапазоне от 0 до 255. 0 означает успех, а все, кроме 0, означает ошибку. Мы можем использовать это для проверки ошибок.

Проверка статуса выхода

$? содержит код возврата ранее выполненной команды:

$ ls ./no/exist
ls: cannot access './no/exist': No such file or directory
$ echo "$?"
2

Давайте используем код выхода в инструкции if:

-c 1 останавливается после отправки одного пакета запроса. Здесь мы проверяем, равен ли статус выхода 0.

Выход:

$ ex1
PING google.com (216.58.197.206): 56 data bytes
64 bytes from 216.58.197.206: icmp_seq=0 ttl=114 time=11.045 ms
--- google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 11.045/11.045/11.045/0.000 ms
google.com reachable.

Как соединить команды

Логические операторы и статус выхода команды

Команда выводит статус выхода, и мы можем использовать && и || для определения следующих действий.

Команда выхода

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

exit 0
exit 1
exit 2
etc.

Пример:

#!/bin/bash
HOST="google.com"
ping -c 1 $HOST  
if [ "$?"" -ne "0" ]
then
  echo "$HOST unreachable."
  exit 1
fi
exit 0

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

$ ex1 && ls          
...
2020-10-03-image-1.png  ex1     myscript1
2020-10-03-image-2.png  ifstatement  
2020-10-03-image-3.png  logfile

Логическое И (&&)

Вторая команда выполняется, если первая команда возвращает код состояния 0, что означает, что она выполнена успешно.

mkdir /tmp/bak && cp test.txt /tmp/bak

Логическое ИЛИ (||)

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

cp test.txt /tmp/bak/ || cp test.test.txt /tmp

Примеры

Если команда ping завершится успешно, будет запущен оператор echo.

#!/bin/bash
host="google.com"
ping -c 1 $host && echo "You can reach ${host}."

В случае сбоя команды ping запускается оператор echo.

#!/bin/bash
host="google.com"
ping -c 1 $host || echo "You can't reach ${host}."

Точка с запятой

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

cp text.txt /tmp/bak/ ; cp test.txt /tmp
# This is the same as
cp text.txt /tmp/bak/  
cp test.txt /tmp

Труба |

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

Первая команда изменяет каталог на домашний каталог и выводит список файлов и каталогов.

Вторая команда просто печатает каталог, в котором была выполнена команда.

$ echo "$(cd ~ && ls)"
$ echo "$(cd ~ | ls)"

Функции

В сценарии Bash вы должны определить функцию, прежде чем использовать ее. Вы можете создать функцию с ключевым словом function или без него.

function function-name(){}
# or
function-name(){}

При вызове функции используйте только имя функции без ().

Функции могут вызывать другие функции.

Функция now объявляется перед вызовом функции hello. Если вы определите функцию now после вызова hello, она не будет работать.

#!/bin/bash
# this won't work
function hello(){
  echo "Hello!"
  now
}
hello
function now(){
  echo "It's $(date +%r)"
}

date +%r выводит в формате 17:04:12.

Параметры функции

Как мы обсуждали в разделе о параметрах скрипта, $0 — это не имя функции, а сам скрипт. $1 — это первый параметр функции.

#!/bin/bash
function fullname(){
  echo "$0"
  echo "My name is $1 $2"
}
fullname John Doe
# Output
# /Users/shinokada/bin/ex1
# My name is John Doe

[email protected] содержит все параметры.

Переменная область

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

Локальные переменные

Вы можете получить доступ к локальным переменным внутри функции с помощью ключевого слова local. Только функции могут иметь локальные переменные.

Функция Выход Статус

Вы можете явно вернуть статус выхода в функции:

return 0

Неявно возвращается статус выхода последней команды, выполненной в функции. Допустимые коды от 0 до 255. 0 означает успех, а $? показывает статус выхода.

$ my_function
$ echo $?
0

Вы можете использовать $? в операторе if:

Приведенный выше сценарий создает резервную копию /etc/hosts по умолчанию, если нет аргумента. Если вы дадите аргумент, он проверит, является ли это файлом. Если это файл, он создаст копию в каталоге /tmp.

$$ — идентификатор процесса (PID) самого скрипта. PID меняется каждый раз, когда вы запускаете скрипт. Так что, если вы запускаете скрипт чаще, чем один раз в день, это полезно.

basename ${1} возвращает имя файла из вашего аргумента. Например, basename из /etc/hosts это hosts.

Пример date +%F2020-10-04.

$ ls /tmp
$ ex1           
Backing up /etc/hosts to /tmp/hosts.2020-10-04.77124
Backup succeeded.
$ ls /tmp
hosts.2020-10-04.77124

ключевые слова выхода и возврата

return приведет к тому, что текущая функция выйдет за пределы области видимости, а exit приведет к завершению сценария в точке, где он был вызван.

Контрольный список

  • Начни с шебанга.
  • Опишите цель сценария
  • Сначала объявите все глобальные переменные
  • Объявите все функции после глобальных переменных
  • Используйте локальные переменные в функциях.
  • Напишите основной текст после функций
  • Используйте явный код статуса выхода в ваших функциях, в операторе if и в конце скрипта.

Заключение

Мы рассмотрели настройки, переменные, тесты, if операторы, двойные скобки, for циклы, параметры, пользовательский ввод, while циклы, статусы выхода, логические операторы, функции и области действия переменных.

Я надеюсь, что эта статья даст вам основу для следующего шага в изучении сценариев Bash. Всем удачного кодирования.

Новостная рассылка

Получите полный доступ ко всем статьям на Medium, став участником.

использованная литература

  1. Переменные, Внутренние переменные
  2. Шеллчек
  3. Shellcheck вики
  4. Shell-формат
  5. Вики о Bash Hackers
  6. Расширенное руководство по сценариям на Bash

Создание сценариев на Bash — полезный навык для пользователей Linux. Даже для новичка знание этого навыка может стать разницей между полноценным использованием вашей машины и выполнением всего вручную. Вот почему в этой статье мы научим вас писать сценарии bash для автоматизации Linux и получения полного контроля над рабочим столом. Мы рассмотрим основы написания сценариев с помощью оболочки Bash, основы того, что делает сценарий, как запускать их в вашей системе, что означают слова shebang и многое другое!

Типы скриптов

Есть много разных типов скриптов. В основном: SH и BASH. Эти расширения файлов важны, потому что расширение файла сообщает интерпретатору, как его запускать. Если файл является файлом SH, его можно запустить в любой оболочке, а не только в Bash. Это означает, что сценарий, написанный для Bash в Linux, может работать на Mac, BSD и других местах с аналогичными оболочками.

Сценарии, использующие расширение файла BASH, предназначены только для запуска внутри Bash. Достаточно сказать, что ваш скрипт с расширением файла bash не будет работать в оболочке Fish в Linux или любой другой доступной подобной оболочке.

Она взорвалась

Некоторые скрипты вообще не используют расширения файлов. Вместо этого они используют shebang, чтобы интерпретатор понимал, для чего предназначен сценарий и как его запускать. При написании сценария шебанг ВСЕГДА стоит на первом месте. Если shebang отсутствует, часто сценарий отказывается запускаться, особенно если расширение файла не используется.

О шебангах можно многое узнать, но новичкам не стоит о них беспокоиться. Они полезны только для продвинутых пользователей Bash, которые хотят писать невероятно сложные инструменты Bash. Как новичкам, пользователям следует подумать только о стандартном: #! / Bin / bash

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

Для начала откройте терминал и введите следующую команду:

nano myfirstbashscript

Это вызывает текстовый редактор Nano. Внутри nano добавьте shebang, чтобы помочь интерпретатору определить, что делать со сценарием.

#!/bin/bash

Отсюда мы можем все! Например: пользователь Ubuntu может создать простой скрипт обновления, добавив строки:

sudo apt update;sudo apt upgrade -y

В качестве альтернативы, другой пример: создайте скрипт непрерывного ping для работы в фоновом режиме, если вас беспокоит скорость вашей сети.

ping google.com

Добавьте в скрипт любые команды, которые вы хотите! Будьте изобретательны!

После добавления того, что вы хотите в свой скрипт, сохраните его с помощью nano с помощью CTRL + O.

Создав сценарий, пора обновить разрешения. В терминале выполните:

sudo chmod +x myfirstbashscript

Запуск скриптов

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

sudo sh script.sh

Чтобы запустить файлы bash, попробуйте:

sudo bash script.bash

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

Все три способа запуска скриптов работают очень хорошо. При этом использование ./filename — наихудший способ, поскольку скрипты часто не запускаются, если у сценария bash нет правильных разрешений. Установите разрешения с помощью:

sudo chmod +x script

Делаем ваш скрипт двоичным

Чтобы запустить сценарий, просто набрав имя файла в терминале, вам нужно сделать его двоичным. Для этого используйте команду chmod, чтобы сделать его исполняемым.

sudo chmod +x

Когда сценарий помечен как исполняемый файл, пора переместить сценарий, чтобы он был доступен по пути пользователя. Сделайте это с помощью команды MV. В качестве альтернативы используйте команду CP вместо команды перемещения, если вы хотите сохранить резервную копию своего сценария в исходном месте.

sudo mv /location/of/script /usr/bin/

или

sudo cp /location/of/script /usr/bin/

Затем запустите только что перемещенный сценарий внутри терминала из любого места, просто набрав его имя в терминале. Например: вы использовали YouTube-DL для написания сценария автоматического копирования YouTube и поместили его в / usr / bin / для облегчения доступа.

Чтобы запустить указанный скрипт, вам нужно:

youtubescript

Это оно!

Заключение

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

Оболочка прекрасна, и чем больше вы узнаете о ней, тем больше вы узнаете об их собственных системах Linux, о том, как их автоматизировать и даже улучшить внутреннюю работу! С bash нет предела, все, что нужно — немного творчества!

Понравилась статья? Поделить с друзьями:
  • Разработка спортивного праздника день здоровья
  • Разработка приглашения на новогодний праздник
  • Разработка праздника хэллоуин
  • Разведка морской пехоты россии праздник
  • Разработка праздника золотая осень

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии