shell快速入门

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell快速入门相关的知识,希望对你有一定的参考价值。

本文下载

shell快速入门

参考文档

shell从入门到放弃(上)

shell从入门到放弃(中)

shell从入门到放弃(下)

朱双印的个人日志-shell

shell的基本概念

shell是什么

Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。      

它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。

shell有哪些

Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,习惯上把它们称作一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器。

bash

bash是Linux标准默认的shell,bash由Brian Fox和Chet Ramey共同完成,是Bourne Again Shell的缩写,内部命令一共有40个。

 

Linux使用它作为默认的shell是因为它有诸如以下的特色:

可以使用类似DOS下面的doskey的功能,用方向键查阅和快速输入并修改命令。

自动通过查找匹配的方式给出以某字符串开头的命令。

包含了自身的帮助功能,你只要在提示符下面键入help就可以得到相关的帮助。

sh

sh 由Steve Bourne开发,是Bourne Shell的缩写,sh是Unix标准默认的shell。

ash

ash shell 是由Kenneth Almquist编写的,Linux中占用系统资源最少的一个小shell,它只包含24个内部命令,因而使用起来很不方便。

csh

csh 是Linux比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该shell其实是指向/bin/tcsh这样的一个shell,也就是说,csh其实就是tcsh。

ksh

ksh 是Korn shell的缩写,由Eric Gisin编写,共有42条内部命令。该shell最大的优点是几乎和商业发行版的ksh完全兼容,这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。

 

注意: bash是 Bourne Again Shell 的缩写,是linux标准的默认shell ,它基于Bourne shell,吸收了C shell和Korn shell的一些特性。bash完全兼容sh,也就是说,用sh写的脚本可以不加修改的在bash中执行。

编译语言与解释型语言

编译语言

很多传统的程序设计语言,例如C、C++和Java,都是编译型语言。这类语言需要预先将我们写好的源代码(source code)转换成目标代码(object code),这个过程被称作“编译”。

 

运行程序时,直接读取目标代码(object code)。由于编译后的目标代码(object code)非常接近计算机底层,因此执行效率很高,这是编译型语言的优点

 

但是,由于编译型语言多半运作于底层,所处理的是字节、整数、浮点数或是其他机器层级的对象,往往实现一个简单的功能需要大量复杂的代码。例如,在C++里,就很难进行“将一个目录里所有的文件复制到另一个目录中”之类的简单操作。

解释型语言

解释型语言也被称作“脚本语言”。执行这类程序时,解释器(interpreter)需要读取我们编写的源代码(source code),并将其转换成目标代码(object code),再由计算机运行。因为每次执行程序都多了编译的过程,因此效率有所下降

 

使用脚本编程语言的好处是,它们多半运行在比编译型语言还高的层级,能够轻易处理文件与目录之类的对象;缺点是它们的效率通常不如编译型语言。不过权衡之下,通常使用脚本编程还是值得的:花一个小时写成的简单脚本,同样的功能用C或C++来编写实现,可能需要两天,而且一般来说,脚本执行的速度已经够快了,快到足以让人忽略它性能上的问题。脚本编程语言的例子有awk、Perl、Python、Ruby与Shell。

shell脚本入门

shell脚本是什么

shell脚本就是命令的堆积。但是很多不命令不具有幂等性,需要用程序逻辑来判断运行条件是否满足,以避免运行中产生错误;

幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的

运行shell脚本

 (1) 赋予执行权限,并直接运行此程序文件;

chmod +x  test.sh

. /test.sh

当以这种方式运行脚本时:

技术分享图片

我们在第一行的bash运行了命令。随后生成了子进程test.sh。在子进程中运行test.sh。

此时,test.sh不能继承bash中定义的本地变量。

 (2) 直接运行解释器,以脚本文件为参数;

bash  test.sh

       -n:检测脚本是否正确,但不执行

       -x:执行脚本,并输出执行过程

--posix:改变bash的行为,使其符合Posix 1003.2规定的标准。

当以这种方式运行脚本时,同上,只是生成的子进程是bash

 (3)sh运行脚本

相当于打开了bash的POSIX标准模式,即bash --posix

sh是bash的“子集”

当以这种方式运行脚本时,同上,只是生成的子进程是sh

(4)source运行脚本

source test.sh

相当于:

. ./ test.sh #.空格./ test.sh

当以这种方式运行脚本时:

技术分享图片

没有生成子进程,直接在bash里运行了test.sh。此时可以继承bash的本地变量。这里的source也可以理解为将test.sh文件中的内容包含到当前文件或进程中。

