shell教程

shell简介

简介

    Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。

    Shell初学者请注意,在平常应用中,建议不要用 root 帐号运行 Shell 。作为普通用户,不管您有意还是无意,都无法破坏系统;但如果是 root,那就不同了,只要敲几个字母,就可能导致灾难性后果。

    Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,习惯上把它们称作一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器。 Linux使用它作为默认的shell是因为它有诸如以下的特色:1可以使用类似DOS下面的doskey的功能,用方向键查阅和快速输入并修改命令。2 自动通过查找匹配的方式给出以某字符串开头的命令。3 包含了自身的帮助功能,你只要在提示符下面键入help就可以得到相关的帮助。

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

    但是,考虑到Shell脚本的命令限制和效率问题,下列情况一般不使用Shell:

  1. 资源密集型的任务,尤其在需要考虑效率时(比如,排序,hash等等)。
  2. 需要处理大任务的数学操作,尤其是浮点运算,精确运算,或者复杂的算术运算(这种情况一般使用C++或FORTRAN 来处理)。
  3. 有跨平台(操作系统)移植需求(一般使用C 或Java)。
  4. 复杂的应用,在必须使用结构化编程的时候(需要变量的类型检查,函数原型,等等)。
  5. 对于影响系统全局性的关键任务应用。
  6. 对于安全有很高要求的任务,比如你需要一个健壮的系统来防止入侵、破解、恶意破坏等等。
  7. 项目由连串的依赖的各个部分组成。
  8. 需要大规模的文件操作。
  9. 需要多维数组的支持。
  10. 需要数据结构的支持,比如链表或数等数据结构。
  11. 需要产生或操作图形化界面 GUI。
  12. 需要直接操作系统硬件。
  13. 需要 I/O 或socket 接口。
  14. 需要使用库或者遗留下来的老代码的接口。
  15. 私人的、闭源的应用(shell 脚本把代码就放在文本文件中,全世界都能看到)。

语法

最简单的shell脚本如下:

#!/bin/bash

echo "Hello World !"

“#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。echo命令用于向窗口输出文本。

普通变量

变量名只能包含数字、字母和下划线,因为某些包含其他字符的变量有特殊含义。

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

your_name="xxx"
使用变量:使用一个定义过的变量,只要在变量名前面加美元符号($),如:echo $your_name

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

myUrl="http://see.xidian.edu.cn/cpp/shell/"
readonly myUrl

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

三种变量:

1) 局部变量

局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

2) 环境变量

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

3) shell变量

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

特殊变量

$0   当前脚本的文件名

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

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

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

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

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

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

替换

转义替换:

-e 表示对转义字符进行替换。可以使用 echo命令的 -E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。如:

命令替换:

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

变量替换:

${var}      变量本来的值

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

${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。

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

${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。

运算符

Bash支持很多运算符,包括算数运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符。原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

算术运算符:

+      加法        `expr $a + $b` 结果为 30。

-       减法        `expr $a - $b` 结果为 10。

*      乘法        `expr $a \* $b` 结果为  200。

/      除法        `expr $b / $a` 结果为 2。

%     取余        `expr $b % $a` 结果为 0。

=      赋值        a=$b 将把变量 b 的值赋给 a。

==   相等。用于比较两个数字,相同则返回 true。       [ $a == $b ] 返回 false。

!=    不相等。用于比较两个数字,不相同则返回 true。       [ $a != $b ] 返回 true。

关系运算符:

-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。

-ne 检测两个数是否相等,不相等返回 true。       [ $a -ne $b ] 返回 true。

-gt   检测左边的数是否大于右边的,如果是,则返回 true。       [ $a -gt $b ] 返回 false。

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

-ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。

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

布尔运算符:

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

-o    或运算,有一个表达式为true 则返回 true。        [ $a -lt 20 -o $b -gt100 ] 返回 true。

-a    与运算,两个表达式都为true 才返回 true。        [ $a -lt 20 -a $b -gt100 ] 返回 false。

字符串运算符:

=      检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。

!=    检测两个字符串是否相等,不相等返回 true。       [ $a != $b ] 返回 true。

-z     检测字符串长度是否为0,为0返回 true。    [ -z $a ] 返回 false。

-n    检测字符串长度是否为0,不为0返回 true。         [ -z $a ] 返回 true。

str   检测字符串是否为空,不为空返回 true。       [ $a ] 返回 true。

文件测试运算符:

-b file       检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。

-c file       检测文件是否是字符设备文件,如果是,则返回 true。       [ -b $file ] 返回 false。

-d file       检测文件是否是目录,如果是,则返回 true。       [ -d $file ] 返回 false。

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

-g file       检测文件是否设置了SGID 位,如果是,则返回 true。       [ -g $file ] 返回 false。

-k file       检测文件是否设置了粘着位(StickyBit),如果是,则返回 true。[ -k $file ] 返回 false。

-p file       检测文件是否是具名管道,如果是,则返回 true。       [ -p $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。

字符串

字符串可以用单引号,也可以用双引号,也可以不用引号。

单引号字符串的限制:

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

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

双引号的优点:

    双引号里可以有变量。

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

获取字符串长度

   string="abcd"

   echo ${#string} #输出 4

提取子字符串

   string="alibaba is a great company"

   echo ${string:1:4} #输出liba

查找子字符串

   string="alibaba is a great company"

    echo`expr index "$string" is`

数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。

读取数组

#!/bin/sh

NAME[0]="Zara"

echo "First Index: ${NAME[0]}"

#使用@ 或 * 可以获取数组中的所有元素

echo "First Method: ${NAME[*]}"

#获取数组长度的方法与获取字符串长度的方法相同

# 取得数组元素的个数

length=${#array_name[@]}

# 或者

length=${#array_name[*]}

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

lengthn=${#array_name[n]}

echo命令

#显示转义字符

echo "\"It is atest\""      // "It is atest"

#显示变量

name="OK"

echo "$name It is a test"    // OK It is a test

#显示换行

echo "OK!\n"

echo "It is a test"

OK!

It is a test

#显示不换行

echo "OK!\c"

echo "It is a test"

OK!It si a test

#显示结果重定向至文件

echo "It is a test" > myfile

#原样输出字符串

   echo '$name\"'

显示命令执行结果

   echo `date`

条件

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

 

case 值 in
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

循环

for类型:

for 变量 in 列表

do

   command1

   command2

   ...

   commandN

done

while类型:

while command
do
   Statement(s) to be executed if command is true
done

until 循环格式为:

until command

do

  Statement(s) to be executed until command is true

done

函数

Shell 函数的定义格式如下:

function_name () {

   list of commands

    [return value ]

}

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

function function_name () {

   list of commands

    [return value ]

}

带参数函数例子如下:

#!/bin/bash

funWithParam(){

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

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

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

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

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

   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

输出:

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 12 !

The string of the parameters is 1 2 3 4 5 67 8 9 34 73 !"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值