Shell
1 什么是shell
shell(外壳)是一个用C语言编写的程序,它是用户适用Linux是桥梁。shell既是一种命令语言,又是一种程序设计语言。
shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
使用shell进行程序开发的效率非常高,在Linux中有很多类型的shell,不同的shell具备不同的功能,shell还决定了脚本中函数的语法,Linux默认的shell是/bin/bash
,流行的shell有ash, bash, ksh, csh, zsh, nologin等,不同的shell都有自己的特点和用途。
其中nologin
用于指定某个用户不能登录:
#usermod -s /sbin/nologin 用户名
大多数Linux系统默认使用的是bash
,可以通过help命令来查看帮助,且包含的功能几乎可以涵盖shell所具有的的功能,所以一般的shell脚本都会指定bash
为执行路径。
2 shell入门
(1) 代码规范
#!bin/bash 【告知系统当前这个脚本要使用的shell解释器】
shell相关指令
(2) 文件命名规范
文件名.sh
【.sh是Linux下bash shell的默认后缀】
(3) 使用流程
- 创建
.sh
文件 【#touch/vim
,当使用vim打开未创建的文档时,若保存修改,则创建成功】 - 编写shell代码
- 执行shell脚本 【脚本必须得有执行权限】
实例:创建test.sh
,实现第一个shell脚本程序,输出hello world!
#echo 待输出文本 【输出命令】
注:输出的内容如果包含字母和符号(不包含变量),则需要用引号括起来;如果是纯数字可以括也可以不括。
由于创建的文档默认情况下没有执行权,因此需要赋予test.sh执行权:
#chmod +x test.sh
注意,这里运行时一定要写成#./test.sh
,而不是#test.sh
,运行其他二进制文件的程序也一样。直接写#test.sh
,Linux系统会去PATH
(环境变量)里寻找有没有叫test.sh
的,而只有/bin, /sbin, /usr/sbin等再PATH中,你的当前目录通常不在PATH里,所以写成test.sh
是找不到命令的,要用#./test.sh
告诉系统,就在当前目录找。
实例:使用root用户账号创建并执行test2.sh
,实现创建一个shelltest
用户,并在其家目录中新建文件try.html
。
3 shell进阶
3.1 变量
3.1.1 变量的定义与使用
变量需先定义后使用。
定义:变量名=变量值
【如x="test"
】
使用:$变量名
【如echo $x
】
注意,变量名后面的等号左右不能有空格,此外,变量名的命名需遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头;
- 中间不能有空格;
- 不能使用标点符号;
- 不能使用
bash
里的关键字(可用help
命令查看保留关键字)
实例:使用变量实现hello world!
的输出。
关于单双引号的问题:
(1) 单引号不能识别变量,只会原样输出,而且单引号不能实现转义。
(2) 双引号能够识别变量,而且能够实现转义(类似于“*”,乘号)。
实例:定义一个变量,输出当前时间,要求格式为“年-月-日 时:分:秒
”。
若直接将命令赋予给变量:
当在脚本中需要执行一些指令并将执行的结果赋予给变量时,需要只用“反引号”(Esc
键下方的键)。
3.1.2 只读变量
语法:readonly 变量名
实例:定义变量a并且其值为10,随后设置其为只读变量,再去尝试赋予新的值。
3.1.3 接收用户输入
语法:read -p 提示信息 变量名
实例:编写一个脚本test.sh,要求执行之后提示用户输入文件的名称(路径),然后自动为该用户创建文件。
3.1.4 删除变量
语法:unset 变量名
实例:定义变量a=20,再输出a的值,随后删除a,最后再输出a的值。
注:echo输出为空也会占一行。
3.2 条件判断语句
语法1:
if [ condition ]
then
command1
command2
...
fi
单行写法:if [ condition ];then command;fi
注:[ condition ],condition左右有空格
语法2:
if [ condition ]
then
command1
command2
...
else
command
fi
语法3:
if [ condition ]
then
command1
elif [ condition ]
then
command2
else
command3
fi
3.3 运算符
在shell中,运算符和其他编程脚本语言一样,常见的有算术运算符、关系运算符、逻辑运算符、字符串运算符以及文件测试运算符等。
3.3.1 算术运算符
下表列出了常用的算术运算符,假定变量a为10,变量b为20:
注意:
- 条件表达式要放在方括号之间,并且表达式和运算符之间要有空格,例如:
[$a==$b]
是错误的,必须写成[ $a == $b ]
。 - 原生
bash
不支持简单的数学运算,但是可以通过其他命令来实现,例如awk
和expr
,expr
最常用。expr
是一款表达式计算工具,使用它能完成表达式的求值操作。例如,两数相加:
#!bin/bash
val=`expr 2 + 2`
echo "两数之和为:$val"
注意使用的是反引号`,而不是单引号’,完整的表达式要被反引号包含。
代码实例:
输出:
3.3.2 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值为数字。
下表列出了常用的关系运算符,假定变量a为10,变量b为20:
其中:
-eq
:equal-ne
:not equal-gt
:greater than-lt
:less than-ge
:greater than or equal-le
:less than or equal
3.3.3 逻辑运算符
下表列出了常用的逻辑运算符,假定变量a为10,变量b为20:
3.3.4 字符串运算符
下表列出了常用的字符串运算符,假定变量a为"abc",变量b为"efg:
3.3.5 文件测试运算符
文件测试运算符用于检测Unix/Linux文件的各种属性,属性检测描述如下:
代码实例:
3.4 shell脚本附带选项
问题描述:在Linux shell中如何处理tail -10 test.txt
这样的命令行选项?
步骤:
- 调用tail指令
- 系统把后续选项传递给tail
- tail先去打开指定的文件
- 取出最后10行
问题:自己写的shell是否也可以想内置命令一样传递一些选项呢?
答:可以。传递方式与上述的描述一致,关键是怎么接收。例如:
传递:
#./test.sh a b c
接收:
在脚本中可以使用“$1
”表示a,“$2
”表示b,以此类推。
也就是说,接收参数只需要用$
加上选项对应的序号即可。
实例:编写test1.sh
,传递a, b, c
,并输出其值。
其中$1, $2, $3
是变量。
实例:创建自定义指令“user
”,可以直接执行,要求该指令具备以下语法和功能:
#user -add 用户名
【添加用户】#user -del 用户名
【删除用户及其家目录】
同时题目中要求是指令,因此需要添加别名(别名机制依靠的是一个别名映射文件:~/.bashrc
):
编辑之后使创造的命令生效需执行:source ~/.bashrc
,或重新登录当前用户。