您的位置:首页 > 运维架构 > Shell

Shell脚本学习笔记

2017-05-08 14:29 239 查看
前言

随着使用linux越来越多,shell脚本编写必不可少,本文记录了一些在学习shell脚本中的一些知识点,以备后用。

参考:菜鸟教程

一、Shell简介

Shell 是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。

作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。平时所说的Shell脚本是指Shell作为程序设计语言。

二、Shell分类

Shell脚本种类很多,与python类似,相当于采用不同的解释器,主要有以下几种:

a)sh(全称 Bourne Shell): 是UNIX最初使用的 shell,而且在每种 UNIX 上都可以使用。Bourne Shell 在 shell 编程方便相当优秀,但在处理与用户的交互方面不如其他几种 shell。

b)bash(全称 Bourne Again Shell): LinuxOS 默认的,它是 Bourne Shell 的扩展。与 Bourne Shell 完全兼容,并且在 Bourne Shell 的基础上增加了很多特性。可以提供命令补全,命令编辑和命令历史等功能。它还包含了很多 C Shell 和 Korn Shell 中的优点,有灵活和强大的编辑接口,同时又很友好的用户界面。

c)csh(全称 C Shell): 是一种比 Bourne Shell更适合的变种 Shell,它的语法与 C 语言很相似。

d)Tcsh: 是 Linux 提供的 C Shell 的一个扩展版本。Tcsh 包括命令行编辑,可编程单词补全,拼写校正,历史命令替换,作业控制和类似 C 语言的语法,他不仅和 Bash Shell 提示符兼容,而且还提供比 Bash Shell 更多的提示符参数。

e)ksh (全称 Korn Shell): 集合了 C Shell 和 Bourne Shell 的优点并且和 Bourne Shell 完全兼容。

f)pdksh: 是 Linux 系统提供的 ksh 的扩展。pdksh 支持人物控制,可以在命令行上挂起,后台执行,唤醒或终止程序。

本文关注的是 Bash,也就是 BourneAgain Shell,由于易用和免费,Bash在日常工作中被广泛使用。同时,Bash也是大多数Linux系统默认的Shell。因此文件开头如下:

#!/bin/bash

三、Shell变量

3.1 定义变量

Shell定义变量时,如:my_name=”yunge”。变量命名遵循如下规则:

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

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

c)不能使用标点符号。

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

备注:(1)变量名和等号之间不能有空格。(2)已定义的变量可以重新定义。

3.2 使用变量

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

my_name=”yunge” 

echo $my_name

echo ${my_name}

备注:使用时变量外侧有没有花括号均可,但是要养成良好的编程习惯,建议都加上花括号,这样可以区分出变量边界。

3.3 只读变量

可以使用readonly将变量变为只读,只读变量不可以重新定义,重新赋值。

my_name=”liuxinyun”

readonly my_name

3.4 删除变量

使用unset可以删除变量,删除后变量不可以被使用,unset不能删除只读变量,用法和readonly一样。

3.5 变量类型

Shell运行中有两种变量:局部变量(自己使)、环境变量(所有程序共同使用)。

四、Shell字符串

4.1 字符串定义

字符串定义可以使用单引号、双引号,也可以不用引号。

备注:(1)单引号里的任何字符都会原样输出,变量是无效的;单引号字串中不能出现单引号(对单引号使用转义符后也不行)。(2)双引号里可以有变量,可以使用转义字符。

4.2 获取字符串长度

