您的位置:首页 > 运维架构 > Shell

shell函数

2013-06-08 21:55 162 查看
1、格式

function 函数名 ()

{

命令1

...

}

2、脚本中定义并使用函数

#!/bin/bash

#func1

hello ()

{

echo "Hello there today's date is `date`"

}

echo "now going to the function hello"

hello

echo "back from the function"

3、向函数传递参数

一般使用位置变量($1,$2...$9),调用参数的转换格式如下:_FILENAME或_filename(下划线加变量名)

4、从调用函数中返回

两种处理:

正常执行到函数末尾,返回脚本中调用函数的控制部分;

return返回脚本中函数调用的下条语句,可带返回值,如下

return --- 函数中返回,用最后状态命令决定返回值

return 0 --- 无错误返回

return 1 --- 有错误返回

5、函数返回值测试

通过最后状态命令测试

check_it_is_a_directory $FILENAME;

if [ $? = 0 ]

then

echo "all is ok"

else

echo "something went wrong!"

fi

或使用if测试返回0或1

if check_it_is_a_directory $FILENAME; then

echo "all is ok"

else

echo "something went wrong!"

fi

6、shell中使用函数

set命令可查看所有定义函数,包括已载入shell的所有函数;改动函数需用unset删除函数(非真正删除,仅对与shell或脚本不可利用),改完再重新载入此文件。

7、创建函数文件

创建包容函数的函数文件并载入shell,函数名为functions.main,如下:

#!/bin/bash

#functions.main

#

#findit: this is front end for the basic find command

findit()

{

if [ $# -lt 1 ]; then

echo "usage : findit file"

return 1

fi

find / -name $1 -print

}

8、定位文件

格式 . pathname/filename

将文件载入shell,如

. functions.main(点+空格+文件名(目录名+文件名))

9、检查载入函数

set命令确保函数已载入

set | grep findit可查看到载入函数findit

10、shell函数修改、删除、集中

删除函数使其对shell不可利用

unset function_name

set命令检查确认

编辑函数functions.main,加入for循环以便脚本可从命令行中读取多个参数

#!/bin/bash

#functions.main

#

#findit: this is front end for the basic find command

findit()

{

if [ $# -lt 1 ]; then

echo "usage : findit file"

return 1

fi

for loop

do

find / -name $1 -print

done

}

11、脚本中或文件中调用函数

脚本中调用函数:

#!/bin/bash

#function file

is_it_a_directory()

{

_DIRECTORY_NAME=$1

if [ $# -lt 1 ]; then

echo "is_it_a_directory: I need a directory name to check"

return 1

fi

if [ ! -d $_DIRECTORY_NAME ]; then

return 1

else

return 0

fi

}

error_msg()

{

echo -e "\007"

echo $@

echo -e "\007"

return 0

}

echo -n "enter destination directory :"

read DIREC

if is_it_a_directory $DIREC

then :

else

error_msg "$DIREC does not exist...creating it now"

mkdir $DIREC > /dev/null 2>&1

if [ $? != 0 ]

then

error_msg "could not create directory:: check it out!"

exit 1

else :

fi

fi

echo "extracting files..."

从函数文件中调用函数:

将函数is_it_a_directory放入到function.sh函数文件中,如下:

#!/bin/bash

#functions.sh

#main script functions

is_it_a_directory()

{

_DIRECTORY_NAME=$1

if [ $# -lt 1 ]; then

echo "is_it_a_directory: I need a directory name to check"

return 1

fi

if [ ! -d $_DIRECTORY_NAME ]; then

return 1

else

return 0

fi

}

error_msg()

{

echo -e "\007"

echo $@

echo -e "\007"

return 0

}

编写脚本调用该文件中的函数需要文件定位,如: 点+空格+函数文件(目录+函数文件),如以下脚本中的调用:

#!/bin/bash

#direc_check

#source the function file function.sh

#that's a <dot><space><forward slash>

. home/test/script/function/function.sh

echo -n "enter destination directory :"

read DIREC

if is_it_a_directory $DIREC

then :

else

error_msg "$DIREC does not exist...creating it now"

mkdir $DIREC > /dev/null 2>&1

if [ $? != 0 ]

then

error_msg "could not create directory:: check it out!"

exit 1

else :

fi

fi

echo "extracting files..."

12、定位文件不仅用于函数

也包含组成配置文件的全局变量

如,先定义个配置文件backfunc,然后从另个脚本readfuc中通过定位文件调用该配置文件中的参数,如下:

#!/bin/bash

#name:backfunc

_CODE="comet"

_FULLBACKUP="yes"

_LOGFILE="/logs/backup/"

_DEVICE="/dev/rmt/0n"

_INFORM="yes"

_PRINT_STATS="yes"

通过定位文件调用函数的脚本如下:

#!/bin/bash

#readfuc

if [ -r backfunc ]; then

. backfunc

else

echo "`basename $0` cannot locate backfunc file"

fi

echo -n "Enter the code name : "

read CODE

if [ "${CODE}" != "${_CODE}" ]; then

echo "wrong code...exiting...will use defaults"

exit 1

fi

echo "The enviroment config file reports"

echo "full backup required :$_FULLBACKUP"

echo "the logfile is :$_LOGFILE"

echo "the device to backup to is :$_DEVICE"

echo "you are to be informed by mail :$_INFORM"

echo "a statistic report to be printed:$_PRINT_STATS"

13、函数举例

(1) 变量输入字符判断,如下:

#!/bin/bash

#func2

char_name()

{

_LETTERS_ONLY=$1

_LETTER_ONLY=`echo $1 | awk '{if($0~/[^a-zA-Z]/) print "1"}'`

if [ "$_LETTER_ONLY" != "" ]

then

return 1

else

return 0

fi

}

name_error()

{

echo "$@ contain erros, it must cotain only letters"

}

while :

do

echo -n "entry your first name :"

read F_NAME

if char_name $F_NAME

then

break

else

name_error $F_NAME

fi

done

while :

do

echo -n "entry your second name :"

read S_NAME

if char_name $S_NAME

then

break

else

name_error $S_NAME

fi

done

(2) 提示Y或N的处理

#!/bin/bash

#continue_prompt

continue_prompt()

{

_STR=$1

_DEFAULT=$2

if [ $# -lt 1 ]; then

echo "continue_prompt: I need a string to display"

return 1

fi

while :

do

echo -n "$_STR [Y...N] [$_DEFAULT]:"

read _ANS

if [ "$_ANS" = "" ]; then

: ${_ANS:=$_DEFAULT}

case $_ANS in

Y) return 0 ;;

N) return 1 ;;

esac

fi

case $_ANS in

y|Y|Yes|YES) return 0 ;;

n|N|No|NO) return 1 ;;

*) echo "answer either Y or N,default is $_DEFAULT" ;;

esac

echo $_ANS

done

}

