Shell中关于处理方法返回值问题详解

背景

如今,不会Linux的程序员都不意思说自己是程序员,而不会shell编程就不能说自己会Linux。通过shell编程,写一些工具批处理的时候,经常需要自定义函数。更复杂点的情况下,可能有需要返回一个值。

由于在shell的世界中,并不像其他编程语言,它不支持我们所熟悉的方法返回。本文一起总结一下如何优雅的解决返回值问题?

测试程序

我们一般通过$?来获取上一个语句的输出。看一下下面得测试语句:

新建testReturn脚本

returnString(){
 return $1
}
returnString $1
result=$?
echo "result=$result"

现在我们有一个testReturn的脚本,里面有一个returnString的方法,我们希望它能够直接返回我们输入的参数。
当我们分别以hello,500,12作为输入参数时,他的执行和输出情况是一样的么?

./testReturn hello
./testReturn 500
./testReturn 12

在心中试着猜一下可能的情况,现在我们来揭晓答案:

程序输出情况

在执行hello的时候,并没有输出hello,而是报了一个return只接受数字类型的错误

aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello
./testReturn: line 23: return: hello: numeric argument required
result=255

在执行500的时候,页没有输出500,而是输出了244

aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500
result=244

执行12的时候,终于正确了,返回12

aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12
result=12

异常分析

现在我们分析一下returnString这个方法,为什么会有这么多种输出情况呢?

首先他的写法显然是不严谨的,但也不是完全错误,比如输入12他就正确返回了。

return本身是shell里面的buildin函数,笔者总结了下,他有以下几个特征:

  • return可以返回数字状态,常常用于返回0,1,标识一个函数执行后是否成功
  • 注意return不可以返回非数字类型
  • 同时数字类型也有可能发生溢出现象

全局变量

如果我们就是要返回一个字符串,怎么办呢?可以通过定义全局变量来进行赋值,类似于静态变量/成员变量的写法,我们让他的作用域穿透整个上下文。

result=""
returnString(){
 result=$1
}
returnString $1
echo "result=$result"

再看一下输出,得到了我们需要的结果:

aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello
result=hello
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500
result=500
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12
result=12

但是这样写,会污染全局变量,并且result这个变量很容易在内部和外部都被修改,导致内部修改失效。

eval

除了return,还有其他一些buildin的关键字,比如eval,local。

默认在当前脚本定义的变量都是全局变量,在方法中则可以通过local来定义局部变量,这样可以避免全局变量污染.
同时结合eval赋值语句,来实现变量的修改

returnString(){
 local __result=$2
 eval $__result=$1
}
returnString $1 result
echo "result=$result"

同样我们也得到了希望的结果

aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello
result=hello
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500
result=500
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12
result=12

echo

最后在介绍一种方法,通过echo输出,结合command substitution。

这个command substitution也没有找到比较合适的翻译,姑且按字面意思翻译命令替换。

如果你的方法内部只有一处echo输出,那么也可以利用她来进行值得返回,不过这个就有点局限性,一定要确保方法内只有一次输出,否则就会出现赋值内容过多。

returnString(){
 local __result=$1
 echo $__result
}
# 或者 result=`returnString $1`
result=$(returnString $1)
echo "result=$result"

同样可以得到预期结果

aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello
result=hello
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500
result=500
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12
result=12

越界问题

现在我们已经有几种办法可以返回字符串了,那么return返回数字有时候正确,有时候又不正确是为什么呢?

我们知道return原本就是用于返回执行状态的,比如0,1.那么我们在返回500的时候,实际上是数据溢出了。

根据测试,我们推断shell的内置return承接返回值用的是一个字节的大小,也就是8位,最多可以输出无符号0-255的整形,范围之外的数据全部溢出显示。因此在使用return的时候,务必留意数值大小。

小结

