目录
73. 创建函数
function name
{
commands
}
或者
name ()
{
commands
}
#!/bin/bash
fun1 ()
{
echo "I am ready to leave!"
}
cnt=6
while [ $cnt -gt 0 ]; do
fun1
cnt=$[ $cnt - 1 ]
done
fun1 ()
{
echo "cnt is now $cnt"
}
fun1
使用(无输入参数的)自定义函数时,就跟使用shell内置命令一样。函数名必须是唯一的。
并且可以在下文重新定义该函数。
74. 函数的返回值 return echo
return是跟退出状态码($?)搭配使用的。
#!/bin/bash
dbl ()
{
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
dbl
echo "The new value is $?"
不过,但凡使用退出状态码($?)就有一个问题:退出状态码必须是0~255,超出范围会出问题。
所以echo法更有效。
#!/bin/bash
dbl1 ()
{
read -p "Enter another value: " value
echo $[ $value * 2 ] # it is not a printf statement, but more like a return
# echo "what 's wrong"
}
result=$(dbl1)
echo "The new value is $result"
result=$(func)调用了func并获取了func的输出值。输出值范围不受限,也可以是浮点数和字符串。
75. 向函数传递输入参数
bash shell会将函数当作小型脚本来对待。函数命令行上的任何参数都会通过$1、$2等定义。也可以用特殊变量$#来判断传给函数的参数数目。总之,就跟给脚本传参数一样。
#!/bin/bash
func2 ()
{
echo "The number of this function's params is $#"
echo "The first param is $1. The 2nd param is $2."
}
func2 11 32 125 119 # $1 $2 $3 $4
echo "The number of this script's params is $#"
echo "The first param is $1. The 2nd param is $2."
整个脚本和单个函数的 $#, $1, $2,... 是独立的概念。
76. 函数变量的作用域
默认情况下,在脚本中定义的任何变量都是全局变量。在函数外定义的变量可在函数内正
常访问。
#!/bin/bash
# using a global variable to pass a value
function dbl
{
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
dbl
echo "The new value is: $value"
但局部变量的作用还是不小的:
#!/bin/bash
function factorial
{
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=$(factorial $temp)
echo $[ $result * $1 ]
fi
}
read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"
因为局部函数变量的一个特性是自成体系。除了从脚本命令行处获得的变量$1 $2 ...,自成体系的函数不需要使用任何外部资源。这个特性使得函数可以递归地调用.
77. 创建和调用库
bash shell允许创建函数库文件,然后在多个脚本中引用该库文件。
Lib1.sh
#!/bin/bash
function addem
{
echo $[ $1 + $2 ]
}
function multem
{
echo $[ $1 * $2 ]
}
function divem
{
if [ $2 -ne 0 ]
then
echo $[ $1 / $2 ]
else
echo -1
fi
}
test38.sh
#!/bin/bash
source ./Lib1.sh
. ./Lib1.sh
result1=$( addem 1 2 )
result2=$( multem 3 5 )
result3=$( divem 10 5 )
echo "result1 = $result1"
echo "result2 = $result2"
echo "result3 = $result3"
用source命令或者 . (点操作符),来运行库文件脚本。这样脚本就可以调用库中的函数了
78. shell脚本菜单
一般是将菜单布局本身作为一个函数来创建,这样就可以反复调用了
#!/bin/bash
menu ()
{
clear
echo
echo -e "\t\t\tSys Admin Menu\n"
echo -e "\t1. Display disk space"
echo -e "\t2. Display logged on users"
echo -e "\t3. Display memory usage"
echo -e "\t0. Exit program\n\n"
echo -en "\t\tEnter option: "
read -n 1 option
}
while [ 1 ]; do
menu # Repeat the menu
case $option in
0 )
echo "Let us exit"
break;;
1)
echo -e "\nLet us Display disk space";;
2)
echo -e "\nLets display logged on users";;
3)
echo -e "\nLets display memory usage";;
*)
echo -e "\nSorry, wrong selection";;
esac
echo -en "\n\n\tHit any key to continue"
read -n 1 line
done
clear
-e 标志可以让echo语句识别 制表符\t 和 换行符\n。
79. select命令
select命令只需要一条命令就可以创建出菜单,然后获取输入的答案并自动处理。select命令的格式如下。
select variable in list
do
commands
done
#!/bin/bash
function diskspace {
clear
df -k
}
function whoseon {
clear
who
}
function memusage {
clear
cat /proc/meminfo
}
PS3="Enter option: "
select option in "Exit program" "Display disk space" \
"Display logged on users" "Display memory usage"
do
case $option in
"Exit program")
break ;;
"Display disk space")
diskspace ;;
"Display logged on users")
whoseon ;;
"Display memory usage")
memusage ;;
*)
clear
echo "Sorry, wrong selection";;
esac
done
clear
直接拿list里面的字符串做成 选项。文本字符串值才是要在case语句中进行比较的内容。
select命令本身是无限循环的,唯有break才能跳出。
PS3作为select语句的shell界面提示符,提示符为PS3的值(赋予的字符串),更换默认的提示符”#?”