Функции
Часто используемые, повторяющиеся блоки имеет смысл выделять в отдельные функции, чтобы при необходимости их запускать, передавая параметры.
Определение функции выглядит следующим образом:
Код:
<имя_функции>() {
<команды>
return <число>
}
function <имя_функции>() {
<команды>
return <число>
}
Первый вариант ближе к синтаксису языка С и считается более переносимым, во втором варианте круглые скобки можно не указывать. Также может отсутствовать оператор return, если функция не возвращает значения.
Самый простой пример скрипта, содержащего объявление и вызов функции будет выглядеть так:
Код:
#!/bin/bash
f() {
echo Test
}
f
Мы объявили функцию f, которая выводит слово Test, и затем вызвали её:
Код:
test:~$ ./script6.sh
Test
Так же, как и скрипт, функция может принимать параметры и использовать их, ссылаясь по номеру ($1, $2, …, $N). Вызов функции с параметрами в скрипте осуществляется так:
Код:
<имя функции> <параметр1> <параметр2>… <параметрN>
Функция может возвращать результат своего выполнения (код завершения) в виде числового значения в диапазоне от 0 до 255. Принято считать, что если функция возвращает 0, то она выполнилась успешно, во всех остальных случаях значение содержит код ошибки. Чтобы получить код завершения функции в скрипте, необходимо обратиться к переменной $?. Добавив параметры и возвращаемое значение, получим следующий скрипт:
#!/bin/bash
Код:
summ() {
re='^[0-9]+$'
if ! [[ $1 =~ $re ]] ; then
return 1
elif ! [[ $2 =~ $re ]] ; then
return 2
else
s=$(($1 + $2))
return 0
fi
}
summ $1 $2
case $? in
0) echo "The sum is: $s" ;;
1) echo "var1 is not a nubmer" ;;
2) echo "var2 is not a nubmer" ;;
*) echo "Unknown error" ;;
esac
Здесь мы создали функцию summ, которая принимает 2 параметра и с помощью регулярного выражения ^[0-9]+$ проверяет, является ли каждый из переданных параметров числом. В случае, если первый параметр не число, то код завершения функции будет 1, если второй параметр не число, то код завершения функции будет 2. Во всех остальных случаях функция вычисляет сумму переданных параметров, сохраняя результат в глобальной переменной s.
Скрипт вызывает функцию, передавая ей на вход параметры, которые были переданы ему самому при вызове. Далее проверяется код завершения функции и выдается соответствующая ошибка, если код не равен 0, иначе выдается сумма, сохраненная в переменной s. Протестируем скрипт:
Код:
test:~$ ./script7.sh abc 123
var1 is not a nubmer
test:~$ ./script7.sh 234 def
var2 is not a nubmer
test:~$ ./script7.sh 10 15
The sum is: 25
По умолчанию переменные объявляются глобальными, т.е. видны в любом блоке скрипта. Переменные, объявленные как локальные, имеют ограниченную область видимости, и видны только в пределах блока, в котором они были объявлены. В случае с функцией это означает, что локальная переменная "видна" только в теле функции, в которой она была объявлена.
Для того, чтобы объявить переменную локальной, используется слово local, например local loc_var=123. Важно отметить, все что переменные, объявляемые в теле функции, считаются необъявленными до тех пор, пока эта функция не будет вызвана.
Объединим все воедино, создав на основе рассмотренных ранее структур следующий скрипт:
Код:
#!/bin/bash
clearFiles() {
rm *.dat
if [ $? -eq 0 ]
then
echo Files deleted
fi
}
genFiles() {
for (( i=1; i<=$1; i++ ))
do
head -c ${i}M </dev/urandom >myfile${i}mb.dat
done
ls -l *.dat
}
delFiles() {
for f in *.dat
do
size=$(( $(stat -c %s $f) /1024/1024 ))
if [ $size -gt $1 ]
then
rm $f
echo Deleted file $f
fi
done
ls -l *.dat
}
showWeather() {
curl -s "https://weather-broker-cdn.api.bbci.co.uk/en/observation/rss/$1" | grep "<desc" | sed -r 's/<description>//g; s/<\/description>//g'
}
menu() {
clear
echo 1 - Delete all .dat files
echo 2 - Generate .dat files
echo 3 - Delete big .dat files
echo 4 - List all files
echo 5 - Planet info
echo 6 - Show weather
echo "x/q - Exit"
echo -n "Choose action: "
read -n 1 key
echo
}
while true
do
case "$key" in
"x" | "q" | "X" | "Q") break ;;
"1")
clearFiles
read -n 1
;;
"2")
echo -n "File count: "
read count
genFiles $count
read -n 1
;;
"3")
echo -n "Delete file greater than (mb): "
read maxsize
delFiles $maxsize
read -n 1
;;
"4")
ls -la
read -n 1
;;
"5")
./script4.sh
read -n 1
;;
"6")
echo -n "Enter city code: " # 524901 498817 5391959
read citycode
showWeather $citycode
read -n 1
;;
esac
menu
done
В данном скрипте мы объявили 5 функций:
clearFiles
genFiles
delFiles
showWeather
menu
Далее реализован бесконечный цикл с помощью оператора while с условием true, в который вложен оператор выбора в зависимости от нажатой клавиши, а также вызов функции menu для отображения списка доступных действий. Данный скрипт в интерактивном режиме позволяет выполнить следующие действия:
Удалить все файлы .dat в текущей директории
Создать указанное количество файлов
Удалить файлы больше определенного размера
Вывести список всех файлов текущей директории
Запустить скрипт, выдающий информацию о планетах
Отобразить погоду по коду указанного города