解释器(头文件)

shell脚本的第一行(即头文件),是解释器程序文件的路径,用于指明解释运行当前脚本代码的解释器;

n  #!/bin/bash

n  #!/bin/tcsh

n  #!/usr/bin/python3

n  #!/usr/bin/perl

shell的变量

定义变量

定义本地变量

定义变量时,变量名不加美元符号($),如:

myUrl="http://zhaoyongtao.blog.51cto.com/"

myNum=100

注意,变量名和等号之间不能有空格。同时,变量名的命名须遵循如下规则:

l  首个字符必须为字母(a-z,A-Z)。

l  中间不能有空格,可以使用下划线(_)。

l  不能使用标点符号。

l  不能使用bash里的关键字(可用help命令查看保留关键字)。

重复定义

对某个变量名进行重复定义,后一次定义会覆盖前一次定义

只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

#!/bin/bash

 

myUrl="http://zhaoyongtao.blog.51cto.com/"

readonly myUrl

myUrl=http://blog.51cto.com/

上面这个脚本尝试更改只读变量,执行时就会报错

命令行定义

readonly var=value

只读变量只对当前bash生效。如果想让其可以继承,可以定义环境只读变量:

export readonly var=value

定义环境变量

使用export关键字定义环境变量

export var=value

或是先定义本地变量,在声明为环境变量

var=value

export var

declare定义

使用declare也可以声明一个变量

declare abc=123 #声明变量abc的值为123

-i:声明×××变量

-x:声明环境变量。相当于export环境变量

-r:声明只读变量

 

使用变量

使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:

your_name="kim"

echo $your_name

echo ${your_name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界。推荐使用变量时,都用加花括号的写法

删除变量

使用 unset 命令可以删除变量。语法:

unset variable_name

变量被删除后不能再次使用;unset 命令不能删除只读变量

变量类型

运行shell时,会同时存在三种变量:

1) 本地变量

本地变量只在当前bash进程终有效,对当前shell进程外的其他shell进程,包括当shell的子shell进程均无效

1)局部变量

局部变量只对当前函数或代码段有效。

如果在脚本范围为存在一个全局变量var(即一个函数外有一个全局变量)。则脚本中的同名var变量会覆盖全局变量。

如果在函数中使用local定义同名var变量local var= ,则函数中的var变量不会覆盖全局变量var。

2)全局变量

2) 环境变量

所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

3) shell变量

shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

特殊变量

在shell中,某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量。

特殊变量列表

变量

含义

$0

当前脚本的文件名

$n

传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2

$#

传递给脚本或函数的参数个数。

$*

传递给脚本或函数的所有参数。

[email protected]

传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。

${@:起点}表示由起点开始(包括起点),取得后面的所有位置参数

${@:起点:个数}:表示由起点开始(包括起点),取得指定个数的位置参数

$?

上个命令的退出状态,或函数的返回值。

$$

当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

$*[email protected]的区别

$* 和 [email protected] 都表示传递给函数或脚本的所有参数。

假设某脚本有参数:a,b,c,d,e

这样看上去都是一样的

$*= a b c d

"$*"= a b c d

[email protected]= a b c d

"[email protected]"= a b c d

然后我们分别遍历它们:

for var in [email protected]/$*/[email protected]”/“$*”

do

echo "$var"

done

不被双引号(" ")包含时

都以"$1" "$2" … "$n" 的形式输出所有参数。

结果都为:

a

b

c

d

被双引号(" ")包含时

"$*" 会将所有的参数合为一个字符串,以"$1 $2 … $n"的形式输出所有参数;

遍历结果为:

a b c d

这证明所有参数在一个变量中

"[email protected]" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

遍历结果不变

变量的替换

转义字符

如果表达式中包含特殊字符,Shell 将会进行替换。例如,在双引号中使用变量就是一种替换,转义字符也是一种替换。

#!/bin/bash

 

a=10

echo -e "Value of a is $a "  # -e 表示对转义字符进行替换,不适用-e则原样输出

echo能使用的转义字符有:

转义字符

含义

\

反斜杠

a

警报,响铃



退格(删除键)

f

换页(FF),将当前位置移到下页开头

换行

回车

水平制表符(tab键) 

v

垂直制表符

命令替换

命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。

`command`  #注意是反引号

例如:

#!/bin/bash

 

DATE=`date`

echo "Date is $DATE"

变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值。

#!/bin/bash

 

echo ${var:-"Variable is not set"}

echo "1 - Value of var is ${var}"

 