通过shell命令可以很方便的写出一些小脚本,但是如果遇到逻辑复杂,建议通过其他更合适的预览来实现,比如Python,Golang之类。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • PowerShell函数一次返回多个返回值示例

    本文介绍在自定义PowerShell函数时,如何让函数返回值,如何接收返回值,如何让不相干的内容不放到返回值数组中. PowerShell函数体中的任何输出,一般来说,都会以返回值的形式返回给函数调用者.多个输出的内容是放到一个返回值数组中的. 比如有如下一个返回值测试的函数, 复制代码 代码如下: function Test-ReturnValue {     1     'Hello'     return Get-Date } 这个函数定义了三个返回值,调用的效果如下: 复制代码 代码如下

  • linux shell自定义函数(定义、返回值、变量作用域)介绍

    linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.下面说说它的定义方法,以及调用需要注意那些事项. 一.定义shell函数(define function) 语法: [ function ] funname [()] { action; [return int;] } 说明: 1.可以带function fun() 定义,也可以直接fun() 定义,不带任何参数. 2.参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值. retu

  • Linux Shell函数返回值

    Shell函数返回值,一般有3种方式:return,argv,echo 1) return 语句 shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回. 示例: #!/bin/bash - function mytest() { echo "arg1 = $1" if [ $1 = "1" ] ;then return 1 else return 0 fi } echo echo "mytest 1" mytest 1 e

  • shell脚本中执行python脚本并接收其返回值的例子

    1.在shell脚本执行python脚本时,需要通过python脚本的返回值来判断后面程序要执行的命令 例:有两个py程序  hello.py 复制代码 代码如下: def main():     print "Hello" if __name__=='__main__':     main() world.py def main():     print "Hello" if __name__=='__main__':     main() shell 脚本 te

  • linux shell 自定义函数方法(定义、返回值、变量作用域)

    一.定义shell函数(define function) 语法: [ function ] funname [()] { action; [return int;] } 说明: 1.可以带function fun() 定义,也可以直接fun() 定义,不带任何参数. 2.参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值. return后跟数值n(0-255 实例(testfun1.sh): #!/bin/sh fSum 3 2; function fSum

  • PowerShell函数指定返回值类型实例

    本文介绍在自定义PowerShell函数时,如何设置返回值的数据类型.PowerShell函数的返回值可以有类型,也可以没有类型,跟输入参数相似.     定义PowerShell函数的返回值类型,要使用OutputType这个指令.将这个指令放到param指令之前即可实现对返回值类型的定义. 复制代码 代码如下: function Test-IntelliSense {     [OutputType('System.DateTime')]     param()     return Get

  • Shell中函数返回值超出问题

    1.前言 快半年没有写博客了,荒废了很久,工作中的杂事太多,自己越来越懒了.为了鞭策自己成长,还是要坚持写写博客,记录自己的成长. 2.shell函数介绍 语法: 复制代码 代码如下: [ function ] funname [()] {   action;     [return int;]  } 说明: (1)可以带function fun()  定义,也可以直接fun() 定义,不带任何参数. (2)参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值

  • Shell中关于处理方法返回值问题详解

    背景 如今,不会Linux的程序员都不意思说自己是程序员,而不会shell编程就不能说自己会Linux.通过shell编程,写一些工具批处理的时候,经常需要自定义函数.更复杂点的情况下,可能有需要返回一个值. 由于在shell的世界中,并不像其他编程语言,它不支持我们所熟悉的方法返回.本文一起总结一下如何优雅的解决返回值问题? 测试程序 我们一般通过$?来获取上一个语句的输出.看一下下面得测试语句: 新建testReturn脚本 returnString(){ return $1 } retur

  • Django中get()和filter()返回值区别详解

    先上官方文档! filter(**kwargs) 返回包含与给定查找参数匹配的对象的新查询集. 简单来说,返回一个又对象组成的查询集合 get(**kwargs) 返回与给定查找参数匹配的对象,该对象应采用字段查找中描述的格式. 例子 例如在Model中有一个Order类,包含一个id字段,输入 id 为2019 字段的 id 1.get()方法 orders = Orders.objects.get(id=20190003) print(order) 先查看orders是什么,结果为 Orde

  • C++中Covariant返回值类型详解

    目录 前言 什么是协变返回值类型(Covariant) 协变返回值类型(Covariant)的作用 前言 C++中当子类覆写(override)父类虚函数时,子类函数的返回值类型可以和父类函数的返回值类型不一致吗?先说结论:可以,但当且仅当它们的返回值类型是协变返回值类型(Covariant)时可以.C++中gcc从3.4开始支持这一特性. 什么是协变返回值类型(Covariant) 函数的协变返回值类型指的是子类中的成员函数的返回值类型不必严格等同与该函数所重写的父类中的函数的返回值类型,而可

  • PHP方法的返回值示例详解

    前言 不仅是PHP,大部分编程语言的函数或者叫方法,都可以用return来定义方法的返回值.从函数这个叫法来看,本身它就是一个计算操作,因此,计算总会有个结果,如果你在方法体中处理了结果,比如进行了持久化保存,那么这个函数就不用返回任何内容.而计算的结果是要给外部使用的,这时候就要将计算结果进行返回了. return关键字 function testA($a, $b) { echo $a + $b; } var_dump(testA(1, 2)); // NULL function testB(

  • C# WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇C#进阶系列--WebApi接口传参不再困惑:传参详解,这篇博文内容本身很基础,没想到引起很多园友关注,感谢大家的支持.作为程序猿,我们都知道参数和返回值是编程领域不可分割的两大块,此前分享了下WebApi的传参机制,今天再来看看WebApi里面另一个重要而又基础的知识点:返回值.还是那句话:本篇针对初初使用WebApi的同学们,比较基础,有兴趣的且看看.

  • java中重写父类方法加不加@Override详解

    java重写父类方法加不加@Override 这个是我在刚学习java时遇到的问题,希望能给像我一样的新手学习时带来帮助,如有错误请指正,谢谢! class Father{ public String name; public int age; public Father(){ } public void work(){ System.out.println("盖房子"); } } class Son extends Father{ public int weight; public

  • Spring Mvc中传递参数方法之url/requestMapping详解

    前言 相信大家在使用spring的项目中,前台传递参数到后台是经常遇到的事, 我们必须熟练掌握一些常用的参数传递方式和注解的使用,本文将给大家介绍关于Spring Mvc中传递参数方法之url/requestMapping的相关内容,分享出来供大家参考学习,话不多说,直接上正文. 方法如下 1. @requestMapping: 类级别和方法级别的注解, 指明前后台解析的路径. 有value属性(一个参数时默认)指定url路径解析,method属性指定提交方式(默认为get提交) @Reques

  • Selenium执行Javascript脚本参数及返回值过程详解

    在Selenium中可以使用drvier.execute_script()来执行Javascript脚本,支持多行语句. 使用Javascript可以实现以下功能: 移除元素隐藏.禁用.只读等限制属性 为元素添加id或高亮样式 页面滚动 富文本框输入(HTML注入) 获取页面信息 使用Javascript参数 在使用Javascript语句时,还可以动态传入参数或元素对象,Javascript语句中使用占位符"argument[n]"来表示取第几个参数,如: js = "ar

  • Postman动态获取返回值过程详解

    前面我们总结了postman接口依赖获取cookie的方法,奈何今天老大新给的接口是依赖于token的,大家都知道,postman支持的脚本语言是JavaScript,而我对于JavaScript简直就是小白,于是乎,开始一顿在网上搜,奈何网上适合小白的资料少之又少,费了老鼻子劲才把token从返回的response中提取出来,现在总结在这里,方便日后的查阅,同时也为各位小伙伴们提供一个解题的思路. 先大概讲一下我们的业务场景,就是一个充值的接口,需要依赖登录返回的token,我想做的事情就是,

  • Android onTouchEvent事件中onTouch方法返回值(介绍)

    1.若return false说明没有成功执行onTouch事件,在执行完onTouch里面的代码之后,onTouch事件并没有结束.因此某些组件如Gallery会自动执行它所在view里onTouch方法的代码.若在onTouch方法里面增加你的代码并且最后return false就会执行你在OnTouch方法中的处理操作了. 2.若return true说明你已经成功执行onTouch方法了,在执行完onTouch中的代码之后,这个onTouch事件就结束了.也不会再调用组件如Gallery

随机推荐