Linux命令行与Shell脚本编程大全-创建函数

本章内容:

  • 基本的脚本函数
  • 返回值
  • 在函数中使用变量
  • 数组变量和函数
  • 函数递归
  • 创建库
  • 在命令行中使用函数
创建函数

有两种格式可以用来在bash shell脚本中创建函数。第一种格式是采用关键字function,后跟分配给该代码块的函数名:

function name {
   command
}

另一种格式:函数名后的圆括号为空,表明正在定义的是一个函数。

name() {
  command
}
使用函数
#!/bin/bash
# using a function in a script

function func1{
  echo "This is a example of a function"
}

count=1
while [ $count -le 5 ]
do
  func1
  count=$[ $count +1 ]
done
echo "This is the end of the loop"
func1
echo "Now this is the end of the script"

返回值

bash shell 会把函数当做小型脚本,运行结束时会返回一个退出状态码,有3种不同的方法来为函数生成退出状态码。
第一种方式:利用标准的$?来决定函数的退出状态码,备注:$?变量会返回执行的最后一条命令的退出状态码,必须得紧跟在后面

#!/bin/bash
# testing the exit status of a function
func1() {
  echo "trying to display a non-existent file"
  ls -l badfile
}

echo "testing the function:"
func1
echo "The exit status is : $?"

第二种方式:使用return命令 备注:退出状态码必须小于256,任何大于256的值都会返回一个错误值

#!/bin/bash
#using the return command in a function

function db1 {
  read -p "Enter a value: " value
  echo "doubling the value"
  return $[ $value * 2 ]
}

db1
echo "The new value is $?"

$./test5
Enter a vlaue:200
doubling the value
The  new value is 1
$

第三种方式:使用函数输出
正如同可以将命令的输出保存到shell变量中一样,也可以将函数的输出保存到shell变量中。可以用这种技术来获得任何类型的函数输出,并将其保存到变量中去:

result= `db1` 

这个命令会将db1函数的输出赋值给$result这个变量。

#!/bin/bash
#using the echo ri return a value

function db1 {
  read -p "Enter a value: " value
  echo $[ $value * 20 ]
}

result=`db1`
echo "The new value is $result"

$./tetst5
Enter a value: 200
The new value is 400
$
$./test5
Enter a value: 2000
The new value is 4000
$
向函数传递参数
#!/bin/bash
#passing parameters to a function

