流年似水博客开通了,本站主要是写关于Web和大数据方面内容,正在更新中,欢迎大家光临!
  1. 文章:97 篇
  2. 总浏览:69,685 次
  3. 评论:22条
  4. 最后更新:2020-06-08
  5. 分类目录:39 个

Shell之函数

Shell l, xy 453℃ 0评论

函数

9.1 系统函数

1basename基本语法
                basename [string / pathname] [suffix]       功能描述:basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
                    选项:
                suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
2.案例实操
1)截取该/home/xy/banzhang.txt路径的文件名称
[xy@hadoop101 datas]$ basename /home/xy/banzhang.txt
banzhang.txt
[xy@hadoop101 datas]$ basename /home/xy/banzhang.txt .txt
banzhang
3.    dirname基本语法
       dirname 文件绝对路径        (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
4.案例实操
(1)获取banzhang.txt文件的路径
[xy@hadoop101 ~]$ dirname /home/xy/banzhang.txt
/home/xy

     5. 读取控制台输入’

    read读取控制台输入

1.基本语法

 read(选项)(参数)
    选项:
        -p:指定读取值时的提示符;
        -t:指定读取值时等待的时间(秒)。
            参数
           变量:指定读取值的变量名
2.案例实操
       1)提示7秒内,读取控制台输入的名称
[xy@hadoop101 datas]$ touch read.sh
[xy@hadoop101 datas]$ vim read.sh
#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds " NAME
echo $NAME
[xy@hadoop101 datas]$ ./read.sh
Enter your name in 7 seconds xiaoze
xiaoze

9.2 自定义函数

1.基本语法
[ function ] funname[()]
{
       Action;
       [return int;]
}
funname
2.经验技巧
       1)必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译
       2函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
3.案例实操
       1)计算两个输入参数的和

问题怎么获取函数的返回值呢 ? 

shell函数(调用、返回值,返回值获取)

Shell函数返回值,常用的两种方式:returnecho
1) return 语句
shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回。
示例1:
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$ #!/bin/sh
[devadmin@swarm1 pos-gateway]$ function mytest()
> {
> echo "arg1 = $1"
> if [ $1 = "1" ] ;then
> return 'ret1'
> else
> return 'ret0'
> fi
> }
[devadmin@swarm1 pos-gateway]$ mytest 1
arg1 = 1
-bash: return: ret1: numeric argument required
[devadmin@swarm1 pos-gateway]$
“numeric argument required”错误:
Shell 函数返回值只能是整形数值,一般是用来表示函数执行成功与否的,0表示成功,其他值表示失败。因而用函数返回值来返回函数执行结果是不合适的。如果要硬生生地return某个计算结果,比如一个字符串,往往会得到错误提示:“numeric
argument required”。
如果一定要让函数返回一个或多个值,可以定义全局变量,函数将计算结果赋给全局变量,然后脚本中其他地方通过访问全局变量,就可以获得那个函数“返回”的一个或多个执行结果了。
 
重新修改下示例2:
[devadmin@swarm1 pos-gateway]$ function mytest() { echo "arg1 = $1" ; if [ $1 = "1" ] ;then return 100; else return 200; fi ; }
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$ mytest 1
arg1 = 1
[devadmin@swarm1 pos-gateway]$ echo $?
100
[devadmin@swarm1 pos-gateway]$ mytest 2
arg1 = 2
[devadmin@swarm1 pos-gateway]$ echo $?
200
[devadmin@swarm1 pos-gateway]$
示例3:
[devadmin@swarm1 pos-gateway]$ if mytest 1; then
> echo "mytest 1"
> fi
arg1 = 1
[devadmin@swarm1 pos-gateway]$
说明:先定义了一个函数mytest,根据它输入的参数是否为1来return 100或者return 200。
A、如何调用shell函数(执行函数):函数名 参数
B、获取shell函数结果:$?
C、另外,可以直接用函数的返回值用作if的判断。(示例3)
注意:return只能用来返回整数值,且和c的区别是返回为正确,其他的值为错误
 
