С помощью служебной переменной $?, можно проверить -- является ли входной аргумент целым числом.
#!/bin/bash
SUCCESS=0
E_BADINPUT=65
test "$1" -ne 0 -o "$1" -eq 0 2>/dev/null
# Проверка: "равно нулю или не равно нулю".
# 2>/dev/null подавление вывода сообщений об ошибках.
if [ $? -ne "$SUCCESS" ]
then
echo "Порядок использования: `basename $0` целое_число"
exit $E_BADINPUT
fi
let "sum = $1 + 25" # Будет выдавать ошибку, если $1 не является целым числом.
echo "Sum = $sum"
# Любая переменная может быть проверена таким образом, а не только входные аргументы.
exit 0
Диапазон, возвращаемых функциями значений, 0 - 255 -- серьезное ограничение. Иногда может оказаться весьма проблематичным использование глобальных переменных, для передачи результата из функции. В таких случаях можно порекомендовать передачу результатов работы функции через запись в stdout.
Пример 33-10. Необычный способ передачи возвращаемого значения
#!/bin/bash
# multiplication.sh
multiply () # Функции выполняет перемножение всех переданых аргументов.
{
local product=1
until [ -z "$1" ] # Пока не дошли до последнего аргумента...
do
let "product *= $1"
shift
done
echo $product # Значение не будет выведено на экран,
} #+ поскольку оно будет записано в переменную.
mult1=15383; mult2=25211
val1=`multiply $mult1 $mult2`
echo "$mult1 X $mult2 = $val1"
# 387820813
mult1=25; mult2=5; mult3=20
val2=`multiply $mult1 $mult2 $mult3`
echo "$mult1 X $mult2 X $mult3 = $val2"
# 2500
mult1=188; mult2=37; mult3=25; mult4=47
val3=`multiply $mult1 $mult2 $mult3 $mult4`
echo "$mult1 X $mult2 X $mult3 X mult4 = $val3"
# 8173300
exit 0
Такой прием срабатывает и для строковых значений. Таким образом, функция может "возвращать" и нечисловой результат.
capitalize_ichar () # Первый символ всех строковых аргументов
{ #+ переводится в верхний регистр.
string0="$@" # Принять все аргументы.
firstchar=${string0:0:1} # Первый символ.
string1=${string0:1} # Остаток строки.
FirstChar=`echo "$firstchar" | tr a-z A-Z`
# Преобразовать в верхний регистр.
echo "$FirstChar$string1" # Выдать на stdout.
}
newstring=`capitalize_ichar "each sentence should start with a capital letter."`
echo "$newstring" # Each sentence should start with a capital letter.
Используя этот прием, функция может "возвращать" даже несколько значений.
Пример 33-11. Необычный способ получения нескольких возвращаемых значений
#!/bin/bash
# sum-product.sh
# Функция может "возвращать" несколько значений.
sum_and_product () # Вычисляет сумму и произведение аргументов.
{
echo $(( $1 + $2 )) $(( $1 * $2 ))
# Вывод на stdout двух значений, разделенных пробелом.
}
echo
echo "Первое число: "
read first
echo
echo "Второе число: "
read second
echo
retval=`sum_and_product $first $second` # Получить результат.
sum=`echo "$retval" | awk '{print $1}'` # Первое значение (поле).
product=`echo "$retval" | awk '{print $2}'` # Второе значение (поле).
echo "$first + $second = $sum"
echo "$first * $second = $product"
echo
exit 0
Следующая хитрость -- передача массива в функцию, и "возврат" массива из функции.
Передача массива в функцию выполняется посредством записи элементов массива, разделенных пробелами, в переменную, с помощью операции подстановки команды. Получить массив обратно можно, следуя вышеописанной стратегии, через вывод на stdout, а затем, с помощью все той же операции подстановки команды и оператора ( ... )-- записать в массив.
Пример 33-12. Передача массива в функцию и возврат массива из функции
#!/bin/bash
# array-function.sh: Передача массива в функцию и...
# "возврат" массива из функции
Pass_Array ()
{
local passed_array # Локальная переменная.
passed_array=( `echo "$1"` )
echo "${passed_array[@]}"
# Список всех элементов в новом массиве,
#+ объявленном и инициализированном в функции.
}
original_array=( element1 element2 element3 element4 element5 )
echo
echo "original_array = ${original_array[@]}"
# Список всех элементов исходного массива.
# Так можно отдать массив в функцию.
# **********************************
argument=`echo ${original_array[@]}`
# **********************************
# Поместив все элементы массива в переменную,
#+ разделяя их пробелами.
#
# Обратите внимание: метод прямой передачи массива в функцию не сработает.
# Так можно получить массив из функции.
# *****************************************
returned_array=( `Pass_Array "$argument"` )
# *****************************************
# Записать результат в переменную-массив.
echo "returned_array = ${returned_array[@]}"
echo "============================================================="
# А теперь попробуйте получить доступ к локальному массиву
#+ за пределами функции.
Pass_Array "$argument"
# Функция выведет массив, но...
#+ доступ к локальному массиву, за пределами функции, окажется невозможен.
echo "Результирующий массив (внутри функции) = ${passed_array[@]}"
# "ПУСТОЕ" ЗНАЧЕНИЕ, поскольку это локальная переменная.
echo
Читать дальше