shell函数详解,基本使用进阶使用

一、基本使用

shell中可以自定义函数,然后在脚本中可调用,但必须保证先定义再使用。

1. 函数定义

function_name () {
    ....
    [return int]
}
# 或者
function function_name() {
   ....
}

重点:

  • function关键字可以省略,但加上更容易让人理解这是一个函数定义。
  • 可以手动调用return返回,也可以省略,如果省略将以最后一条命令运行结果作为返回值
  • 注意!!return只能返回数字0~255

2. 函数调用

function_name parm1 parm2

调用函数仅使用其函数名即可,后面跟函数的参数,使用方式见后面示例。

3. 获取参数

在函数内部,使用 $n 的方式获取输入参数,数字n表示第几个参数。如 $1 表示第一个参数,$2 表示第二个参数,但如果要获取第十个参数,不能使用 $10 而是要使用 ${10}

另外还有几个特殊符号来处理参数:

字符说明
$n获取第n个参数,这里n不是字母n,而是指某个数字,如 $1${12}
$#参数个数
$*所有函数的参数
$@与$*相同,区别是加引号时返回参数的形式不一样
$?获取函数返回值

$* 与 $@ 区别:

  • 相同点:都是表示所有参数。
  • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,则 “$*” 表示 “1 2 3”(一个参数),而 “$@” 表示 “1” “2” “3”(三个参数)。

4. 获取返回值

使用 $? 获取返回值,值得注意的是,函数的返回值只能是0~255

后面会介绍一些方法去获取一些非数字的返回值的情况。

5. 示例

#!/bin/bash

# 定义一个加法函数,注意这里返回的值必须在0~255之间,否则会报错
function add() {
    return $(($1 + $2))
}

# 直接函数名加参数列表调用即可
add 1 2

# 使用$?获取函数输出,这里会打印出 3
echo $?

二、进阶使用

前面我们得知函数的返回值只能是0~255的数字,但需要返回超过这个范围的数字,或者需要返回字符串、数组、map等类型的数据时,该怎么做呢?

另外我们也知道了可以使用 $n 可以获取第n个参数,但如果想传入数组、map这样的特殊参数,又该如何做呢?

这些问题可以通过如下内容一步步掌握。

1. 全局变量和局部变量

默认情况下,所有变量都是全局的,即函数中定义的变量也可以在函数外使用,函数中也可以直接给函数外的变量赋值。所以我们可以使用全局变量来绕开返回值限制的问题

如果我们希望某个变量仅仅只是函数内局部可见,避免函数外同名变量的相互影响,可以使用 local 关键字定义变量。

示例:

#!/bin/bash

#在函数中直接使用第一个参数给变量赋值
function foo() {
    global_var=$1 #定义一个全局变量,并赋值
    local local_var=$1 #定义一个局部变量,并赋值
}


echo "before function, global_var: $global_var"
echo "before function: local_var: $local_var"

foo "apple" #调用函数

echo "after function: global_var: $global_var"
echo "after function: local_var: $local_var"

执行结果为:

before function, global_var:
before function: local_var:
after function: global_var: apple
after function: local_var:

可以看到,全局变量在函数外可以成功赋值和使用,而局部变量则不行。

不过,有时候我们为了一些独立性、封装性、解耦合等要求,并不希望都使用全局变量,该如何做可以继续阅读。

2. 使用反引号``获取函数输出

shell中使用反引号包含的字符串,会被当做一条命令来执行,返回值是命令的执行的结果,如:

echo `date`
# 打印结果为:2022年 05月 06日 星期五 15:14:26 CST

所以我们可以在函数中调用echo来返回我们想要返回的任一结果,然后通过反引号获取echo的输出来实现获取特殊的返回结果,如:

#!/bin/bash

#通过echo返回一个字符串
function foo() {
    echo "this is function echo with parameter: $1"
}

#通过echo返回一个超过255的数字
function bar() {
    echo 1024
}

#使用var1和var2接收函数的返回
var1=`foo "apple"`
var2=`bar`