2) argv全局变量
这种就类似于C语言中的全局变量(或环境变量)。
示例:
#!/bin/bash -
g_var=
function mytest2()
{
echo "mytest2"
echo "args $1"
g_var=$1
return 0
}
mytest2 1
echo "return $?"
echo
echo "g_var=$g_var"
结果:
mytest2
args 1
return 0
g_var=1
函数mytest2通过修改全局变量(g_var)的值,来返回结果。
注: 以上两个方法失效的时候,以上介绍的这两种方法在一般情况下都是好使的,但也有例外。
示例:
#!/bin/bash -
function mytest3()
{
grep "123" test.txt | awk -F: '{print $2}' | while read line ;do
echo "$line"
if [ $line = "yxb" ]; then
return 0 # return to pipe only
fi
done
echo "mytest3 here "
return 1 # return to main process
}
g_var=
function mytest4()
{
grep "123" test.txt | awk -F: '{print $2}' | while read line ;do
echo "$line"
if [ $line = "yxb" ]; then
g_var=0
echo "g_var=0"
return 0 # return to pipe only
fi
done
echo "mytest4 here "
return 1
}
mytest3
echo $?
echo
mytest4
echo $?
echo
echo "g_var=$g_var"
其中,test.txt 文件中的内容如下:
456:kkk
123:yxb
123:test
结果:
yxb
mytest3 here 
1
yxb
g_var=0
mytest4 here 
1
g_var=
可以看到mytest3在return了以后其实没有直接返回,而是执行了循环体后的语句,同时看到mytest4中也是一样,同时,在mytest4中,对全局变量的修改也无济于事,全局变量的值根本就没有改变。这个是什么原因那?
笔者认为,之所以return语句没有直接返回,是因为return语句是在管道中执行的,管道其实是另一个子进程,而return只是从子进程中返回而已,只是while语句结束了。而函数体之后的语句会继续执行。
同理,全局变量在子进程中进行了修改,但是子进程的修改没有办法反应到父进程中,全局变量只是作为一个环境变量传入子进程,子进程修改自己的环境变量,不会影响到父进程。
因此在写shell函数的时候,用到管道(cmd &后台进程也一样)的时候一定要清楚此刻是从什么地方返回。
 
3) echo 返回值
其实在shell中,函数的返回值有一个非常安全的返回方式,即通过输出到标准输出返回。因为子进程会继承父进程的标准输出,因此,子进程的输出也就直接反应到父进程。
示例4:
#!/bin/sh
function test()
{
echo "arg1 = $1"
if [ $1 = "1" ] ;then
echo "1"
else
echo "0"
fi
}
echo
echo "test 1"
test 1
echo
echo "test 0"
test 0
echo
echo "test 2"
test 2
结果:
test 1
arg1 = 1
1
test 0
arg1 = 0
0
test 2
arg1 = 2
0
怎么?有没有搞错,这两个函数几乎没什么区别,对,它几乎就是return和echo不一样,但是有一点一定要注意,不能向标准输出一些不是结果的东西(也就是说,不能随便echo一些不需要的信息),比如调试信息,这些信息可以重定向到一个文件中解决,特别要注意的是,脚本中用到其它类似grep这样的命令的时候,一定要记得1>/dev/null 2>&1来空这些输出信息输出到空设备,避免这些命令的输出。
#! /bin/sh
function test()
{
echo "test here"
return 100
}
DD=`test`
#echo excute over
echo "return: $?"echo "DD: $DD"
如上shell代码段,执行结果是
return: 100
DD: test here
如果 把#echo excute over注释去掉,执行结果是
excute over
return: 0
DD: test here
也就是说:$?是接收上一条函数的执行结果,在例一中,$?接收test函数的执行结果,执行结果其实就是其返回值,就是return 传出来的数值(return只能是数字,不能是字符串之类的),如果函数中没有显式调用return返回出来状态,那么系统会使用函数中最后一条shell指令的执行结果作为返回值,如果函数test()最后一条指令调用其他函数,如:test1(),那么test的返回值就是test1的返回值。
DD是作为一个变量接收函数的标准输出,比如echo产生出来的信息,不包括报错之类的信息,如上如果函数test中调用test1,那么test和test1中的标准输出都会赋值给变量DD.
注意:DD=`test` , ` `符号不是单引号‘’,而是ESC下面的那个符号,该句话的意思是执行函数test结果赋值给DD,如果是单引号的话这句话是把字符串“test”赋值给变量DD,注意,这句话的执行结果不是赋值是否成功,而是函数的执行状态
 
总结:所以,可以总结一下函数返回值获取的方法:
1)用变量接收函数返回值,函数用echo等标准输出将要返回的东西打印出来。
2)用$?来接收函数的执行状态,但是$?要紧跟在函数调用处的后面。

转载请注明:流年似水 » Shell之函数

喜欢 (0)or分享 (0)

Warning: copy(https://cn.gravatar.com/avatar/?s=54&d=%2Fwp-content%2Fthemes%2Fyusi1.0%2Fimg%2Fdefault.png&r=g): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 239

Warning: copy(/wp-content/themes/yusi1.0/img/default.png): failed to open stream: No such file or directory in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 243
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址