echo ${var:="Variable is not set"}

echo "2 - Value of var is ${var}"

 

unset var

echo ${var:+"This is default value"}

echo "3 - Value of var is $var"

 

var="Prefix"

echo ${var:+"This is default value"}

echo "4 - Value of var is $var"

 

echo ${var:?"Print this message"}

echo "5 - Value of var is ${var}"

 

形式

说明

${var}

变量本来的值

${var:-word}

如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。

${var:=word}

如果变量 var 为空或已被删除(unset),返回word,将   var 的值设置为 word。var不为空,则值不变

${var:?message}

如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
  若此替换出现在Shell脚本中,那么脚本将停止运行。

如果变量 var 被定义,无返回,var值不变

${var:+word}

如果变量 var 被定义,返回var的值,不改变 var 的值

如果变量 var 未定义,返回word,不改变 var 的值

 

shell的运算符

Shell支持很多运算符,包括:Shell算数运算符、关系运算符、布尔运算符、字符串运算符等

算数运算符

算术运算符

u  +,-

u  *, / 

u  %:取余

u  **:次方

算术运算格式

(1) let  VAR=算术表达式 let var=$a+$b。只支持整数运算

(2) VAR=$[算术表达式] var1=$[$a+$b] 。只支持整数运算

(3) VAR=$((算术表达式)) var3=$(($a+$b)) 。只支持整数运算

(4) VAR=$(expr $ARG1 $OP $ARG2) expr 2 + 2  #变量和运算符间必须有空格,且*号使用时,要用转义。只支持整数运算

(5)bc命令。支持小数运算echo "2.5*3.4" |bc

关系运算符

-eq 检测两个数是否相等,相等返回 true。

-ne 检测两个数是否相等,不相等返回 true。

-gt  检测左边的数是否大于右边的,如果是,则返回 true。

-ge 检测左边的数是否大等于右边的,如果是,则返回 true。

-lt   检测左边的数是否小于右边的,如果是,则返回 true。

-le   检测左边的数是否小于等于右边的,如果是,则返回 true。

-gt>

-gt与-lt只能比较两个数字的大小。而>和小于可以根据ASCII码比较字符串的大小。

[  “a”> “b” ]  # 单中括号需要转义。字母和括号间有空格

[[  “a” > “b” ]] # 双中括号不需转义。字母和括号间有空格

布尔运算符

运算符

说明

举例

!

非运算,表达式为 true 则返回 false,否则返回 true。

[ ! false   ] 返回 true。

-o

或运算,有一个表达式为 true 则返回 true。

[ $a -lt   20 -o $b -gt 100 ] 返回 true。

||

或运算。但同有些-o区别


-a

与运算,两个表达式都为 true 才返回 true。

[ $a -lt   20 -a $b -gt 100 ] 返回 false。

&&

与运算,但同-a有些区别


-a&&

-a是单大括号[-a]

&&是双大括号[[&&]]。也可以是 [判断1] && [判断2]

&&相比-a多了短路与特性:

cmd1 && cmd2 # 若cmd1为真则执行cmd2。为假则不执行

-o&&

-o是单大括号[-a]

||是双大括号[[||]]。也可以是 [判断1] || [判断2]

||相比-o多了短路或特性:

cmd1 || cmd2 # 若cmd1为真则不执行cmd2。为假则执行

扩展:

cmd1 && cmd2 || cmd3 #若cmd1位真则执行cmd2,为假则执行cmd3

 

字符串运算符

运算符

说明

举例

=

检测两个字符串是否相等,相等返回 true。

[ $a = $b   ] 返回 false。

!=

检测两个字符串是否相等,不相等返回 true。

[ $a != $b   ] 返回 true。

-z

检测字符串长度是否为0,为0返回 true。

[ -z “$a”   ] 返回 false。

-n

检测字符串长度是否为0,不为0返回 true。

[ -n “$a”   ] 返回 true。

str

检测字符串是否为空,不为空返回 true。

[ $a ] 返回 true。

[][[]]

在使用-z与-n时,如果是“[]”,需要给变量加上双引号。“[[]]”则不用加。

在使用”=~”匹配正则表达式时,只能使用“[[]]”

tel=136999

[[ $tel =~ [0-9]{6} ]]

echo $?

0

文件测试运算符


  

操作符

说明

举例

-b file

检测文件是否是块设备文件,如果是,则返回 true。

[ -b $file   ] 返回 false。

-c file

检测文件是否是字符设备文件,如果是,则返回 true。