#打印出var1和var2
echo -e "$var1\n$var2"

执行结果:

this is function echo with parameter: apple
1024

3. 给函数传递数组,函数返回数组

关于shell中数组的相关知识,本文暂不介绍,这里假设读者已经掌握了。

函数参数本身其实是识别不了数组,但我们可以把所有参数构建成一个新的数组来使用,再利用前面两点的知识,可以如下使用:

#!/bin/bash

function double_array() {
    local array=(`echo "$@"`) #获取输出参数并转化为一个数组类型变量
    local size="$#" #获取数组长度,也可以通过${#array[@]}得到
    local i
    for ((i = 0; i < size; i++)) {
        array[$i]=$[ $[array[$i]] * 2 ] #遍历并乘2
    }
    echo "${array[*]}" #通过echo输出,注意函数内不要加多余的echo语句
}

a=(1 2 3 4 5) #定义一个数组变量

b=(`double_array ${a[*]}`) #将a传入函数,并得到数组b

echo "a: ${a[*]}, size: ${#a[@]}"
echo "b: ${b[*]}, size: ${#b[@]}"

执行结果:

a: 1 2 3 4 5, size: 5
b: 2 4 6 8 10, size: 5

4. 给函数传递map,函数返回map

a. 扩展知识:shell中的map使用

bash 4.1.2版本后加入了map类型,使用 declare -A 定义。如:

declare -A m=(["a"]="apple" ["b"]="boy" ["c"]="cat" ["d"]="dog")

echo "size: ${#m[@]}" #输出map长度
echo "keys: ${!m[@]}" #输出map所有key
echo "values: ${m[@]}" #输出map所有value
echo "m[c]: ${m["c"]}" #输出map中key1对应的值

执行结果:

size: 4
keys: a b c d
values: apple boy cat dog
m[c]: cat

b. 给函数传递map

map比数组复杂挺多的,没法一次性拿到map所有的字符串信息,只能自己拼接一下了。

#!/bin/bash

function use_map() {
    declare -A map=$1
    echo "in function ***************"
    echo "size: ${#map[@]}" #输出map长度
    echo "keys: ${!map[@]}" #输出map所有key
    echo "values: ${map[@]}" #输出map所有value
}

# 这里申明的是一个字符串变量,map变量的话需要先手动转换成字符串
map_str="(["a"]="apple" ["b"]="boy" ["c"]="cat" ["d"]="dog")"

# 注意需要加双引号,当作一个参数传递进去
use_map "$map_str"

# 函数内的map是局部的,这里打印不出map的信息
echo -e "\nout function ***************"
echo "size: ${#map[@]}" #输出map长度
echo "keys: ${!map[@]}" #输出map所有key
echo "values: ${map[@]}" #输出map所有value

执行结果:

in function ***************
size: 4
keys: a b c d
values: apple boy cat dog

out function ***************
size: 0
keys:
values:

c. 函数输出map

要输出一个map,在函数中拼接一个map格式的字符串返回即可。

#!/bin/bash

