Linux

Введение в скрипты на bash.

Опубликовано

Создайте папку my_bash_scripts для будущих сценариев. Добавьте только что созданную директорию в переменную окружения $PATH. Откройте файл ~/.bashrc и добавьте туда следующую строчку.

export PATH=~/my_bash_scripts:"$PATH"

считайте внесённые изменения

source .bashrc

На одном из предыдущих занятий мы писали команду для поиска файлов попадающие под определённые права доступа. Создайте файл find.sh и добавьте туда текст комады.

Я рекомендую работать в текстовом редакторе sublime и создавать новые файлы просто вписав sublime new_file.sh.

Каким образом вы будете создавать файл, решайте сами, главное не забудьте изменить его права на испольнение командой chmod.

#! /bin/bash
find ~\ 
  \(\
    -type f\
    -not -perm 0600\
  \)\
  -or\
  (\
    -type d\
    -not -perm 0700\
  \)

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

\\n — последовательность продолжения строки.

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

Ветвление

FILE=./find_1.sh  # помещаем путь к файлу
​
if [ -e "$FILE" ]; then # флаг -e возвращает истину, если объект существует
  echo "is exist"
else
  echo "not exist"
fi

ещё один пример

iduser=$(id -u)  # получаем id текущего пользователя
if [ $iduser -eq 0 ]; then
  echo "you are super-user"
else
  echo "you are user"
fi

Так же мы можем управлять командами

команда 1 && команда2 — Вторая команда выполнится только в случае если первая завершилась успешно.

mkdir temp && cd temp  # если каталог temp создался, то мы сделаем его текущим рабочим каталогом.

команда1 || команда2 — Вторая команда будет выполнена, только в случае ошибки первой

[-d temp] || mkdir temp  # если каталога temp не существует, то сделаем каталог

Получение информации от пользователя

read -p "вот из ё нэйм?: " name
echo "hello, $name"

-p флаг устанавливающий фразу приглашение к вводу.

Установка нескольких значений одним вводом

echo "Введите пару-тройку значений разделённые запятой"
read var1 var2 var3 var4
echo $var1
echo $var2
echo $var3
echo $var4

Считаем информацию из файла /etc/passwd

FILE=/etc/passwd
read -p "Введите имя пользователя -> " user_name
file_info=$(grep "^$user_name" $FILE)  # 1
if [ -n "$file_info" ];then # если строка не пустая
  IFS=":" read user pw uid gid name home shell <<< "$file_info"  # 2
  echo "Пользователь: '$user'"
  echo "Идентификатор пользователя: '$uid'"
  echo "Идентификатор группы: '$gid'"
  echo "Имя, Фамилия, Адресс: '$name'"
  echo "Домашний каталог: '$home'"
  echo "Оболочка Shell: '$shell'"
else
  echo "Пользователь '$user_name' не найден.">&2
  exit 1
fi
  1. Присваиваем переменной результат работы функции grep. Регулярное выражение позволяет извлечь строчку которая начинается(^) с имени хранящемся в $user_name.
  2. IFS (Internal Field Separator) — переменная, которая хранит в себе значение по которым будет производиться разбиение введённой строки на переменные при работе функции read. По умолчанию это невидимые символы. Если установить новое значение в начале функции, мы изменим значение этой переменной только на время выполнения функции read. Оператор <<< отмечает встроенную строку, которая подаётся на стандартный ввод команды read.

Закрепление материала

Обработка ввода данных

#! /bin/bash
invalid_input(){
  echo "неправильные данные: '$REPLY' ">&2
  exit 1
}
​
read -p "введите одно слово : "
​
[[ -z $REPLY ]] && invalid_input  # если пустая строка
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input  # если более одного слова
if [[ $REPLY =~ [[:alnum:]] ]]; then  # если из буквенно-цифровых символов
  echo 'введено верное значение'
  if [[ -e $REPLY ]]; then  # проверка существования файла
    echo 'и существует файл с таким именем'
  else
    echo 'но файла с таким именем нет'
  fi
​
  if [[ $REPLY =~ ^[[:digit:]]+$ ]]; then  # проверка на число
    echo "$REPLY - это число"
  else
    echo "$REPLY - явно не число"
  fi
else
  invalid_input
fi

Статистика системы

#!/bin/bash
​
clear
echo "
Меню:
1 - инфо о системе
2 - дисковое пространство
3 - домашний каталог
0 - выход
"
​
read -p "введите [0-3]>"
if [[ $REPLY =~ ^[0-3]$ ]]; then
  if [[ $REPLY == 0 ]]; then
    echo "программа остановлена"
    exit
  fi
  if [[ $REPLY == 1 ]]; then
    echo "Имя хоста: $HOSTNAME"
    uptime
    exit
  fi
  if [[ $REPLY == 2 ]]; then
    echo "Дисковое пространство"
    df -h
    exit
  fi
  if [[ $REPLY == 3 ]]; then
    echo "Места занято"
    if [[ $(id -u) -eq 0 ]]; then
      du -sh /home/*
    else
      du -sh $HOME
    fi
    exit
  fi
else
  echo "введите число от 0 до 3">&2
  exit 1
fi

Наличие нескольких точек выхода(exit) является моветоном в написании скриптов.

Циклы

1.While

count=0
while [ $count -le 10 ]; do
 echo $count
 count=$(( count+1 ))
done

Используя полученные знания перепишем программу статистика системы.

#!/bin/bash
DELAY=3  # <---
while [[ $REPLY != 0 ]]; do  # <---
  clear
  echo "
  Меню:
   1 - инфо о системе
   2 - дисковое пространство
   3 - домашний каталог 
   0 - выход
  "
​
  read -p "введите [0-3]>"
 
  if [[ $REPLY =~ ^[0-3]$ ]]; then
    if [[ $REPLY == 0 ]]; then
      echo "программа остановлена"
      sleep $DELAY  # <---
    fi
    if [[ $REPLY == 1 ]]; then
      echo "Имя хоста: $HOSTNAME"
      uptime
      sleep $DELAY  # <---
    fi
    if [[ $REPLY == 2 ]]; then
      echo "Дисковое пространство"
      df -h
      sleep $DELAY  # <---
    fi
    if [[ $REPLY == 3 ]]; then
      echo "Места занято"
      if [[ $(id -u) -eq 0 ]]; then
        du -sh /home/*
      else
        du -sh $HOME
      fi
    sleep $DELAY  # <---
    fi
  else
    echo "введите число от 0 до 3">&2
    sleep $DELAY  # <---
  fi
done
​
echo "все-го хо-ро-ше-го!"

переписать программу используя конструкции break и continue.

2. until

until — синтаксически и функциональна похожа на while, с одним лишь отличием — если while работает, пока код ответа 0, то until работает до тех пор, пока код ответа не станет 0 (то есть пока условие ложно) . Аналогичный счётчик до 10 при помощи untill.

count=0
until [ $count -ge 10 ];do
  echo $count
  count=$((count+1))
done

3. for

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

#! /bin/bash
word='A B C'
for i in $word; do
  echo  $i
done
#! /bin/bash
word={1..10}
for i in $word; do
  echo  $i
done
#! /bin/bash
for i in {1..10}; do
  echo  $i
done

так же цикл for можно писать как на С

#! /bin/bash
for ((i=0; i<10; ++i)); do
  echo  $i
done

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

Ваш адрес email не будет опубликован.