然后文件调用函数

#!/bin/bash

. continue_prompt

if continue_prompt "Do your want to delete the var filesystem" "N"; then

echo "Are you nuts!!"

else

echo "Phew! what a good answer"

fi

(3) 通过用户名寻找ID

定义函数文件

#!/bin/bash

#who_is

who_is()

{

if [ $# -lt 1 ]; then

echo "whois : need user id's please"

return 1

fi

for loop

do

_USER_NAME=`grep $loop /etc/passwd | awk -F: '{print $4}'`

if [ "$_USER_NAME" = "" ]; then

echo "whois: sorry cannot find $loop"

else

echo "$loop is $_USER_NAME"

fi

done

}

脚本调用函数

#!/bin/bash

. who_is

echo "`who_is test see oracle`"

(4) 打印出文本文件行数

#!/bin/bash

#numberfile

numberfile()

{

_FILENAME=$1

if [ $# -lt 1 ]; then

echo "need a filename to number"

return 1

fi

loop=1

while read LINE

do

echo "$loop $LINE"

loop=`expr $loop + 1`

done < $_FILENAME

}

调用该函数文件

#!/bin/bash

. numberfile

numberfile ccc

(5) 大小写转换

定义函数文件

#!/bin/bash

str_to_upper()

{

_STR=$1

if [ $# -ne 1 ]; then

echo "need an string to convert"

return 1

fi

echo $@ | tr '[a-z]' '[A-Z]'

}

脚本调用

#!/bin/bash

. str_to_upper

str_to_upper asdfajkjqke

(6) 判断字符串是否为大写

函数文件

#!/bin/bash

#is_upper

is_upper()

{

if [ $# -ne 1 ]; then

echo "is_upper: I need a string to test OK"

return 1

fi

_IS_UPPER=`echo $1|awk '{if($0~/[^A-Z]/) print "1"}'` 换成 _IS_LOWER=`echo $1|awk '{if($0~/[^a-z]/) print "1"}'` 即是检测小写

if [ "$_IS_UPPER" != "" ]

then

return 1

else

return 0

fi

}

调用脚本

#!/bin/bash

. is_upper

echo -n "entry your name:"

read NAME

if is_upper $NAME; then

echo "Great it is upper case!"

else

echo "it's not upper!"

fi

(7) 字符串长度判断

函数文件

#!/bin/bash

#check_length

check_length()

{

_STR=$1

_MAX=$2

if [ $# -ne 2 ]; then

echo "I need string and max length"

return 1

fi

_LENGTH=`echo $1|awk '{print length($1)}'`

if [ "$_LENGTH" -gt "$_MAX" ]; then

return 1

else

return 0

fi

}

脚本调用

#!/bin/bash

. check_length

while :

do

echo -n "Enter your fisrt name :"

read NAME

if check_length $NAME 10

then

break

else

echo "the name field is too long 10 characters max"

fi

done

wc命令的缺点,会将空格部分也做为字符串的长度来计算

(8) MONTHS显示

函数文件

#!/bin/bash

months_test()

{

_MONTHS=$1

if [ $# -ne 1 ]; then

echo "months: I need a number 1 to 12 "

return 1

fi

case $_MONTHS in

1|01|Jan)_FULL="January" ;;

2|02|Feb)_FULL="February" ;;

3|03|Mar)_FULL="March" ;;

4|04|Apr)_FULL="April" ;;

5|05|May)_FULL="May" ;;

6|06|Jun)_FULL="June" ;;

7|07|Jul)_FULL="July" ;;

8|08|Aug)_FULL="August" ;;

9|09|Sep|Sept)_FULL="September" ;;

10|Oct)_FULL="October" ;;

11|Nov)_FULL="November" ;;

12|Dec)_FULL="December" ;;

*) echo "months: Unknown month"

return 1

;;

esac

echo $_FULL

}

脚本调用

#!/bin/bash

. months_test

MY_MONTHS=`months_test 02`

echo "the report for Month and $MY_MONTHS"

(9) chop函数,截取部分字符串

函数文件

#!/bin/bash

chop()

{

_STR=$1

_CHOP=$2

CHOP=`expr $_CHOP + 1`

if [ $# -ne 2 ]; then

echo "need a string and an character to chop"

return 1

fi

_LENGTH=`echo $_STR|awk '{print length($0)}'`

if [ "$_LENGTH" -lt "$_CHOP" ]; then

echo "need more characters than there are in the string"

return 1

fi

echo $_STR|awk '{print substr($1,'$CHOP')}'

}

脚本调用

#!/bin/bash

. chop

CHOPED=`chop "1234567890" 5`

echo $CHOPED
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: