SHELL初始和扩展
在国庆期间我把Linux命令再系统的过了一遍,作为后端开发人员必备的技能,我感觉自己不论是对Linux命令的掌握,还是对Linux内核设计、实现的理解都很薄弱,所以国庆特意加班加点再过了一遍,回忆起了很多之前淡忘的命令。
言归正传,什么是SHELL编程呢,我们一般把shell编程得到的结果称为shell脚本,同时,现在使用的最多的shell是bash,所以shell脚本也被称为bash脚本。shell脚本是一种格式非常规整、严格的脚本语言,有时多打一个空格或者少打一个符号可能都会导致很多问题,这也意味着shell开发人员不仅要对语法、对命令很熟悉,同时也要非常非常细心。
shell为什么是一门脚本语言,其实虽然它被称为语言,但是说到底就是命令的集合加上特定的格式就变成了shell脚本。比起一门语言,我更将它认为是一种批处理文本,类似于声明式API,将命令写入到文件中,再执行这个文件。之所以将它称之为脚本,因为它是一行一行由解释器解释执行的,具有这种性质的语言,都称之为脚本语言。
shell初识
什么是shell?翻译过来就是“壳”,指的是操作系统的表层,与操作系统的内核(kernel)对应,是用户和内核交互的界面。这里要区分shell terminal和consule之间的区别。shell特指命令行,而terminal是终端,很多应用软件都有中断,比如你打开Goland敲代码,是不是也可以输入命令操控程序?输入命令的那个平台就是terminal。同时我们的输入输出设备也可以看做是terminal。而console是控制台,早期电脑是很大的,电脑基本都配有console,console就是一个有很多开关、按钮的机器,用于控制电脑。
shell是一个程序。当你输入命令的时候,它会将命令传给内核执行,并把结果返回给用户。所以shell被称作命令行,类似于windows中的cmd和powershell。
同时,shell还是一个命令解释器,解释用户输入的命令,支持变量、条件判断、循环等语法,这些语句被解释器执行。
然后,shell还内置了很多工具,可以看成一个工具箱,提供了很多方便我们操作的API。
shell有很多种,只要能提供命令行环境的程序,我们都可以看做shell
现在Bash就是最常用的Shell
#查看当前设备默认的shell
echo $SHELL
#查看当前系统的所有shell
cat /etc/shells
#查看bash版本
bash --version
简单命令
echo
echo就是一个输出命令,可以看成Go语言的Println,自带换行
标签:
- -n 取消换行
- -e 解释转义字符 比如\n \r
这里学习了一下\r \n的区别
\r:光标回到行首
\n:光标回到行首,光标进行换行
用例子来看就是
echo -e "hello -n world"
hello
world
echo -e "hello \r world"
world
#因为已经将hello给覆盖掉了,\r回到行首,world将hello覆盖
echo -e "lll\rss"
ssl
#覆盖前两个
命令格式与逻辑
空格:我们通过空格来区分不同的参数,每个参数之间必须有一个或多个空格,如果是多个空格,解释器会自动缩忽略多余的空格
分号:命令的结束符,可以使得一行执行多个命令,在上一个命令结束后,执行下一个命令
**&&**:当上一个命令执行成功,继续运行第二个命令
**||**:当上一个命令执行失败,继续运行第二个命令
type命令
type命令用来判断命令的来源,因为bash内置了很多命令,我们可以通过type来判断一个命令是内置命令还是外部程序
type type
#这是一个内指命令
type ls
#这是 ls --color=auto的别名
快捷键(我不记得的)
- cl+l 清屏并且移动到页面顶部
- cl+u 从光标删除到行首
- cl+k 从光标删除到行尾
- cl+w 删除光标前一个单词
- cl+d 退出shell
Bash模式扩展
在shell收到命令之后会根据用户输入,拆分成一个个词元,然后shell会扩展里面的特殊字符,完成这步之后才会调用相应的命令。也就是翻译一些特殊符号。
其中部分扩展其实就是通配符扩展。
Bash一共提供八种扩展
- ~
- ?
- []
- {}
- 变量
- 子命令
- 算术
~
波浪线会自动扩展成当前用户的主目录,也就是/home/username,同时~+会扩展成当前目录,和pwd命令等效。
?
?代表匹配任意单个字符,不包括空
*
*代表文件路径里面的任意数量的任意字符,包括0个,且可以匹配空
【】
【】匹配方括号中的任意一个元素 比如 [abc] 满足匹配结果的为a b c,【-】,匹配范围之内的任意元素,比如【1-5】,满足匹配条件为1 2 3 4 5
{}
大括号匹配所有值,每个元素之间通过逗号分割,逗号与元素之间不能有空格
echo {1,2,3}
1 2 3
echo d {a,e,i,u,o}g
dag deg dig dug dog
#括号还可以嵌套
echo {j{p,pe},ng}
jpg jpeg png
{..}表示一个数组。比如{a..z}可以拓展成26个小写字母,同时支持逆序,{z..a}就是从z到a的输出
{..}可以指定步长 比如
echo {0..8..2}
0 2 4 6 8
变量
可以直接$name 或者 ${name}两种方式来扩展变量值,一般推荐第二种方式
子命令
比如 $(pwd) $(date)等等 直接拿到命令的值
算术扩展
((…))可以扩展成整数的运算结果,比如((2+2))
字符类
[[:class:]]表示一个字符类,扩展成某一类特定字符中的一个,常用的字符类有很多,匹配任意英文,数字,大小写等等
量词语法
+(pattern) :匹配一次或多次
@(pattern) 只匹配一次
!(pattern) 匹配给定内容之外的任何内容
引号与转义
在bash中只有一种数据类型,那就是字符串,不管用户输入什么数据,Bash都认为是字符串
某些字符在Bash中有特殊含义,比如$,你想要原样输出就必须通过转义的方式,比如\ $输出$。同时\还能改写命令,当一条命令过长,就可以在伟航使用\进行改写,使其成为多行。
mv \
/path/to/foo \
/path/to/bar
单引号
Bash允许字符串放在单引号或者双引号中,加以引用。单引号用于保留字符的字面含义,各种特殊字符在单引号里面,都会变为普通字符,比如 * $ \等等。单引号能使Bash扩展,变量引用和子命令都失效。所以在单引号里面用正则是什么呆瓜啊。
双引号
双引号比单引号款所,大部分特殊字符在双引号里都会失去特殊含义编程普通字符,只有$ 和 ` 和 \仍然会被扩展
重定向
cat << name
name
最后的name一定要顶格