1 变量
+1.1 变量概论
+
+-
+
变量名:
+
+- 只包含字母、数字和下划线: 变量名可以包含字母(大小写敏感)、数字和下划线 _,不能包含其他特殊字符。
+- 不能以数字开头: 变量名不能以数字开头,但可以包含数字。
+- 避免使用 Shell 关键字: 不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。
+- 使用大写字母表示常量: 习惯上,常量的变量名通常使用大写字母,例如 PI=3.14。
+- 避免使用特殊符号: 尽量避免在变量名中使用特殊符号,因为它们可能与 Shell 的语法产生冲突。
+- 避免使用空格: 变量名中不应该包含空格,因为空格通常用于分隔命令和参数。
+
+
+-
+
变量引用:$variable_name
+
+-
+
变量边界:{variable_name}(尽量使用)
+
+-
+
只读变量:readonly variable_name
+
+-
+
删除变量:unset variable_name
+
+-
+
变量类型 :
+运行shell时,会同时存在三种变量:
+
+- 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
+- 环境变量: 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
+- shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
+
+
+
+1.2 字符串
+字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。
+1.2.1 定义
+
+-
+
单引号
+特点:
+
+- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
+- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
+
+
+-
+
双引号
+特点:
+
+- 双引号里可以有变量
+- 双引号里可以出现转义字符
+注意:在shell脚本中,命令参数可以加双引号进行字符拼接,也可以不加双引号;区别在于空格是否会被认为参数分割符
+
+
+-
+
反引号
+特点:
+
+
+-
+
不用引号
+特点:
+
+
+
+1.2.2 一些例子
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #1. index查找子字符位置 # string="runoob is a great site" echo `expr index "$string" io` # 输出 4
#2. 拼接字符串 b=c "abcd${b}" #输出 abcdc
#3. ${#}获取字符串长度 string="abcd" echo ${#string} #输出 4
#4. 字符串n:n提取子字符串 string="runoob is a great site" echo ${string:1:4} # 输出 unoo echo –e 开启字符转义
|
+
+2 比较测试
+2.1 条件测试
+test condition(与其他语言不同的是shell编程中,0表示真,1表示假)
+1
| test -d dirname # 测试是否是目录
|
+2.2 文件测试
+文件测试,主要是判断文件是否符合指定的文件属性或文件是否存在
+
+
+
+操作符 |
+意义 |
+
+
+
+
+-b |
+当文件存在,且为块文件时测试为 真 |
+
+
+-c |
+当文件存在,且为字符文件时测试 为真 |
+
+
+-d |
+当路径存在,且为目录时测试为真 |
+
+
+-e |
+当文件或目录存在时为真 |
+
+
+-f |
+当文件存在,且为普通文件时为真 |
+
+
+-g |
+当文件或目录存在,且设置了SGID 时为真 |
+
+
+-h |
+当文件存在,且为符号链接时为真 |
+
+
+-k |
+当文件或目录存在且设置了黏滞位 时为真 |
+
+
+-p |
+当文件存在,且为命名管道时为真 |
+
+
+-r |
+当文件或目录存在,且可读时为真 |
+
+
+-S |
+当文件存在,且其大小大于0时为真 |
+
+
+
+
+
+
+操作符 |
+意义 |
+
+
+
+
+-S |
+当文件存在,且为套接字文件时为真 |
+
+
+-t |
+当文件是与终端设备相关联的文件描述符时为真 |
+
+
+-u |
+当文件或目录存在,且设置了SUID时为真 |
+
+
+-w |
+当文件或目录存在,且可写时为真 |
+
+
+-X |
+当文件或目录存在,且可执行时为真 |
+
+
+ |
+当文件或目录存在,且被前进程有效用户时为真 |
+
+
+-G |
+当文件或目录存在,且属于当前用户所在的用户 组时为真 |
+
+
+file1ntfile2 |
+nt是new than的缩写,所以file1比file2新时为真 |
+
+
+file1otfile2 |
+ot是old than的缩写,所以file1比file2旧时为真 |
+
+
+file1effile2 |
+ef是equal from的缩写,所以当file1和file2为同 文件的硬链接是为真 |
+
+
+
+例如:
+[ -b /dev/doc ];echo $? # 测试/dev/doc是否为块文件,并打印返回值
+(一定要注意中括号与变量之间要留有空格)
+2.3 字符串测试
+
+
+
+ |
+ |
+
+
+
+
+操作符 |
+意义 |
+
+
+< |
+按ASCII码顺序,前面的字符串小于后面的字符串则为真 |
+
+
+> |
+按ASCII码顺序,前面的字符串大于后面的字符串则为真 |
+
+
+= |
+字符串完全相同为真;适用于[]和test(test和[]是等价的) |
+
+
+== |
+字符串完全相同为真;适用于[[]] |
+
+
+=~ |
+前面的字符串中包含后面的字符串时为真 |
+
+
+!= |
+字符串不相等为真 |
+
+
+-Z |
+字符串为空则为真 |
+
+
+-n |
+字符串非空为真 |
+
+
+
+【注意】
+
+- 以上左右操作符,在使用时,必须两侧都有空格才可以, 否则shell会将其中的操作符当做普通字符进行处理
+- 字符串测试最好用双中括号[[]]
+
+2.4 整数值测试
+Shell中对整数值的测试使用的是字母操作符,而不是通常的算术运算符,常用的整数值测试操作符如下表所示:
+
+
+
+操作符 |
+意义 |
+
+
+
+
+-eq |
+equal to,两个数相等为真 |
+
+
+-ge |
+greater than or equal to,前者大于等于后者为真 |
+
+
+-gt |
+greater than,前者大于后者为真 |
+
+
+-le |
+less than or equal to,前者小于等于后者为真 |
+
+
+-It |
+less than,前者小于后者为真 |
+
+
+-ne |
+no equal,两者不相等为真 |
+
+
+附: |
+ |
+
+
+在 Bash 中,双方括号 [[ … ]] 用于条件测试。它提供了一些在单方括号 [ … ] 中不可用的高级条件测试功能,并且在使用时不需要进行字符串引号转义。双方括号通常用于更复杂的条件表达式。 |
+ |
+
+
+
+3 语句
+3.1 if语句
+3.1.1 if……elif……else……(fi)
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| if [ 条件测试 ];then
# 条件测试为真时执行该语句·
elif [ 条件测试 ];then
# 条件测试为真时执行该语句
else
# 上述条件测试都为假时执行该语句
fi(shell语句没有程序块的概念,用fi表示结束)
注意:[]可以改成(()),这样就可以用运算符比较了。
|
+3.1.2 if……else……(fi)
+1 2 3 4 5 6 7 8 9
| if [ 条件测试 ];then
# 条件测试为真时执行该语句·
else
# 上述条件测试都为假时执行该语句
fi(shell语句没有程序块的概念,用fi表示结束)
|
+注意:
+
+-
+
在shell中空格用来分割不同的命令和参数:
+
+- 注意if和[]之间的空格
+- 条件和[]之间也要严格空格
+- []中运算符号与变量也要严格空格隔开,否则会产生错误
+
+
+-
+
else后面不需要引号和then
+
+-
+
用&&、||、!连接不同条件时,再加一个[]
+
+
+【示例】
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #!/bin/bash # "#!俗称shebang,此处用于指定shell为bash" if [ -e ~/.bashrc ];then
echo "file exists"
else
echo "file is not exists"
fi
【运行结果】
os@tedu:~$/file.sh运行程序
file exists.显然结果是真,因此输出“file exists”
|
+3.2 case语句
+case … esac 为多选择语句,与其他语言中的 switch … case 语句类似,是一种多分支选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
+可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; esac
|
+3.3 for循环
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # 语法 for var in list do 循环语句 done
# 举例:
# 1)C风格
for((i=1;i<=10;i++)) do echo $(expr $i \* 3 + 1) done
# 2)seq风格
for i in $(seq 1 10) do echo $(expr $i \* 3 + 1) done
# 3){1..50}风格
for i in {1..10} do echo $(expr $i \* 3 + 1) done
|
+3.4 while循环
+1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| while 表达式 do
循环语句
done # done后面可以接重定向符号,将文件行做为输入判断:
while 表达式
do
循环语句
done < filename
|
+3.5 until循环
+until循环结构在其他编程语言中并不常见。使用方法与前面讲的for循环和while循环结构类似,但是until是在条件测试为假时执行循环语句,直到条件测试为真时退出。
+1 2 3 4 5 6 7
| until 表达式 do
# 循环语句
done
|
+3.6 select循环
+select循环结构是Shell中比较特殊的一种循环结构,前面讲的循环结构中,大多有一个数组来保存各个元素,有时也不需要数组。而select循环结构中数组和变量时必须的,select循环是一个可以和用户进行交互式的循环结构,在命令行Shell中非常实用
+1 2 3 4 5 6
| select var in list do
# 循环语句
done
|
+shell中continue、break语句和在python、c用法一样
+四、数组
+4.1 定义数组
+
+- 数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。
+- 与大部分编程语言类似,数组元素的下标由 0 开始。
+Shell 数组用括号来表示,元素用"空格"符号分割开(数组可以换行,换行符不影响),语法格式如下:
+
+1
| array_name=(value1 value2 ... valuen)
|
+4.2 访问数组:
+1 2 3 4 5 6 7 8 9 10
| a=(1 2 3 4 5)
unset a[2] # 销毁指定数组元素
unset a # 销毁数组
# '#'获取用户数组长度(使用 @ 或 * 可以获取数组中的所有元素) ${
${
|
+注意:
+
+- shell中赋值符号与变量和值之间不能有空格,否则会被认为三个不同命令或参数
+- "#"操作符的作用位获取参数的长度,不仅可以获取数组的长度,对于变量也可以使用该操作符进行获取长度
+
+4.4 数组切片
+1 2 3
| Array1=${array[@]:m:n}
Array1=${array[*]:m:n}
|
+4.5 数组替换
+1 2 3 4 5 6 7 8 9 10
| ${array[@]/from/to}
# 举例 arr=(1 2 3 4 5) ${arr[@]/2/10} arr=${arr[@]/2/10} # 重新赋值永久替换
# array需要替换的数组名称 # from数组中需要被替换的旧字符串 # to被替换的新的字符串,可以省略
|
+4.6 关联数组
+除了常见的下标索引形式的数组,Shell中还有一种被称为关联数组的数组形式,借助散列技术,使用字符串作为索引值,而不是使用数组作为索引
+1
| ass array=([index]=vall [index1]=val2)
|
+4.7 遍历数组
+1 2 3 4 5 6 7 8 9 10 11 12
| my_array=('Black' 'Copper' 'Crowntail' 'Dragon' 'Dumbo_Halfmoon'
'Dumbo_HMPK' 'Fighter' 'Giant' 'Halfmoon' 'Imbellis' 'Koi' 'Mahachaiensis' 'Orange' 'Red' 'Royal' 'Siamorientalis' 'Smaragdina' 'Smaragdina_guitar' 'Splendens' 'Steel' 'Stiktos' 'Turquoise' 'Veiltail' 'White' 'Yellow')
for value in ${my_array[*]} do
in_file="${outdir}${value}_ID.txt"
echo -e "${in_file}\n"
done
|
+五、函数
+5.1 定义
+1 2 3 4 5
| function 函数名(){
# 函数体
}
|
+5.2 函数的参数
+函数参数是函数调用时,用以传递给函数的一些数据,Shell中函数可以接受多个参数。除了传递进来的参数外,每个函数中还都包含了一些内部参数,常用获取内部参数使用的,常见的内部参数符号如下所示:
+
+
+
+符号 |
+意义 |
+
+
+
+
+# |
+传递到脚本的参数个数 |
+
+
+* |
+以一个单字符串显示所有向脚本传递的参数 |
+
+
+$ |
+脚本运行是的档期那进程ID号 |
+
+
+l |
+后台运行的最后一个进程ID号 |
+
+
+@ |
+与*相同,但是使用时加引号,并在引号中返回每个参数 |
+
+
+- |
+显示Shell使用的当前选项,与set命令功能相同 |
+
+
+? |
+显示最后命令的退出状态 |
+
+
+
+六、文本处理命令
+6.1 格式化输出
+6.1.1 语法
+格式化输出能够对把输出的内容根据指定的格式输出,自动进行对齐、换行等操作。格式化输出内容使用的是printf指令,printf指令常用的格式化字符如下所示
+1 2 3 4 5 6
| # 语法 printf format-string [arguments...] # 举例 printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg # 输出 姓名 性别 体重kg
|
+6.1.2 格式化字符
+格式说明符由 % 字符开始,后跟一个或多个字符,用于指定输出的格式。常用的格式说明符包括:
+
+%s
:字符串
+%d
:十进制整数
+%f
:浮点数
+%c
:字符
+%x
:十六进制数
+%o
:八进制数
+%b
:二进制数
+%e
:科学计数法表示的浮点数
+
+6.1.3 printf 的转义序列
+
+
+
+序列 |
+说明 |
+
+
+
+
+\a |
+警告字符,通常为ASCII的BEL字符 |
+
+
+\b |
+后退 |
+
+
+\c |
+抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
+
+
+\f |
+换页(formfeed) |
+
+
+\n |
+换行 |
+
+
+\r |
+回车(Carriage return) |
+
+
+\t |
+水平制表符 |
+
+
+\v |
+垂直制表符 |
+
+
+\ |
+一个字面上的反斜杠字符 |
+
+
+\ddd |
+表示1到3位数八进制值的字符。仅在格式字符串中有效 |
+
+
+\0ddd |
+表示1到3位的八进制值字符 |
+
+
+
+6.2 sed命令
+sed是一个很好的文本处理工具,其本身是一个管道命令,主要是以行为单位进行文本文档的处理,可以将数据行进行替换、删除、新增、选取等特定工作。sed常用选项及功能如下所示:
+1 2
| # 语法 sed [-hnV][-e<script>][-f<script文件>][文本文件]
|
+
+
+
+参数 |
+作用 |
+
+
+
+
+-h |
+显示帮助 |
+
+
+-n |
+使用安静模式 |
+
+
+-v |
+显示版本信息 |
+
+
+-e |
+以选项中指定的script(命令行)来处理输入的文本文件 |
+
+
+-f |
+以选项中指定的script(文件)来处理输入的文本文件 |
+
+
+-r |
+执行正则表达式的语法 |
+
+
+-i |
+直接修改读取的文件内容,而不是输出到终端 |
+
+
+动作 |
+作用 |
+
+
+a |
+新增行,a的后面可以是字符串 |
+
+
+c |
+取代行,c的后面可以是字符串 |
+
+
+d |
+删除行,通常后面不接参数,直接删除对应行 |
+
+
+i |
+插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行); |
+
+
+p |
+打印,将某个选择的数据打印出,通常与-n选项一起运行 |
+
+
+s |
+替换,直接或通过正则表达式进行替换 |
+
+
+
+6.3 awk命令
+作为一款文本处理工具,awk被设计用于数据流,其不仅能够对行进行操作,还可以对列进行操作。awk命令有许多内建的功能,比如数组、函数等,具有很大的灵活性。
+1 2 3 4 5 6 7 8 9 10
| # 【语法】 awk ‘BEGIN(command}{command 1}END{command 2}‘file
# command是脚本开始执行时执行的命令
# command 1为脚本执行过程中执行的命令
# command 2为脚本执行结束时执行的命令
# file是需要被处理的文件名称
|
+6.4 diff命令
+diff命令能够对两个文件进行详细的对比,并将差异结果进行重点标记,输出到文件中。输出到的文件成为被修补文件(patchfile),其中包含了修改过的、添加、删除的行及行号,用户可以通过修补文件对源文件进行更改。
+1 2 3 4
| # 【语法】 diff ver1ver2
# ver1和ver2是要对比的两个文件,对比结果会输出到终端中,也可以采用重定向的方式将输出保存到任意位置
|
+