Создайте папку 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
- Присваиваем переменной результат работы функции grep. Регулярное выражение позволяет извлечь строчку которая начинается(^) с имени хранящемся в $user_name.
- 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