Shell编程中关于函数退出状态码的讨论

2024-09-20 10:03:53 浏览数 (1)

最近在学习《Linux命令行和shell脚本编程大全》(第四版)这本书,对于自己遇到的问题以及通过搜索引擎和书籍中的解决方案进行一个案例的剖析,希望对于像我这样的初学者,有一个帮助。

当我们使用python的思维来理解shell中的return返回值的时候,我们对于数据的结果总是存在困惑,如何将这种困惑打消,就是接下来的文章想要说明的事情。

0 函数退出状态码的形式

函数运行结束,会生成一个状态码,或者不准确的称函数的返回值。

函数退出码具体有三种方式:

a. 默认退出码

b. 使用return关键字

c. 使用变量输出

1 默认退出码

我们通过$? 放在运行函数的后面,即可看到函数的退出码,如下:

代码语言:shell复制
#!/bin/bash
func() {
        echo "this is the first line of the function"
}
echo "Testing the function."
func
echo "The exit code is $?"

结果:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sh fun_status_code.sh 
Testing the function.
this is the first line of the function
The exit code is 0

通过上面的例子可以看到:

第一、$? 紧跟着函数运行行,这样才能获取到函数运行的状态码

第二、函数运行成功的退出码为0,如果未成功则为非0,因为退出码为0-255的256个可能,并且仅能显示0~255这256个数字。

第三、这里存在一个问题,函数退出码仅能说明函数内有错误,但是无法说明具体哪里出问题,如下:

代码语言:shell复制
#!/bin/bash
func() {
        echo "this is the first line of the function"
        ls badfile
        echo "hhhh"
}
echo "Testing the function."
func
echo "The exit code is $?"

结果:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sh fun_status_code.sh 
Testing the function.
this is the first line of the function
ls: cannot access 'badfile': No such file or directory
hhhh
The exit code is 0

从这个例子可以看出,尽管func函数体中有失败的脚本,但是由于函数最后一行是被正确执行的,因此函数退出码依然为0。 这个特性导致使用默认退出码是一个不恰当的方式。

2 使用return命令

return 命令返回退出状态码是一件容易混淆的事情。如何正确理解呢,这里再做一次强调:

第一、退出状态码仅在[0, 255] 的区间范围内,不会产生其他值,因此,不是return啥就返回啥。

第二、如果return的是文本,那么跟其他语言的返回值是同样的道理。

第三、如果return的值超过255,那么就会对该值与256求余数,得到最后的返回值。

具体见示例一【正常退出码】:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# cat fun_status_code.sh 
#!/bin/bash
func() {
	echo "this is the first line of the function"
	return 33
}
func
echo "the exit code is $?"

结果:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sh fun_status_code.sh 
this is the first line of the function
the exit code is 33

示例二【大于255的退出码】

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# cat fun_status_code.sh 
#!/bin/bash
func() {
	echo "this is the first line of the function"
	return $[ "$1" * 2 ]
}
func $1
echo "the exit code is $?"

结果:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sh fun_status_code.sh 150
this is the first line of the function
the exit code is 44

$1 为150,在return中进行了double的计算为300,那么按照mod(300,256),求余数为44,所以,函数退出码为44。

3 使用变量进行输出

请看如下示例:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# cat fun_status_code.sh 
#!/bin/bash
func() {
	echo "this is the first line of the function"
	echo $[ "$1" * 2 ]
}
result=$(func $1)
echo "the exit code is $result"

结果:

代码语言:shell复制
[root@iZuf6gxtsgxni1r88kx9rtZ linux_cmd]# sh fun_status_code.sh 150
the exit code is this is the first line of the function
300

使用echo其本质上是一个正常函数的返回值,通过返回值来作为退出码,并且范围是任意定的,不需要在[0, 255] 的范围的局限。

0 人点赞