shell脚本学习(四)

目录

  • 函数
  • 输入输出重定向
  • 文件包含

1、函数

函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,Shell 也支持函数。Shell 函数必须先定义后使用。
Shell 函数的定义格式如下:

function_name () {
    list of commands
    [ return value ]
}

也可以在函数名前加上关键字 function

function function_name () {
    list of commands
    [ return value ]
}

函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”
如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
示例一:无返回值

hello(){
    echo "hello world"
}
hello

输出:

hello world

调用函数只需要给出函数名,不需要加括号.
示例二:

hello(){
    echo "请输入数字:"
    read num1
    echo "请输入数字:"
    read num2
    return $(($num1 + $num2))
    #return `expr $nun1 + $num2`
}
hello
result=$?
echo "运行结果:$result"

运行结果:

请输入数字:
2
请输入数字:
4
运行结果:6

函数返回值在调用该函数后通过 $? 来获得.
实例三:函数嵌套

print(){
    echo "函数的嵌套"
}
hello(){
    print
}
hello

输出:

函数的嵌套

像删除变量一样,删除函数也可以使用 unset 命令,不过要加上-f选项,如下所示

$unset -f function_name
函数参数

Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
示例:

func_parameter(){
    echo "参数1:$1"
    echo "参数4:$4"
    echo "参数9:$9"
    echo "参数10:$10"
    echo "参数12:$12"
}
func_parameter  2 3 4 5 6 7 8 9 10 11 12 13

输出:

参数1:2
参数4:5
参数9:10
参数10:20
参数12:22

可以看到结果有问题,哪里来的20、22?

注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数
$10被解释成${1}0,因为${1}是2,然后再和0拼接就成了20
$12被解释成${1}2,因为${1}是2,然后再和2拼接就成了21

正确写法:

func_parameter(){
    echo "参数1:$1"
    echo "参数4:$4"
    echo "参数9:$9"
    echo "参数10:${10}"
    echo "参数12:${12}"
}
func_parameter  2 3 4 5 6 7 8 9 10 11 12 13

输出:

参数1:2
参数4:5
参数9:10
参数10:11
参数12:13

另外,还有几个特殊变量用来处理参数,前面已经提到:


2、输入输出重定向

Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。

输出重定向

命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向.
命令输出重定向的语法为:

$ command > file

这样,输出到显示器的内容就可以被重定向到文件。
例如,下面的命令在显示器上不会看到任何输出:

$ who > users

打开生成的users文件,看到输出内容:

chenzhichao console  Mar  3 10:15 
chenzhichao ttys001  Mar  6 09:48 
chenzhichao ttys003  Mar 16 14:59 
chenzhichao ttys007  Mar  7 14:33 

输出重定向会覆盖文件内容,如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,
示例:

echo "hello world" >> users
echo "哈哈哈😄" >> users
cat users

输出:

hello world
哈哈哈😄

使用 cat 命令查看文件内容

输入重定向

和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

command < file

这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

注意:输出重定向是大于号(>),输入重定向是小于号(<)。

示例:计算 users 文件中的行数,可以使用下面的命令:

wc -l users

输出2 users
也可以将输入重定向到 users 文件:

wc -l < users

输出:2
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > filestdout 重定向到 filecommand < filestdin 重定向到file

示例:users文件内容进行大小写转换,然后重新输出到 > users2

tr 'a-z' 'A-Z' < users > users2 

示例:用bc命令来计算cal.txt输入中的内容

echo 1+2 > cal.txt 
bc < cal.txt  

示例:用sort命令来对输入文件排序,排序后重定向到输出文件

$ cat fruits_in  
tomato  
strawberry  
pear  
apple  
cherry  
$ sort < fruits_in > fruits_out  
$ cat fruits_out  
apple  
cherry  
pear  
strawberry  
tomato  
Here Document:

Here Document:是Shell中的一种特殊的重定向方式,它的基本的形式如下:

command << delimiter  
    document  
delimiter  

它的作用是将两个delimiter之间的内容(document) 作为输入传递给command. 最主要的用途:用于脚本命令行交互中.

  • 开始的delimiter前后的空格会被忽略掉.
  • 结尾的delimiter一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和tab缩进
  • delimiter可以使任何tag,只要满足上面两个条件
  • Here Document可用于命令行中,或脚本里面

示例1:用wc -l命令计算document的行数

wc -l << TEXT
    line 1
    line 2
    line 3
    line 4
TEXT

输出4
示例2:用cat命令将here docuemnt读取出来

cat << TAG
    hello
    apple
    😁
TAG

输出:

    hello
    apple
    😁

3、文件包含

和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。
Shell 文件包含的语法格式如下:

. filename
或
source filename

两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格
示例:创建脚本test2.sh,并添加内容:

str="this is a string"

再创建test.sh,添加代码:

#. ./test2.sh
source ./test2.sh
echo $str

输出:

this is a string
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 基础 头文件 #!/bin/bash 或者#!/bin/sh #!约定的标记,如IOS的Import 执行文件时需...
    ZMJun阅读 1,224评论 1 2
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,135评论 2 34
  • 简介 shell 是类 UNIX 系统的外壳,使用 shell 用于实现人机交互的目的,我们通过它可以与内核之间进...
    noparkinghere阅读 754评论 0 1
  • bash学习 参考 Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)Linux 入门公开课...
    cndaqiang阅读 767评论 0 1
  • 本文笔记源自这里——[实验楼]欢迎大家在下面交流其中有问题的地方喜欢请点收藏,每日更新(全部已亲自实践). 一. ...
    东皇Amrzs阅读 3,963评论 7 54