function get_map() {
    local result=""
    local keys=("a" "b" "c" "d")
    local values=("apple" "boy" "cat" "dog")
    local size=${#keys[@]}
    for ((i = 0; i < size; i++)) {
        result="$result [${keys[$i]}]=${values[$i]}"
    }
    echo "($result)"
}

declare -A map=`get_map`

echo "size: ${#map[@]}" #输出map长度
echo "keys: ${!map[@]}" #输出map所有key
echo "values: ${map[@]}" #输出map所有value

执行结果:

size: 4
keys: a b c d
values: apple boy cat dog

map整体使用起来比数组麻烦了挺多的,也可以考虑直接定义一个全局变量的map使用。

热门文章

CVPR 2021 | 腾讯AI Lab入选论文解读

本文转载自腾讯AI实验室CVPR&#xff08;Conference on Computer Vision and Pattern Recognition&#xff09;是计算机视觉三大顶会之一&#xff0c;也是中国计算机学会推荐的人工智能领域的A类会议。CVPR 2021 接收结果已于本月公布。今年有效投稿多达7500篇&#xff0c;一共…

ECCV 2018 | 腾讯AI Lab解读19篇入选论文

感谢阅读腾讯AI Lab微信号第33篇文章&#xff0c;今年是腾讯AI Lab第二次参加ECCV&#xff0c;共有19篇文章入选&#xff0c;以下为摘要解读。计算机视觉欧洲大会&#xff08;European Conference on Computer Vision&#xff0c;简称ECCV&#xff09;将于9月8日-14日在德国慕尼…

【github】机器学习(Machine Learning)深度学习(Deep Learning)资料

转自&#xff1a;https://github.com/ty4z2008/Qix/blob/master/dl.md# 《Brief History of Machine Learning》 介绍:这是一篇介绍机器学习历史的文章&#xff0c;介绍很全面&#xff0c;从感知机、神经网络、决策树、SVM、Adaboost到随机森林、Deep Learning.译文part1 《De…

CVPR 2019 论文汇总(按方向划分,0506 更新中)

作为计算机视觉领域三大顶会之一&#xff0c;CVPR2019&#xff08;2019.6.16-6.19在美国洛杉矶举办&#xff09;被CVers 重点关注。目前CVPR 2019 接收结果已经出来啦&#xff0c;相关报道&#xff1a;1300篇&#xff01;CVPR2019接收结果公布&#xff0c;你中了吗&#xff1f;…

人脸识别 | 论文参考

人脸识别技术资料整理 2019/04/06 ISRN: Improved Selective Refinement Network for Face Detection DSFD: Dual Shot Face Detector PyramidBox: High Performance Detector for Finding Tiny Face VIM-FD: Robust and High Performance Face Detector SHF: Robust Fac…

《论工业社会及其未来》—泰德.卡辛斯基

中文译文基于1996年中国文史出版社《轰炸文明——发往人类未来的死亡通知单》&#xff0c;原译者王小东 INTRODUCTION 介绍 1. The Industrial Revolution and itsconsequences have been a disaster for the human race. They have greatlyincreased the life-expectancy of t…

七夕礼物 | 全网最火的钉子绕线图制作教程

最近在抖音经常看到这类视频&#xff0c;仔细一想&#xff0c;也对七夕快到了&#xff0c;男同胞们该准备给小姐姐送小礼物了&#xff0c;大邓提前给大家分享一个idea-制作钉子绕线画教程&#xff0c;制作步骤如下打开StringArtGenerator网站选择一张高对比度的大头照上传&…

deepfacelive实时AI换脸使用教程

deepfacelab作者新项目&#xff0c;deepfacelive昨日发布 支持实时AI换脸&#xff0c;支持摄像头或本地文件实时换&#xff0c;效果相当牛逼 3080ti速度差不多30fps&#xff0c;自带遮挡处理 软件已经汉化&#xff0c;由dfldata.xyz滚石汉化 软件下载地址和使用教程请前往dfl…

TESLA GPU——K80

异构计算再添新秀TESLA GPU特性Tesla K80Tesla K40GPU2 颗 Kepler GK2101 Kepler GK110B峰值双精度浮点性能2.91 Tflops (GPU 动态提速频率)1.87 Tflops (基础频率)1.66 Tflops (GPU 动态提速频率)1.43 Tflops (基础频率)峰值单精度浮点性能8.74 Tflops (GPU 动态提速频率)5.6 …

Github上冉冉升起的10大Python项目

GitHub是在线代码仓库&#xff0c;Python作为一种令人惊叹的通用编程语言&#xff0c;已经被成千上万的开发人员用来构建各种有趣和有用的项目。在本文中&#xff0c;我们将介绍一些用Python构建的GitHub上最好的项目。 1. Manim Stars&#xff1a;26.2k Forked by&#xff…

华为fusion compute桌面云开机花屏处理方法

在部署完虚拟化V100R003C10SPC605平台&#xff0c;创建虚机并给虚拟机安装完Redhat 6.5操作系统重启后&#xff0c;出现花屏现象&#xff0c;无法进入图形界面&#xff1b;可以正常进入命令行模式&#xff0c;并且可以正常使用。 Redhat 6.5版本中自带的xorg-x11-drv-cirrus图形…

Unity Shader 闪光特效

Unity Shader源代码如下&#xff1a; Shader "Custom/Flash" { Properties { _MainTex ("Texture", 2D) "white" {} _Speed("Flash_Speed", Float) 1.0 _Angle("Flash_Angle",Range(-1.57,1.57)) 0.78 _Length("Fla…

MFC 获取摄像头 实时显示并图像处理(光斑自动对焦)

第一次写CSDN论文&#xff0c;给自己的毕设做个总结。 对于我这个常年用C语言的渣渣&#xff0c;突然接触需要C的MFC和Opencv&#xff0c;就变成毕设困难户了&#xff0c;好在有CSDN上大神们的帮助和同班同学热心的指导&#xff0c;总算是上手了mfc和Opencv。 废话不多说&#…

人工智能---A*算法

文章目录实验目的实验内容实验器材实验过程与结果代码实验目的 以八数码问题作为对象&#xff0c; 利用A*算法求解并在屏幕上动态显示OPEN表的结点和评估函 数最小的结点 实验内容 使用两种启发式函数并比较两者的不同之处。 实验器材 语言&#xff1a; Python、编译器&am…

我爱机器学习网深度学习类别文章汇总

机器学习领域的几种主要学习方式 解密最接近人脑的智能学习机器——深度学习及并行化实现 5 deep learning startups to follow in 2015 How to run the Caffe deep learning vision library on Nvidia’s Jetson mobile GPU board Hacker’s Guide to Neural Networks Go…

Android 监听双卡信号强度(附完整代码)

Android 监听双卡信号强度 监听单卡信号强度 监听单卡的信号强度非常简单直接用TelephonyManager.listen()去监听sim卡的信号强度.TelephonyManager mTelephonyManager (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE) mTelephonyManager.listen…

何凯明:Single Image Haze Removal Using Dark Channel Prior[CVPR 2009]

在图像去雾领域&#xff0c;几乎没有人不知道《Single Image Haze Removal Using Dark Channel Prior》这篇文章&#xff0c;该文是2009年CVPR最佳论文。作者何凯明博士&#xff0c;2007年清华大学毕业&#xff0c;2011年香港中文大学博士毕业。 soft matting过程比较复杂&…

CS结构与BS结构

CS结构与BS结构 基本概述 B/S结构即浏览器和服务器结构。它是随着Internet技术的兴起&#xff0c;对C/S结构的一种变化或者改进的结构。在这种结构下&#xff0c;用户工作界面是通过WWW浏览器来实现&#xff0c;极少部分事务逻辑在前端(Browser)实现&#xff0c;但是主要事务逻…

2020年专升本没报名的同学还可以报名韩国专升本留学,免试入学

原标题:2020年专升本没报名的同学还可以报名韩国专升本留学,免试入学为了不断丰富自己的知识技能,提升学历,更多的专科学生选择参加专升本考试,但是,专升本的难度相信大家也都有所了解,一点也不亚于高考,而且普通专升本考试只有一次机会,那么专升本没考上难道就没有机…

补录——成人高考掉档后的“救命稻草”

原标题:补录——成人高考掉档后的“救命稻草”成人高考考试结束后,有一些同学核对了考试答案,觉得自己的分数不是很高,担心自己考不上,小编想和同学们说,就算没被录取也不要担心,因为成人高考还会有补录,补录可是成人高考掉档后的最后一根救命稻草,同学们可要牢牢抓住…

养生不是消费,而是人生投资!别再和生命讨价还价了!

原标题:养生不是消费,而是人生投资!别再和生命讨价还价了!有人问我:为什么那么多人非要与生命和身体讨价还价?为何已经面临健康大问题了,还那么精打细算,甚至吝啬得够呛? 为何买房买车很大方,买衣购表很大方,请客喝酒很大方,就是对如何爱自己、投资自己的时候,却…

别让学历低限制了你的想象力!

原标题:别让学历低限制了你的想象力!你经历过这些吗? 想找个好工作,可是学历不够 想报考公务员,可是学历没达标 想报教师资格考试,可是有学历限制 想职位得到晋升,可是要求本科文凭 想在城市人才落户,可是学历太低没资格 …… 每当填写表格的时候,学历那栏总是…

学历提升的几种方法

原标题:学历提升的几种方法在生活和工作中我们可能会面临很多困难和问题,比如毕业了准备找工作,工作了准备买房结婚,结了婚要小孩,小孩大了要进好的学校等等问题。 而这些问题的解决的关键在于你有没有一份好的工作,稳定的收入,和广阔的人脉。但是这些都统统要建立在你的…

学历到底有多重要?来看看网友们怎么说吧

原标题:学历到底有多重要?来看看网友们怎么说吧有人会和你说,学历这玩意一点都不重要。 确实,学历没有一些人想象的那么重要, 但是……这东西就跟钱一样, 你有了才能说它不重要。 责任编辑:

不是学历选择了你,而是你选择了不一样的人生

原标题:不是学历选择了你,而是你选择了不一样的人生风,有大山可以挡; 云,有天空可以躺; 叶,有树根可以抗; 河,有大海可以装; 可我们没有学历的时候,该怎么办? 没学历的时候提升学历。 人生在世,你可以依靠的其实只有你自己而已,其他都是虚的 人在社会和职…

健康管理师是什么 2021年健康管理师报名入口

原标题:健康管理师是什么 2021年健康管理师报名入口健康管理师是从事个体和群体从营养和心理两方面健康的检测、分析、评估以及健康咨询、指导和危险因素干预等工作的专业人员。 健康管理师是什么 健康管理师是2005年10月劳动和社会保障部第四批正式发布的11个新职业之一。20…

福建2021成人高考各层次报名条件,成考专业有哪些?

原标题:福建2021成人高考各层次报名条件,成考专业有哪些?2021成人高考各层次报考条件包括专升本报考及高起专报考条件,考生可根据自身需求查看,本次信息仅供参考。 2021成人高考各层次报考条件信息采集于教育考试院,如有变化请以当年政策为准! 专科升本科:必须是已取得…

论“敲门砖”的重要性

原标题:论“敲门砖”的重要性日常生活、工作、考证等方方面面中,学历都在影响着我们的工作、提拔甚至收入,那么,学历到底在起着什么方面的作用呢?今天小思就给大家好好说下: 01class 学历是找工作的敲门砖 学历是一把钥匙,是学子们踏入社会的敲门砖,此时的学历对于用人…

Angular使用操作事件指令ng-click传多个参数示例

本文实例讲述了Angular使用操作事件指令ng-click传多个参数功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a;<!DOCTYPE html> <html ng-app"myApp"> <head><meta charset"UTF-8"><title>www.jb51.net angular n…

Angular: selector选择器

文章目录组件选择器作为组件来使用作为属性来使用作为类来使用组件选择器 angular中的selector将当前组件封装在selector组件选择器声明的形式中&#xff0c;然后在html中可以以对应的形式对组件进行调用。 举几个例子&#xff1a; 作为组件来使用 selector:"show-det…

ionicCLI Angular页面跳转

1、Component中的.html文件中item添加点击事件&#xff1a; <a class"home-menu-item" *ngFor"let item of menuItems" (click)"gotoPage(item)"><img class"" src"{{item.imgSrc}}"><span>{{item.subTi…

angular6项目部署到服务器上刷新页面404

angular6项目在本地访问正常&#xff0c;部署上去也可以访问&#xff0c;但刷新页面会404 解决办法&#xff1b;使用HashLocationStrategy 路由策略 //app.module.ts import { HashLocationStrategy, LocationStrategy } from angular/common;NgModule({providers: [{ provid…

angular 循环单选框默认选中无效的解决办法 ng-model 和ng-checked

最近做项目遇到一个问题&#xff0c;模态框弹出查询条件&#xff0c;里面循环几个单选框默认选中&#xff0c;然后有一个清空按钮&#xff0c;窗口样式如下。 但是这个单选框默认选中和清空这里我搞了一天&#xff0c;尝试了多种办法&#xff0c;用ng-model和ng-checked都敲了…

angular js 的select数据绑定

1.最初&#xff0c;循环数组&#xff0c;只知道用ng-repeat&#xff1b;后来才知道select不用ng-repeat也能实现循环输出&#xff08;ng-options&#xff0c;一定不要忘了末尾的s&#xff09;&#xff1a; 最初&#xff1a; <select id"column" name"colum…

angular+ng-zorro表格拖拽

angular集成了cdk drag-drop 来实现拖拽功能 app.modules.ts导入 import { DragDropModule } from angular/cdk/drag-drop; imports: [DragDropModule ]一、表格内拖拽排序 <nz-table [nzData]"sourceData" [nzFrontPagination]"false" [nzShowPagina…

浅谈angular依赖注入

一、什么是依赖注入&#xff1f; 首先&#xff0c;用最通俗的语言来说&#xff0c;某公司财务类要给员工发放工资&#xff0c;它需要人事类提供一个薪资标准&#xff0c;财务类想要完成工资发放&#xff0c;就必须实例化人事类&#xff0c;&#xff0c;也就是说财务类依赖于人…

angular脏检查原理及伪代码实现

我们经常听到angular的脏检查机制和数据的双向绑定&#xff0c;这两个词似乎已经是它的代名词了。那么从编程层面&#xff0c;这到底是什么鬼&#xff1f;当$scope的一个属性被改变时&#xff0c;界面可能会更新。那么为什么angular里面&#xff0c;修改$scope上的一个属性&…

Angular 2.0 预备库 Angular Starter Kit

Angular Starter Kit 详细介绍angular-next-starter-kit 是使用 Angular 1.x 开发的应用准备迁移到 Angular 2.0 的种子项目。Angular 2.0 引入了一些新概念和设计模式&#xff0c;但是 Angular 2.0 还有几个月才能在生产环境使用。为了能让 Angular 1.x 开发的应用使用 Angula…

angular2中在使用路由懒加载时候出现的错误

为什么80%的码农都做不了架构师&#xff1f;>>> ERROR in Cannot use in operator to search for providers in null 出现这个问题的原因是&#xff0c;在使用懒加载的时候&#xff0c;没有指定module&#xff0c;没有找到相关的提供信息。 const routes: Routes …

[Angular实战网易云]——2、构建目录

构建目录 使用过angular&#xff0c;就会知道什么是模块化&#xff0c;顾名思义&#xff0c;就是把整体分割成能够单独运行的一个各模块&#xff0c;这样做的好处有很多&#xff0c;比如实现逻辑更清晰、可读性强、团队开发分工明确,容易控制、充分利用可以重用代码、抽象出可…

angular.js指令集实现模态框拖动效果

define([application-configuration], function (app) { "use strict"; app.directive(draggable, [$document, function($document) {//模态框拖动指令 return function(scope, element, attr) {var startX 0, startY 0, x 0, y 0;element…

js面试题

1、介绍js的基本数据类型   答&#xff1a; Undefined、Null、Boolean、Number、String    2、js有哪些内置对象&#xff1f;  答&#xff1a;数据封装类对象&#xff1a;Object、Array、Boolean、Number 和 String   其他对象&#xff1a;Function、Arguments、Math、D…

Angular4.X 介绍

Angular4.X 介绍 写在前面 为什么突然有想学习一点 angular 的知识呢&#xff1f;因为前几天突然在头条看到一个帖子&#xff0c;说&#xff0c;现在JavaScript成功的干过Java成为最火的编程语言&#xff0c;而JavaScript中&#xff0c;最火的框架就是 Angular。而且他说不接受…