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 > file
将 stdout
重定向到 file
,command < file
将stdin
重定向到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