function addem {
  if [ $# -eq 0 ] || [ $# -gt 2 ]
  then
    echo -1
  elif [ $# -eq 1 ]
  then
    echo $[ $1 + $1 ]
  else
    echo $[ $1 + $2 ]
  fi
}

echo -n "Adding 10 and 15: "
value=`addem 10 15`
echo $value
echo -n "Let's try adding just one number: "
value=`addem 10`
echo $value
echo -n "Now trying adding no number: "
value=`addem`
echo $value
echo -n "Finally, try adding tree number: "
value=`addem 10 20 30`
echo $value

$./test6
Adding 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no number: -1
Finally, try adding tree number: -1
$

由于函数使用特殊参数环境变量作为自己的参数值,它不能直接从脚本的命令行获取传递给脚本的参数值。必须在调用函数是手动将它们传过去。

#!/bin/bash
#trying to access script parameters inside a function

function func7 {
  echo $[ $1 * $2 ]
}

if [ $# -eq 2 ]
then
  value=`func7 $1 $2`
  echo "The result is $value"
else
  echo "The Usage: badtest1 a b"
fi
$
$./test7
The Usage: badtest1 a b
$./test7 10 15
The result is 150
$
在函数中处理变量

函数会用两种类型的变量:

  • 全局变量
  • 局部变量
    全局变量是在shell脚本中任何地方都有效的变量。如果你在函数中定义了一个全局变量,你可以在脚本的主体部分读取它的值。默认情况下,你在脚本中定义的任何变量都是全局变量。在函数外定义的变量可以在函数内正常访问:
#!/bin/bash
#using a global variable to pass a value
function db1 {
   value=$[ $value * 2 ]
}

read -p "Enter a value: " value
db1
echo "The new value is:$value"

#$value 变量是在函数外定义的,并在函数外被赋值了。当db1函数被调用时,变量及其值在函数中依然有效。如果变量在函数中被赋予了新的值,那么在脚本中引用该变量是,新值依然有效。
#!/bin/bash
#demonstrating a bad use of variables

function func1 {
  temp=$[ $value + 5 ]
  result=$[ $temp * 2 ]
}

temp=4
value=6

func1
echo "The result is $result"
if [ $temp -gt $value ]
then
  echo "temp is larger"
else
  echo "temp is smaller"
fi

$./badtest2
The result is 22
temp is larger
$

#由于$temp变量在函数中用到了,它的值在脚本中使用,产生了一个意想不到的结果。此时如果需要避免这个问题,得需要使用局部变量

局部变量在函数内部使用的任何变量都可以被声明称局部变量,只要在变量声明的前面加上local关键字就可以了:

local temp
#local 关键字保证了变量只局限在该函数中。如果脚本中在该函数之外有同样名称的变量,那么shell将会保持这两个变量的值是分离的。那么你就能很轻松地让函数变量和脚本变量分离开来,只共用想共用的:
#!/bin/bash
# demonstrating the local keyword

function func1 {
  local temp=$[ $value + 5 ]
  result=$[ $temp * 2 ]
}

temp=4
value=6

func1
echo "The result is $result"
if [ $temp -gt $value ]
then
  echo "temp is larger"
else
  echo "temp is smaller"
fi
$
$./test9
The result is 22
temp is smaller
$
#现在在func1函数中使用$temp变量时,并不影响在主体脚本中赋给$temp变量的值
数组变量和函数
  • 向函数传数组参数
#!/bin/bash
#tring to pass an array variable
function testit {
  echo "The parameters are: $@"
  thisarray=$1
  echo "The received array is ${thisarray[*]}
}

myarray=(1 2 3 4 5)
echo "The original array is : ${myarray[*]}"
testit  $myarray

$./badtest3
The original arry is: 1 2 3 4 5
The parameters are: 1
./badtest3: thisarray[*]: bad array subscript
The received array is
$
#如果你试图将该数组当成一个函数参数,函数只会取数组变量的第一个值。

解决的方法,你可以将所有的参数重组到新的数组变量中

#!/bin/bash
# array variable to function test

function testit {
  local newarray
  newarray=(`echo $@`)
  echo "The new array value is: ${newarray[*]}"
}

myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}

$./test10
The original array is 1 2 3 4 5
The new array is 1 2 3 4 5
$
  • 从函数返回数组
#!/bin/bash
#returning an array value

function arrayblr {
  local origarray
  local newarray
  local elements
  local i
  origarray=(`echo $@`)
  newarray=(`echo $@`)
  elements=$( $# - 1 )
  for (( i=0; i <= $elements; i++ ))
  {
    newarray[$i]=$[ ${origarray[$i] * 2} ]
  }
  echo ${newarray[*]}  
}

myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
arg1=`echo ${myarray[*]}`
result=(`echo $arg1`)
echo "The newarray is $result[*]"

$
$./test12
The original array is: 1 2 3 4 5
The new array is: 2 4 6 8 10

  • 函数递归
#!/bin/bash
#using recursion

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 a value: " value
result=`factorial $value`
echo "The factorial of $value is: $result"
  • 创建库
#my script functions

function addem {
  echo $[ $1 + $2 ]
}


function multem {
  echo $[ $1 * $2 ]
}



#!/bin/bash
#using a library file 
source ./myfuncs
#. ./myfuncs source的快捷别名, 点操作符

value1=10
value2=5
result1=`addem $value1 $value2`
result2=`multem $value1 $value2`
echo "The result of addem them is: $result1"
echo "The result of multem them is: $result2"

$./test14
The result of addem them is: 15
The result of multem them is: 50
$
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容