Shell概述
一方面,Shell相当于一个命令解释器,将Linux命令解释为二进制机器码,或者反过来,将二进制机器码解释为Linux命令。其实我们启动Linux后命令交互界面就是系统给用户提供的一个Shell解释器的界面。
另一方面,Shell也是一种解释执行的脚本编程语言,并且在Shell中可以直接调用Linux系统命令。
Shell语言类型主要有两种Bourne Shell和C Shell,前者一般简称为B Shell,这两种语言的语法是互不兼容的。而Bourne家族的语言主要包括sh(即B Shell)、ksh、Bash(Linux默认的标准Shell)、psh、zsh,C家族的语言主要包括csh、tcsh。但各自家族的语言的语法是类似的。
Linux系统支持的Shell可以通过`/etc/shells`查看,如果在命令行直接输入sh,则表示将使用B Shell语言来执行(注意Linux默认的是Bash,而不是B Shell)。
第一个脚本
#!/bin/bash #这是注释:将该文件保存为hello.sh echo -e "hello world."
echo [选项] 输出内容:打印输出。
- -e:支持反斜杠控制的字符转换,具体的转义规则可网上搜索相关资料。
脚本编写:Shell脚本的第一行必须是#!/bin/bash,这句话表明此行语句之后的内容为Shell脚本,系统应该使用Shell去执行后面的程序。
赋予权限:“chmod 755 hello.sh”新建的文件是没有执行权限的,需要赋予它执行权限。
执行脚本:有两种方式来执行脚本,第一种方式,使用绝对路径或相对路径来直接运行,如./hello.sh,就可以直接运行该文件。第二种方式,调用bash来运行脚本,如bash hello.sh,注意命令只有小写没有大写,所以不能写成“Bash hello.sh”。推荐使用第一种方式,第二种方式了解就行,因为第二种方式不需要指定第一行的#!/bin/bash,也不需要赋予它执行权限,相当于直接调用bash来解释并执行这个脚本。
dos2unix:如果你的脚本是在Windows中编译的,那么在Linux上是不能运行的,此时只需要安装一个dos2unix就可以了,执行“dos2unix sh文件”就可以将其格式转换为Linux中的格式了。
bash常用快捷键
以下快捷键不区分大小写,直接按对应快捷键即可。
- Ctrl+C:强制终止当前的命令。
- Ctrl+L:清屏,相当于clear命令。
- Ctrl+U:删除和剪切光标之前的命令。
- Ctrl+K:删除和剪切光标之后的命令。
- Ctrl+Y:粘贴Ctrl+U或Ctrl+K中剪切的内容。
- Ctrl+R:在历史命令中搜索,按下Ctrl+R后就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索对应内容。
- Ctrl+D:退出当前终端(断开连接)。
- Ctrl+A:将光标移动到命令开头。
- Ctrl+E:将光标移动到命令结尾。
- Ctrl+S:暂停屏幕输出。
- Ctrl+Q:恢复屏幕输出。
历史命令
history [选项] [历史命令保存文件]:显示执行过的历史命令。
选项:
- -c:清空历史命令(除非极特殊的情况,否则不建议清空)。
- -w:把缓存中的历史命令写入历史命令的保存文件,这个文件默认在用户家目录下的“.bash_history”文件。历史命令平时是保存在缓存中的,正常是需要用户退出登录之后才会将缓存中的历史命令保存进文件。
保存数量:默认会保存1000条历史命令,这个设置保存在/etc/profile中的HISTSIZE=1000中,如果想要多保存一些历史命令,可以更改这个配置后重新登录即可。
使用技巧:
- 使用上、下箭头调用以前的历史命令。
- 使用“!n”执行第n条历史命令。
- 使用“!!”执行上一条命令。
- 使用“!字符串”执行最后一条以该字符串开头的命令。
命令别名
alias 别名=‘原命令‘:给一个命令定义一个别名。直接执行alias就可以查看已经定义好的别名,如常用的ll命令其实是“ls -l --color-auto”的别名。
用户新增加的以命令形式定义的别名只是临时生效的,想要永久生效,需要到自己的家目录下的“.bashrc”文件中进行配置。注意,定义别名时应该尽量避免和原有命令重复。
unalias 别名:删除别名。
命令执行时的查找和执行顺序:
- 使用绝对路径或相对路径的命令。
- 命令别名。
- bash内部命令(这种命令是没有对应的命令文件的)。
- 按照$PATH环境变量定义的目录查找顺序找到的第一个命令,直接使用“echo $PATH”即可打印环境变量的内容。
标准输入输出重定向
标准输入:键盘,设备文件名为/dev/stdin,文件描述符0。
标准输出:显示器,设备文件名为/dev/stdout,文件描述符为1。
标准错误输出:显示器,设备文件名为/dev/stderr,文件描述符为2。
标准输出重定向:
以下四种是将正确的输出和错误的输出分开来的,但是这种方式不常用:
- 命令 > 文件:以覆盖的方式把命令的正确输出结果输出到指定的文件或设备中。
- 命令 >> 文件:以追加的方式把命令的正确输出结果输出到指定的文件或设备中。
- 命令 2> 文件:以覆盖的方式把命令的错误输出结果输出到指定的文件或设备中。
- 命令 2>> 文件:以追加的方式把命令的错误输出结果输出到指定的文件或设备中。
以下五种是将正确和错误的输出到同一个文件中,这是常用的方式,因为你其实并不知道这个命令是否会报错:
- 命令 > 文件 2>&1:以覆盖的方式将正确和错误的输出都保存到同一个文件里(这句话的意思其实是先将2(错误输出)的输出保存到1(正确输出)当中,再使用前面的>将1的结果输出到文件中)。
- 命令 >> 文件 2>&1:以追加的方式将正确和错误的输出都保存到同一个文件里。
- 命令 &> 文件:以覆盖的方式将正确和错误的输出都保存到同一个文件里(常用的方式)。
- 命令 &>> 文件:以追加的方式将正确和错误的输出都保存到同一个文件里(常用的方式)。
- 命令 >> 文件1 2>> 文件2:将正确的输出保存在文件1中,将错误的输出保存在文件2中。
命令 &> /dev/null:丢弃此命令的输出。
输入重定向(不常用):
- 命令 < 文件名:将命令的输入重定向到指定文件。
示例:
wc [选项] < [文件名]:把统计命令的输入,重定向到指定文件。
- -c:统计字节数
- -w:统计单词数
- -l:统计行数
多命令顺序执行
命令1;命令2;命令3;...:使用分号;连接多个命令,命令之间没有任何逻辑关系,即使中间某个命令报错了也不会影响后面的命令执行。如“date ; 命令 ; date”可以测试命令执行的耗时。
命令1&&命令2&&...:即逻辑与,使用&&连接多个命令,命令1正确执行了,才会去执行命令2;命令1报错了,就不会执行命令2。
命令1||命令2||...:即逻辑或,使用||连接多个命令,命令1正确执行了,就不会去执行命令2;命令1报错了,才会执行命令2。
命令 && echo yes || echo no:可以使用这个命令格式来测试某个命令是否被正确执行。
管道符
命令1 | 命令2:命令1的正确输出作为命令2的操作对象。
示例:
ll -a /etc/ | more:使用more来显示前面命令的输出。
netstat -an | grep "ESTABLISHED":在netstat -an的输出中查找关键字ESTABLISHED。
通配符
?:匹配一个任意字符。
*:匹配0个或任意多个任意字符,也就是可以匹配任意内容。
[]:匹配中括号中的任意一个字符。
[-]:匹配中括号中表示的范围中的任意一个字符,如[a-z]。
[^]:匹配非中括号中表示的任意一个字符,如[^0-9]。
特殊符号
‘‘:单引号,单引号中的所有特殊符号都没有了其特殊含义,如$等。
"":双引号,在双引号中大多的特殊符号都没有了其特殊含义,但是$(调用变量的值)、``(反引号,即键盘上和~一起的键,表示引用命令)和\(转义符)是例外。
``:反引号,反引号括起来的是系统命令,Bash会优先去执行它。但是不推荐使用,因为使用时很容易看成单引号。
$():括号中的内容为系统命令,作用和反引号一致,推荐使用这种方式调用系统命令,而不是反引号。
#:表示脚本或配置文件中的注释。
$:用于调用变量的值。
\:转义符。