Linux下的shell编程(六)--函数,重定向,文件

一、Shell函数:Shell函数返回值、删除函数、在终端调用函数

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


Shell
函数的定义格式如下:

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

如果你愿意,也可以在函数名前加上关键字function

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

函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
#
一定要有返回值的意思
Shell
函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果return其他数据,比如一个字符串,往往会得到错误提示:“numericargumentrequired”

如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。

先来看一个例子:



  1. #!/bin/bash  

  2. # Define your function here  

  3. Hello () {  

  4.    echo "Url is http://see.xidian.edu.cn/cpp/shell/"  

  5. }  

  6. # Invoke your function  

  7. Hello  

运行结果:

$./test.sh
Hello World
$

调用函数只需要给出函数名,不需要加括号。

再来看一个带有return语句的函数:


  1. #!/bin/bash  

  2. funWithReturn(){  

  3.     echo "The function is to get the sum of two numbers..."  

  4.     echo -n "Input first number: "   # echo 附带自动换行

  5.     read aNum  

  6.     echo -n "Input another number: "  

  7.     read anotherNum  

  8.     echo "The two numbers are $aNum and $anotherNum !"  

  9.     return $(($aNum+$anotherNum))  

  10. }  

  11. funWithReturn  

  12. # Capture value returnd by last command  

  13. ret=$?   # $?--上个命令的退出状态或者函数的返回值

  14. echo "The sum of two numbers is $ret !"  

运行结果:

The function is to get the sum of two numbers...
Input first number: 25
Input another number: 50
The two numbers are 25 and 50 !
The sum of two numbers is 75 !

函数返回值在调用该函数后通过$?来获得。

再来看一个函数嵌套的例子:#在一个函数里面调用另一个函数


  1. #!/bin/bash  

  2. # Calling one function from another  

  3. number_one () {  

  4.    echo "Url_1 is http://see.xidian.edu.cn/cpp/shell/"  

  5.    number_two  

  6. }  

  7. number_two () {  

  8.    echo "Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/"  

  9. }  

  10. number_one  

运行结果

Url_1 is http://see.xidian.edu.cn/cpp/shell/
Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/

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


  1. $unset .f function_name  

如果你希望直接从终端调用函数,可以将函数定义在主目录下的.profile文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用。#没有成功



二、Shell函数参数

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

带参数的函数示例:


  1. #!/bin/bash  

  2. funWithParam(){  

  3.     echo "The value of the first parameter is $1 !"  

  4.     echo "The value of the second parameter is $2 !"  

  5.     echo "The value of the tenth parameter is $10 !"  

  6.     echo "The value of the tenth parameter is ${10} !"  

  7.     echo "The value of the eleventh parameter is ${11} !"  

  8.     echo "The amount of the parameters is $# !"  # 参数个数  

  9.     echo "The string of the parameters is $* !"  # 传递给函数的所有参数  

  10. }  

  11. funWithParam 1 2 3 4 5 6 7 8 9 34 73  

运行脚本:

The value of the first parameter is 1 !
The value of the second parameter is 2 !
The value of the tenth parameter is 10 !
The value of the tenth parameter is 34 !
The value of the eleventh parameter is 73 !
The amount of the parameters is 11 !
The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"

注意,$10不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数

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

特殊变量

说明

$#

传递给函数的参数个数。

$*

显示所有传递给函数的参数。

$@

$*相同,但是略有区别

$?

函数的返回值。





三、Shell输入输出重定向:ShellHere Document/dev/null文件

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

输出重定向

命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。
#
将命令执行后的结果以字符串的形式输出到文件中
命令输出重定向的语法为:

$ command > file

这样,输出到显示器的内容就可以被重定向到文件。

例如,下面的命令在显示器上不会看到任何输出:

$ who > users

打开users文件,可以看到下面的内容:

$ cat users
oko         tty01   Sep 12 07:30
ai          tty15   Sep 12 13:32
ruth        tty21   Sep 12 10:10
pat         tty24   Sep 12 13:07
steve       tty25   Sep 12 13:03
$

只有一个>,输出重定向会覆盖文件内容,(文件的偏移量是在开头处)请看下面的例子:

$ echo line 1 > users
$ cat users
line 1
$

如果不希望文件内容被覆盖,可以使用>>追加到文件末尾,例如:

$ echo line 2 >> users
$ cat users
line 1
line 2
$

输入重定向

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

command < file

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

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

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

$ wc -l users
2 users
$

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

$ wc -l < users
2
$

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

重定向深入讲解

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

  • 标准输入文件(stdin)stdin的文件描述符为0Unix程序默认从stdin读取数据。

  • 标准输出文件(stdout)stdout的文件描述符为1Unix程序默认向stdout输出数据。

  • 标准错误文件(stderr)stderr的文件描述符为2Unix程序会向stderr流中写入错误信息。


默认情况下,command> file stdout重定向到filecommand< file stdin重定向到file

如果希望stderr重定向到file,可以这样写:

$command 2 > file

如果希望stderr追加到file文件末尾,可以这样写:

$command 2 >> file

2表示标准错误文件(stderr)

如果希望将stdoutstderr合并后重定向到file,可以这样写:

$command > file 2>&1

$command >> file 2>&1

如果希望对stdinstdout都重定向,可以这样写:

$command < file1 >file2

command 命令将stdin重定向到file1,将stdout重定向到file2 

全部可用的重定向命令列表

命令

说明

command> file

将输出重定向到 file

command< file

将输入重定向到 file

command>> file

将输出以追加的方式重定向到file

n> file

将文件描述符为 n的文件重定向到 file

n>> file

将文件描述符为 n的文件以追加的方式重定向到file

n>& m

将输出文件 mn合并。

n<& m

将输入文件 mn合并。

<<tag

将开始标记 tag和结束标记 tag之间的内容作为输入。

HereDocument

HereDocument 目前没有统一的翻译,这里暂译为”嵌入文档“。HereDocument Shell中的一种特殊的重定向方式,它的基本的形式如下:

command << delimiter    documentdelimiter

它的作用是将两个delimiter之间的内容(document)作为输入传递给command
#delimiter
是分隔符的意思,是不是很喜欢用EOF作分隔符?_,不是delimiter随便命名的0.0
注意:

  • 结尾的delimiter一定要顶格写(意思就是说在一行的最前面),前面不能有任何字符,后面也不能有任何字符,包括空格和tab缩进。

  • 开始的delimiter前后的空格会被忽略掉。


下面的例子,通过wc-l 命令计算document的行数:

$wc -l << EOF
    This is a simple lookup program
    for good (and bad) restaurants
    in Cape Town.
EOF
3
$

也可以将 HereDocument 用在脚本中,例如:


  1. #!/bin/bash  

  2. cat << EOF  

  3. This is a simple lookup program  

  4. for good (and bad) restaurants  

  5. in Cape Town.  

  6. EOF  

运行结果:

This is a simple lookup program
for good (and bad) restaurants
in Cape Town.


下面的脚本通过vi编辑器将document保存到test.txt文件:


  1. #!/bin/sh  

  2. filename=test.txt  

  3. vi $filename <<EndOfCommands  

  4. i  

  5. This file was created automatically from  

  6. a shell script  

  7. ^[  

  8. ZZ  

  9. EndOfCommands  

运行脚本:

$ sh test.sh
Vim: Warning: Input is not from a terminal   #terminal--终端
$

#执行完该脚本后,只有在当前目录下生成test.txt.swp的文件,这是vi非正常退出时产生的,至于为什么会非正常退出?不知道。不过可以用vi-r test.txt.swp恢复成txt

打开test.txt,可以看到下面的内容:

$ cat test.txt
This file was created automatically from
a shell script
$

/dev/null文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null

$ command > /dev/null

/dev/null是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果

如果希望屏蔽stdoutstderr,可以这样写:

$ command > /dev/null 2>&1



四、Shell文件包含

像其他语言一样,Shell可以包含外部脚本,将外部脚本的内容合并到当前脚本。

Shell
中包含脚本可以使用:

. filename

source filename

两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格

例如,创建两个脚本,一个是被调用脚本subscript.sh,内容如下:

url="http://see.xidian.edu.cn/cpp/view/2738.html"

一个是主文件main.sh,内容如下:


  1. #!/bin/bash  

  2. . ./subscript.sh  

  3. echo $url  

执行脚本:

$chomd +x main.sh
./main.sh
http://see.xidian.edu.cn/cpp/view/2738.html
$

注意:被包含脚本不需要有执行权限。#有读权限就可以了






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值