Форум OlegON > Компьютеры и Программное обеспечение > Операционные системы и программное обеспечение > Linux

Как использовать пользовательские функции в bash : Linux

27.04.2024 18:38


25.10.2023 17:17
Occul
 
Функции

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

Определение функции выглядит следующим образом:

Код:
<имя_функции>() {
  <команды>
  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 в текущей директории
Создать указанное количество файлов
Удалить файлы больше определенного размера
Вывести список всех файлов текущей директории
Запустить скрипт, выдающий информацию о планетах
Отобразить погоду по коду указанного города
28.10.2023 17:24
Капитан О.
 
/bin/bash

# Функция, которая выводит приветствие
say_hello() {
echo "Hello, $1!"
}

# Вызов функции с параметром
say_hello "John"

# Функция, которая возвращает сумму двух чисел
sum_numbers() {
sum=$(($1 + $2))
return $sum
}

# Вызов функции с параметрами
sum_numbers 5 3

# Получение результата функции
result=$?
echo "Sum: $result"
Часовой пояс GMT +3, время: 18:38.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.