Shell基础
Shell是什么
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统的关键。
可以说,shell使用的熟练程度反映了用户对Linux使用的熟练程度。
Shell就是壳的意思。
Linux内核只能读懂0101的机器语言,而无法读懂我们的语言,而Shell就是访问的翻译者,通过ASCII码将命令转换成内核能读懂的机器语言。而内核执行的结果也会通过shell翻译给我们。也就是说,Shell是命令行解释器。
同时,Shell也是一种功能十分强大的编程语言。我们可以通过shell编程来完成特定的工作。
Shell有两种命令执行方式:
1.交互式(Interactive:解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
2.批处理(Batch:用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。
Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。
Shell的分类
shell可以分为两类:
1.B Shell(Bourne Shell)
2.C Shell
历史上第一种Shell,sh就是B Shell,不过它不支持历史命令功能,所以每一条命令都必须手打,不是很方便。除此之外,B Shell还包括ksh,Bash,psh,zsh。而Linux现在使用的Shell一般都是Bash。
对于C Shell,C Shell与C语言非常类似而得名,Unix中的为C Shell,主要有csh,tcsh。
如何查看当前Shell类型呢?可以查看$SHELL变量。
[root@localhost ~]# echo $SHELL
/bin/bash
我们的Shell中也兼容很多其他的Shell。
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
这些都是我们可以兼容的Shell。
只要调用相应的命令就可以创建一个子Shell,并在其中执行命令。
例如:
[root@localhost ~]# sh
sh-4.2#
这样我们就进入了sh Shell。退出只需要exit即可。其他Shell进入也是一样的。
简单的Shell脚本
创建一个文件,并且编辑如何内容:
#!/bin/bash
echo "Hello World !"
在Shell中#是注释的意思,但是#!bin/bash中的#并不是注释,这表明这是一个脚本文件,是必须的。否则无法调用其它语言。
保存之后,如何执行呢?
方法1:
bash 文件名
[root@localhost tmp]# bash helloworld.sh
Hello World
给文件赋予执行权限,然后直接运行。
[root@localhost tmp]# chmod 755 helloworld.sh
[root@localhost tmp]# ./helloworld.sh
Hello World
Bash的基本功能
1.命令的别名
alias
查看所有存在别的命令的别名
[root@localhost tmp]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
可以看到一些已经存在的别名。
例如ls其实是不支持颜色的,平常我们调用的是ls --color=auto,就支持颜色了。
alias 别名=原命令
设定临时命令别名
[root@localhost tmp]# alias ls='ls -l'
[root@localhost tmp]# ls
total 8
-rwxr-xr-x. 1 root root 31 Apr 28 15:55 helloworld.sh
-rwx------. 1 root root 827 Apr 25 11:20 ks-script-EcWwWC
-rw-------. 1 root root 0 Apr 25 11:11 yum.log
ls就变成了ls -l命令
如果希望定义永久别名,也就是关机之后重新开机也能存在的别名,需要写入环境变量~/.bashrc中。
[root@localhost /]# vim /root/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
在这里定义别名即可。
环境变量配置好了,需要重启才能生效,如需立即生效使用source 文件名生效。
存在别名这种设定的话,那么就很容易就想到,命令是以什么优先级来执行的呢?我们会调用别名,而不是实际的命令,说明别名的优先级在实际命令的优先级之上。
命令的优先级:
1. 以绝对路径调用的命令
2. 别名
3. Bash的内部命令
4. $PATH变量中搜寻的外部命令。
所以,我们定义别名的时候,需要注意不能覆盖了Bash的内部命令,否则会造成内部命令无法调用的情况。
2.Bash的常用快捷键
Ctrl + a :移到命令行首
Ctrl + e :移到命令行尾
Ctrl + u :从光标处删除至命令行首
Ctrl + l:清屏
Ctrl + c:终止命令
Ctrl + z:挂起命令
Alt + u :从光标处更改为全部大写的单词
Alt + l :从光标处更改为全部小写的单词
其中ctrl+z为将服务挂起,变为后台命令,不是终止命令。
3.Bash的历史命令
history [选项]
其中直接调用history可以看到历史命令。
history查看到的命令为缓存+.bash_history。
其中~/.bash_history是保存在文件中的命令,关机的时候,会执行相应的保存操作,将缓存的历史保存到这个文件中,以便下次查看。
~/.bash_history默认保存1000条命令,这个可以到/etc/profile配置文件中进行修改。
选项
-c: 清空~/.bash_history和缓存
-w: 将缓存中的历史写入~/.bash_history中
除此之外,还可以使用
1.键盘上下键来选择历史命令
2.!n调用历史中第n条命令
3.!!调用你一条命令
4.!字符串,调用以这个字符串开头的最近的一条命令。
一般用上下键或者!字符串就可以了。。。
4.重定向
重定向是什么意思呢?
首先我们需要只要,标准输入,标准输出,标准错误输出。
他们分别用0,1,2来表示。默认为键盘,显示器和显示器。
当我们需要将输入或者输出,不输出到标准中的话,而是希望输出到自己想要的地方的过程就是重定向。
例如:也就是说,原本是要输出到显示器中的内容,我们改变他的输出方向,到文件中。这就是输出重定向。
正确输出重定向:
> 输出重定向到一个文件或设备 覆盖原来的文件
>> 输出重定向到一个文件或设备 追加原来的文件
错误输出重定向:
2> 错误输出重定向到一个文件或设备 覆盖原来的文件
2>> 错误输出重定向到一个文件或设备 追加原来的文件
但是这样很麻烦,我们要正确区分是正确还是错误输出。如果是错误输出,使用>就会不生效。
所以我们有正确和错误都会输出的符号:
&> 将一个标准正确和错误输出重定向到一个文件或设备 覆盖原来的文件
&>> 将一个标准正确和错误输出重定向到一个文件或设备 追加到原来的文件
我们也可以使正确输出和错误输出分离。
>> 文件1 2>> 文件2
输入重定向
command {<} [File] {<<} [Word]
从文件中取出数据给命令使用
[root@localhost ~]# wc < anaconda-ks.cfg
44 105 1209
5.多命令顺序执行
当我们需要一次执行多个命令的时候,命令之间需要用连接符连接,不同的连接符有不同的效果。
符号 | 解释 |
;(分号) | 分号,没有任何逻辑关系的连接符。当多个命令用分号连接时,各命令之间的执行成功与否彼此没有任何影响,都会一条一条执行下去。 |
||(逻辑或) | 逻辑或,当用此连接符连接多个命令时,前面的命令执行成功,则后面的命令不会执行。前面的命令执行失败,后面的命令才会执行。 |
&&(逻辑与) | 逻辑与,当用此连接符连接多个命令时,前面的命令执行成功,才会执行后面的命令,前面的命令执行失败,后面的命令不会执行,与 || 正好相反。 |
|(管道符) | 管道符,当用此连接符连接多个命令时,前面命令执行的正确输出,会交给后面的命令继续处理。若前面的命令执行失败,则会报错,若后面的命令无法处理前面命令的输出,也会报错。 |
判断我们的命令是否执行成功,如果成功输出Yes,否则输出No。
[root@localhost /]# ls && echo Yes || echo No
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
Yes
[root@localhost /]# ls1 && echo Yes || echo No
-bash: ls1: command not found
No
通配符:
?: 匹配任意一个字符
*: 匹配任意字符(0到多个)
[]: 匹配[]中任意字符
[-]: 与上面一样,简写,例如[a-z]
[^]: 取反,例如[^0-9]匹配所有除了0-9数字的字符
特殊符号:
符号 | 解释 |
''(单引号) | 被单引号括住的部分视为单一字符串,特殊符号的失去意义 |
""(双引号) | 被双引号括住的部分,特殊符号失去意义,除了$,`反引号,\反斜杠 |
``(反引号) | 反引号括住的部分先执行 |
$ | 调用变量值 |
$() | 括号括住部分先执行 |
# | 注释 |
\ | 转义符 |