[ -b $file   ] 返回 false。

-d file

检测文件是否是目录,如果是,则返回 true。

[ -d $file   ] 返回 false。

-f file

检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回   true。

[ -f $file   ] 返回 true。

-p file

检测文件是否是具名管道,如果是,则返回 true。

[ -p $file   ] 返回 false。

-g file

检测文件是否设置了 SGID 位,如果是,则返回 true。

[ -g $file   ] 返回 false。

-k file

检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。

[ -k $file   ] 返回 false。

-u file

检测文件是否设置了 SUID 位,如果是,则返回 true。

[ -u $file   ] 返回 false。

-r file

检测文件是否可读,如果是,则返回 true。

[ -r $file   ] 返回 true。

-w file

检测文件是否可写,如果是,则返回 true。

[ -w $file   ] 返回 true。

-x file

检测文件是否可执行,如果是,则返回 true。

[ -x $file   ] 返回 true。

-s file

检测文件是否为空(文件大小是否大于0),不为空返回 true。

[ -s $file   ] 返回 true。

-e file

检测文件(包括目录)是否存在,如果是,则返回 true。

[ -e $file   ] 返回 true。

shell的字符串

字符串是shell编程中最常用最有用的数据类型。而在使用字符串时,单引号和双引号的作用有些不同。

单引号与双引号

单引号

str='this is a string'

单引号字符串的限制:

1)     单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

2)     单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

双引号

your_name='qinjx'

str="Hello, I know your are "$your_name"! "

双引号的优点:

1)     双引号里可以有变量

2)     双引号里可以出现转义字符

简单操作

拼接字符串

your_name="qinjx"

greeting="hello, "$your_name" !"

greeting_1="hello, ${your_name} !"

echo $greeting $greeting_1

获取字符串长度

string="abcd"

