Shell基础
来源:互联网 发布:解决sql挂起 编辑:程序博客网 时间:2024/06/05 20:05
一、Shell中的变量
任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识。
0、默认变量
首先介绍几个shell中的默认变量。
示例如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
1、变量定义及赋值
- 1
- 2
- 3
- 1
- 2
- 3
但是要注意的是,赋值处必须为一个整体,不能有空格。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
想要包含空格,需要用单引号或双引号包围,如
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
2、单引号(')和双引号(")的区别
上面的示例中看到hello world
使用单引号或双引号包围再赋值给变量时,两者效果相同,但是其中的区别在哪里?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
可以看到,单引号中的$a
保持原样输出。而双引号中的$a
会替换成其变量值。
3、`符号
这个符号在数字键1的左侧,与单引号很类似。但是其功能与单引号双引号都有不同。在该符号中的命令会被执行。
- 1
- 2
- 3
- 1
- 2
- 3
如果不想使用这个符号,可以用$()
替换
- 1
- 2
- 3
- 1
- 2
- 3
4、命令行交互read
有时候我们希望在脚本运行时能根据用户的输入决定脚本后续执行逻辑,比如在安装插件的时候经常会让用户选择输入[N/Y]
的时候。
比如有一个脚本script_test.sh
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在运行时根据用户的输入决定if
分支的走向。运行结果如下
- 1
- 2
- 3
- 1
- 2
- 3
read
命令的使用形式为
- 1
- 2
- 3
- 1
- 2
- 3
例如,
- 1
- 1
表示将输入内容赋值给变量name
,用户有5秒钟的输入时间。
5、定义变量类型declare
默认情况下,变量的赋值内容都是字符类型的。例如下面的代码,我们期望的是输出一个求和值,但是输出的是一个求和表达式。
- 1
- 2
- 3
- 1
- 2
- 3
如果想要输出求和后的值,可以使用declare命令。
- 1
- 2
- 3
- 1
- 2
- 3
declare
命令的使用形式如下:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
二、Shell中的集合类型
1、数组(array
)
(1)数组定义和赋值
数组中的元素用括号包围,各元素之间用空格隔开。例如
- 1
- 1
可以重新设置指定元素的内容,如下所示
- 1
- 2
- 3
- 1
- 2
- 3
(2)数组元素访问
输出该数组中所有元素:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
数组元素下标从0开始,想要访问指定位置的元素,使用[]指定下标值,如下所示
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
(3)获取数组长度
获取数组长度使用如下命令
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
获取数组中单个元素的长度使用如下命令
- 1
- 2
- 1
- 2
2、map
map
类型中存储的都是键值对。
在Shell中定义map
变量如下所示:
- 1
- 1
输出所有的key
- 1
- 2
- 1
- 2
输出所有的value
- 1
- 2
- 1
- 2
输出指定key
对应的value
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
添加元素
- 1
- 2
- 3
- 1
- 2
- 3
map
中键值对的个数
- 1
- 2
- 1
- 2
三、Shell中的字符操作
在任何语言中对字符串的操作都是非常频繁的。字符串的操作主要包括,字符串截取,字符串替换等。
接下来的示例中,都以字符串http://blog.csdn.NET/dabokele
作为初始字符串。
- 1
- 1
1、字符串删除
删除前面的http://
- 1
- 2
- 1
- 2
删除后面的dabokele
- 1
- 2
- 1
- 2
#
从前往后截取,%
从后往前截取。
示例中表示将符合的最短数据删除,如果使用两个#
,或者两个%
,则表示将符合的最长数据删除。
如下所示,匹配最短时,会将https://csdn.ne
删除,匹配最长时,会将全部字符删除。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
2、字符串截取
可以从字符串的指定位置开始截取,同时可以指定截取的位数,如下所示:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
3、字符串替换
将http
替换成HTTP
- 1
- 2
- 1
- 2
- 使用一个斜杠(
/
)表示只替换第一个遇到的字符。 - 使用两个斜杠(
//
)则表示替换全部符合的字符。 - 使用
#
匹配以指定字符开头的字符串。 - 使用
%
匹配以指定字符开头的字符串。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
4、字符串默认值
假设以下这个场景,如果变量name
没有赋过值,则给一个默认值default
,否则使用指定的值。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
但是,如果已经将变量name设置成“”,则结果如下:
- 1
- 2
- 1
- 2
如果变量内容为“”或者变量未初始化则给默认值,可以在-
前加个冒号,使用:-
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
5、字符串拼接
字符串拼接如下所示
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
6、字符串长度
求字符串长度用#
操作,如下所示
- 1
- 2
- 1
- 2
7、字符串split成数组
在以空格为分隔符分割字符串成数组时操作最简单。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
所以,如果需要指定特定字符进行分割,而原字符串中又没有空格时,可以先将特定字符替换成空格,然后按照上述进行分割,如下所示,
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
如果字符串中本身已有空格,并且期望的分隔符不是空格,按如下方法进行分割。首先将IFS
变量替换成指定字符,分割后再将IFS
更新为原字符。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
8、字符串包含
有时候需要判断字符串str1
中是否包含字符串str2
,使用=~
操作符。
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
查看运行结果
- 1
- 2
- 1
- 2
四、Shell中的控制结构
0、循环接收脚本参数shift
测试脚本如下:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
查看脚本运行结果
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
1、条件表达式
(1)if … then
判断表达式是经常用到的。整体结构如下所示,其中if
和fi
是必须的,中间的elif
和else
是可选的。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
a)算术运算符
算术运算符的使用格式如下
- 1
- 2
- 3
- 1
- 2
- 3
常用的算术运算符包括
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。
b)关系运算符
关系运算符的使用格式如下
- 1
- 2
- 3
- 1
- 2
- 3
常用的关系运算符包括
[ $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。
c)布尔运算符
常用的布尔运算符如下
[ ! false ]
返回 true。-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ]
返回 true。-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ]
返回 false。
d)字符串运算符
常用的字符串运算符如下
[ $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。
e)文件测试运算符
常用的文件测试运算符如下
[ -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检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 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。
(2)case … esac
case
表达式的使用格式如下
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
看一个示例,如果第一个参数为hello
,则打印hello world
。如果第一个参数是bye
,则打印bye bye
。如果是另外的情况,则输出该参数。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
运行结果
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
2、循环表达式
(1)while do done, untile do done
while
循环的格式如下
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
与while
循环相反的是until
循环。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
在while
循环中,当条件满足使,就执行其中的程序。而until
循环中,当条件不成立时就终止循环。
下面举例用两种循环来实现当输入为yes
时跳出循环。
a) while循环示例如下
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
运行结果
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
b) until循环示例如下
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
运行结果如下
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
(2)for … do … done
for
循环的格式如下
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
下面这个示例循环打印输入参数列表
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
运行结果如下
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
(3)for … do … done的另一种形式
for
循环的另一种个数如下
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
循环输出1
到10
中的奇数
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
运行结果如下
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
五、Shell中的函数
在Shell中也可以像其他编程语言那样,将代码块封装成函数。Shell中的函数,需要注意以下两点:
1、函数定义
由于Shell是从上往下执行的,所以在定义函数之前就调用该函数的话,会提示command not found
,例如
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
运行结果如下,前一个函数调用处提示command not found
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
2、函数参数与shell参数
在Shell中定义的函数,是可以传递和接收参数的。在子函数中,$1
表示接收的第一个参数…,这里需要注意与shell参数的区别。
但是测试后发现$0
表示的仍然是shell名称。如果想要显示当前函数名,可以使用$FUNCNAME
参数,如下所示,
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
运行结果如下,
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
六、vi快捷操作
下面操作中出现大写字母,比如G
表示需要同时按住Shift
和G
键。n
表示输入的数字。其他比如text
则表示字符串。
1、跳转
2、查找和替换
(1)查找
(2)替换
在最后输入一个c
(confirm),表示替换前弹出确认提示。按y
则逐一替换当前光标处匹配的字符,n
则跳过当前光标处字符,a
替换全部匹配的字符。
3、复制、删除、撤销、重复
(1) 复制
另外,输入y+跳转
中的操作,可以为复制指定方向。比如yw
,从当前位置复制到下一个单词的开头。这样可以进行复制一个单词的操作。
(2)删除
另外,输入d+跳转
中的操作,可以为删除指定方向。比如dw
,从当前位置删除至下一个单词的开头。
(3)撤销
(4)重复
4、其他
5、列编辑
按Ctrl + v,进入列编辑模式。
(1)删除列
进入列编辑模式,
移动光标,选中需要删除的列,
按d,则会删除选中内容。
(2)插入列
进入列编辑模式,
移动光标选中需要插入内容的列。
按shift + i,会在选中列的第一行输入想要插入的内容。
连续按两次ESC,则会在选中的列处全部插入输入字符。
- 顶
- 踩
- Shell基础
- Shell 基础
- Shell 基础
- shell基础
- shell 基础
- shell基础
- shell基础
- Shell基础
- shell基础
- shell基础
- shell基础
- Shell基础:
- shell基础
- shell 基础
- shell基础
- shell基础
- shell基础
- shell基础
- mac apached 代理搭建
- ARP 应用——检测IP地址冲突
- OCR光学字符识别
- 网页网站运行时间计算
- BIO编程
- Shell基础
- windows下pygame的安装
- 基本数据类型与引用数据类型的不同
- 并发(十五):怎么证明Hashmap不是线程安全的?
- [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:compile (default-c
- 人活着系列之开会(Floyd)
- 约瑟夫环问题(数组和list方法)
- WaitForSingleObject
- 背包问题