{{tag>bash}}

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


Безусловно, все те кто общается с ОС Linux хоть раз да имели дело(во всяком случае слышали точно) с командной оболочкой BASH. Но BASH не только командная оболочка, это еще и превосходный скриптовый язык программирования.
Цель этой статьи — познакомить поближе юзеров с bash, рассказать про синтаксис, основные приемы и фишки языка, для того чтобы даже обычный пользователь смог быстренько написать простой скрипт для выполнения ежедневной(-недельной, -месячной) рутинной работы или, скажем, «на коленке» наваять скриптик для бэкапа директории.

===== Введение =====


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) поменяйте её на ваш путь.
2. Коментарии начинаются с символа # (кроме первой строки).
3. В bash переменные не имеют типа(о них речь пойдет ниже)

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


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

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


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

  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 условия пишутся след. образом (как обычно на примере):

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

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

  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 Выход"
  read doing #здесь мы читаем в переменную $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.



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

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



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

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

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


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

[[bash:основы_bash._часть_2|]]