${#string}

4.3 截取字符串

${string:m:n}  #从第m+1个字符开始截取n长度的字符串

4.4 查找字符

str=”my name is yunge”

echo `expr index“${str}” n`   #输出4

echo `expr index“${str}” yunge`   #输出2

备注:(1)并不是查找字符串位置,而是查找子字符串中字符第一次出现的位置,是或的关系,因此输出的是y在第2个位置。(2)输出中使用了反引号,反引号作用是其中的linux命令先执行。

五、Shell数组

5.1定义数组

Bash支持一维数组,不支持多维数组,数组定义使用小括号,元素之间使用空格分开。

5.2 读取数组

${数组名[下标]}

使用”@”可以获取数组中所有元素,例如:echo ${array[@]}

获取数组长度:${#array[@]}或者${#array[*]}

获取单个元素长度:${#array
}

六、Shell注释

注释使用”#”,在sh中没有多行注释,只能每行前面加”#”。

备注:开发中有时需要大段注释进行调试,为了达到多行注释效果可以使用花括号将要注释的多行括起来定义成函数,不在其他地方调用即可。

七、Shell传递参数

Shell脚本内获取传递参数使用$n(n>=0),n表示传递的第几个参数,当n=0时表示该脚本的文件名称,其他还有一些特殊字符用来进行参数处理,如下所示:

$# 参数个数

$* 以一个单字符串显示所有向脚本传递的参数。

$$ 脚本运行的当前进程ID号

$! 后台运行的最后一个进程的ID号

$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。

$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

八、Shell运算符

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。如下:

#!/bin/bash

 

val=`expr 2 + 2`#反引号

echo "两数之和为 :$val"

8.1 数学运算符

加+、减-、乘*、除/、取余%、赋值=、相等判断==、不等判断!=

备注:(1)表达式和运算符之间必须要有空格。(2)完整的表达式要被反引号包围。(3)条件表达式要放在方括号之间,并且要有空格,例如:
[$a==$b] 是错误的,必须写成 [ $a == $b ]。(4)乘号(*)前边必须加反斜杠(\)才能实现乘法运算。


8.2 关系运算符

是否相等-eq、是否不等-nq、左大于右-gt、左小于右-lt、左大于等于右-ge、左小于等于右-le。

备注:关系运算符只能用于数字,不能用于字符串,除非字符串的值是数字。

8.3 布尔运算符

非!、或-o、与-a。

与数学运算符中的条件运算符类似,使用方括号,且两侧有空格。

8.4 逻辑运算符

&&、||

8.5 字符串运算符

= 判断是否相等

!= 判断是否不等

-z 判断字符串长度是否为0,为0返回true

-n 判断字符串长度是否为0,为0返回false

[ $s ] 判断字符串s是否为空,不为空返回true

8.6 文件测试运算符

-b file 检测文件是否是块设备文件

-c file 检测文件是否是字符设备文件

-d file 检测时间是否是目录

-f file 检测文件是否是普通文件,既不是目录,也不是设备文件

-g file 检测文件是否设置了SGID位

-k file 检测文件是否设置了粘着位

-p file 检测文件是否是有名管道

-u file 检测文件是否设置了SUID位

-r file 检测文件是否可读

-w file 检测文件是否可写

-x file 检测文件是否可执行

-s file 检测文件是否为空,文件大小是否大于0

-e file 检测文件(目录)是否存在

九、test命令

test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。作用相当于之前的条件判断使用的方括号。

十、Shell流程控制

与java等其他语言不同的是,sh流程控制不可为空。例如在java中条件控制,可以不做任何操作,但是在sh中,没有执行命令,就不要写。

10.1 if

if condition

then

         命令1

         命令2

fi

10.2 if else

if condition

then

         命令1

         命令2

else

         命令3

         命令4

fi

10.3 if else-if else

if condition1

then

         命令1

elif condition2

then

         命令2

else

         命令3

fi

10.4 for循环

for var in item1item2 ... itemN

do

    命令1

    命令2

    ...

    命令N

done

10.5 while循环

while condition

do

    命令1

    命令2

    ...

    命令N

done

备注:while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环。

echo '按下<CTRL-D> 退出'

echo -n '输入你最喜欢的电影名: '

while read FILM

do

    echo "是的!$FILM 是一部好电影"

done

10.6 无限循环

while :

do

         命令

done

或者

while ture

do

         命令

done

或者

for (( ; ; ))

10.7 until循环

until循环和while循环在处理方式上相反,在条件为真时停止。

until condition

do

         命令

done

备注:循环至少执行一次。

10.8 case多条件选择

case 值 in

模式1)

    command1

    command2

    ...

    commandN

    ;;

模式2)

    command1

    command2

    ...

    commandN

    ;;

esac

备注:(1)取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至
;;。(2)取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。(3)如果无一匹配模式,使用星号 *
捕获该值,再执行后面的命令。相当于其他语言中的default。(4)case的语法和其他语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break。


10.9 跳出循环

跳出循环使用break和continue,breake跳出所有循环,continue跳出当前循环。

十一、      Shell函数

11.1 函数定义

函数定义可以使用functionmyfun(),也可以使用myfun()直接定义。在参数返回时,可以加return进行返回,也可以不加,不加则以最后一条命令结果作为返回值。返回值的获取是在调用函数后,使用”$?”获取。

11.2 函数传参

函数传参调用和脚本传参基本一致,$n代表获取第几个参数,当n>=10时,必须使用${n}进行获取,否则获取不到。

备注:(1)所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。(2)调用函数仅使用其函数名即可。

十二、      输入输出重定向

12.1 重定向命令

command > file 输出重定向到file #file中所有内容被覆盖

command < file 输入重定向到file #从file文件中读取内容作为输入

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

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

n >> file 将文件描述符为n的文件追加到file

n >& m 将输出文件m和n合并

n <& m 将输入文件m和n合并

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

备注:(1)文件描述符0:标准输入STDIN;文件描述符1:标准输出STDOUT;文件描述符2:标准错误输出STDERR。(2)重定向到某文件,该文件中的所有内容均被覆盖。(3)如果希望将错误写入某文件可以使用command
2 > file(或>>表示追加)。(4)command > file 2>&1将STDOUT和STDERR合并输出到file。


12.2 Here document

指出要执行什么,格式:

command <<delimiter

    document

delimiter

备注:(1)结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。(2)开始的delimiter前后的空格会被忽略掉。

例如:

cat << EOF

欢迎您

EOF

12.3 /dev/null 文件

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

如果希望屏蔽 stdout 和 stderr,可以这样写

command > /dev/null 2>&1

十三、      文件包含

和其他语言一样,Shell也可以包含外部脚本,这样可以封装一些公用代码作为一个独立的文件。使用格式如下:

. file 注意”.”和文件之间有空格

或者

source file

备注:被包含的文件可以不具有执行权限。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux shell