echo ${#string} #输出 4

提取子字符串

string="alibaba is a great company"

echo ${string:1:4} # 输出liba。从变量的第1个字符开始,截取4个字符的长度

echo ${string:0-12:4} # 从倒数第12个字符开始,向后截取4个字符的长度

echo ${string: -12:4} # 从倒数第12个字符开始,向后截取4个字符的长度

echo ${string:0-12:-4} #从倒数第12个字符开始,向后截取所有字符,并删除最后4个字符

变量设置方式

说明

${string#*关键字 }

删除从左到右遇到的第一个“关键字”。及其左侧所有字符

${string##*关键字 }

删除从左到右遇到的最后一个“关键字”。及其左侧所有字符

${string%*关键字 }

删除从右向左遇到的第一个“关键字”。及其右侧所有字符

${string%%*关键字 }

删除从右向左遇到的最后一个“关键字”。及其右侧所有字符

${string/旧字符串/新字符串   }

第一个替换

${string//旧字符串/新字符串   }

所有替换

${string/关键字}

删除字符串中的第一个关键字

${string//关键字}

删除字符串中的所有关键字

${string/#关键字}

删除行首的某个关键字

${string/%关键字}

删除行尾的某个关键字

 

查找子字符串

string="alibaba is a great company"

echo `expr index "$string" is` #输出3。

注:expr index "$string" is的含义为,查找“$string”字符串中“i”或“s”第一次出现的地方。由于i最先出现。所以返回结果为3

字符串的大小写转换

所有字母变大小。加两个^^

echo ${var^^}

所有字母变小写。加两个,,

echo ${var,,}

 

变量替换

数组

定义数组

在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:

array_name=(value1 ... valuen)

例如:

array_name=(value0 value1 value2 value3)

或者

array_name=(

value0

value1

value2

value3

)

还可以单独定义数组的各个分量:

array_name[0]=value0

array_name[1]=value1

array_name[2]=value2

可以不使用连续的下标,而且下标的范围没有限制。

读取数组

读取数组元素值的一般格式是:

${array_name[index]}

例如:

valuen=${array_name[2]}

使用@ 或 * 可以获取数组中的所有元素,例如:

${array_name[*]}

${array_name[@]}

获取数组长度

获取数组长度的方法与获取字符串长度的方法相同,例如:

# 取得数组元素的个数

length=${#array_name[@]}

# 或者

length=${#array_name[*]}

# 取得数组单个元素的长度

lengthn=${#array_name[n]}

shell的条件判断

if-else

if-fi

if [ expression ] # expression 和方括号([ ])之间必须有空格,否则会有语法错误

then

   Statement(s) to be executed if expression is true

fi

if-else-fi

if [ expression ]

then

   Statement(s) to be executed if expression is true

else

   Statement(s) to be executed if expression is not true

fi

if-elif-else-fi

if [ expression 1 ]

then

   Statement(s) to be executed if expression 1 is true

elif [ expression 2 ]

then

   Statement(s) to be executed if expression 2 is true

elif [ expression 3 ]

then

   Statement(s) to be executed if expression 3 is true

else

   Statement(s) to be executed if no expression is true

fi

命令行执行

if ... else 语句也可以写成一行,以命令的方式来运行,像这样:

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;

if ... else 语句也经常与 test 命令结合使用,如下所示:

num1=$[2*3]num2=$[1+5]if test $[num1] -eq $[num2]then echo 'The two numbers are equal!'else echo 'The two numbers are not equal!'fi

test 命令用于检查某个条件是否成立,与方括号([ ])类似。

case-esac

case ... esac 与其他语言中的 switch ... case 语句类似,是一种多分支选择结构。

case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:

case 值 in

模式1)

    command1

    command2

    command3

    ;;  #“;;”和break类似,意为跳到整个case语句的最后

模式2)

    command1

    command2

    command3

    ;;

*)  # “*”号表示无匹配到的值,默认执行什么

    command1

    command2

    command3

    ;;

esac

for

for 变量 in 列表

do

    command1

    command2

    ...

    commandN

done

列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。
in 列表是可选的,如果不用它,for 循环使用命令行的位置参数

while

while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

while command

do

   Statement(s) to be executed if command is true

done

until

until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。

until command

do

   Statement(s) to be executed until command is true

done

command一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

break

break命令允许跳出所有循环(终止执行后面的所有循环)。

在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。例如:

break n  # 表示跳出第 n 层循环。

嵌套循环break的例子,如果 var1 等于 2,并且 var2 等于 0,就跳出循环:

#!/bin/bash

for var1 in 1 2 3

do

    for var2 in 0 5

    do

           if [ $var1 -eq 2 -a $var2 -eq 0 ]

       then

       break 2

    else

       echo "$var1 $var2"

    fi

    done

done

如上,break 2 表示直接跳出外层循环。运行结果:

1 0

1 5

如果使用的是break的话。运行结果:

1 0

1 5

3 0

3 5

continue

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

#!/bin/bash

while :

do

    echo -n "Input a number between 1 to 5: "

    read aNum

    case $aNum in

        1|2|3|4|5) echo "Your number is $aNum!"

        ;;

        *) echo "You do not select a number between 1 to 5!"

            continue

            echo "Game is over!"

        ;;

    esac

done

运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句

echo "Game is over!"

永远不会被执行。

同样,continue 后面也可以跟一个数字,表示跳出第几层循环。

shell的函数

定义函数

函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高。像其他编程语言一样,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”。

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

调用函数

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

一个带有return语句的函数:

#!/bin/bash

funWithReturn(){

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

    echo -n "Input first number: "

    read aNum

    echo -n "Input another number: "

    read anotherNum

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

    return $(($aNum+$anotherNum))

}

funWithReturn

# Capture value returnd by last command

ret=$?

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 !

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

 

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

嵌套函数

#!/bin/bash

 

# Calling one function from another

number_one () {

   echo "Url_1 is http://zhaoyongtao.blog.51cto.com/"

   number_two

}

 number_two () {

   echo "Url_2 is http://zhaoyongtao.blog.51cto.com/10955972/1773727"

}

 number_one

删除函数

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

$unset -f function_name

函数参数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数,当n>=10时,需要使用${n}来获取参数(如${10})。

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

特殊变量

说明

$#

传递给函数的参数个数。

$*

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

[email protected]

与$*相同,但是略有区别,请查看Shell特殊变量。

$?

函数的返回值。

#!/bin/bash

funWithParam(){

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

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

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

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

}

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

shift剔除参数

使用shift可剔除一个参数。如剔除$1,则$2变$1

-n:一次同时剔除前面n个参数。剔除后,后面的参数自动向前排。

通过剔除的方式,我们可以将${10},变为$1来引用

shell文件引用

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

Shell 中包含脚本可以使用:

. filename #点号(.)和文件名中间有一空格

source filename

推荐用source

注意:被包含脚本不需要有执行权限。


以上是关于shell快速入门的主要内容,如果未能解决你的问题,请参考以下文章

Shell 编程基础 --语法快速入门

Shell脚本入门到深入教程:快速入门

Shell基础快速入门 了解shell运行原理

shell编程快速入门

shell 脚本快速编写入门

Shell教程快速入门