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

来源:互联网 发布:比特大陆 知乎 编辑:程序博客网 时间:2024/05/29 08:42

一、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.shHello 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: 25Input another number: 50The 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 usersoko         tty01   Sep 12 07:30ai          tty15   Sep 12 13:32ruth        tty21   Sep 12 10:10pat         tty24   Sep 12 13:07steve       tty25   Sep 12 13:03$

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

$ echo line 1 > users$ cat usersline 1$

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

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

输入重定向

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

command < file

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

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

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

$ wc -l users2 users$

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

$ wc -l < users2$

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

重定向深入讲解

一般情况下,每个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目前没有统一的翻译,这里暂译为”嵌入文档“。HereDocumentShell中的一种特殊的重定向方式,它的基本的形式如下:

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.EOF3$

也可以将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 programfor good (and bad) restaurantsin 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.shVim: Warning: Input is not from a terminal   #terminal--终端$

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

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

$ cat test.txtThis file was created automatically froma 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.shhttp://see.xidian.edu.cn/cpp/view/2738.html$

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






0 0
原创粉丝点击