Shell和命令基础
1.1 Shell简介
1.1.1 什么是Shell
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种操作(命令解释器),Shell接受用户输入的命令并把它送入到内核执行,在用户与系统之间进行交互。Shell在Linux系统中具有极其重要的地位。
图1-1 Shell在Linux系统中的地位
1.1.2 Shell的功能
命令解释器是Shell最重要的功能。Linux系统中的所有可执行文件都可以作为Shell命令来执行。将Linux的可执行文件进行分类,如表1-1所示。
表1-1 Linux系统上可执行文件的分类
类别 | 说明 |
Linux命令 | 存放在/bin、/sbin目录下的命令 |
内置命令 | 处于效率考虑,将一些常用命令的解释程序构造在Shell内部 |
实用程序 | 存放在/usr/bin、/usr/sbin、/usrlocal/bin、/usr/local/sbin等目录下的实用程序 |
用户程序 | 用户程序经过编译生成可执行文件后可作为Shell命令执行 |
Shell脚本 | 由Shell语言编写的批处理文件 |
图1-2描述了Shell是如何完成命令解释的。
图 1-2 命令解释过程
当用户提交了一个命令后,Shell首先判断是否为内置命令(由Shell自身负责解释),如果是就通过Shell的解释器将其解释为系统功能调用并转交给内核执行;若是外部命令或实用程序,就试图在硬盘中查找该命令并将其调入内存,再将其解释为系统功能调用并移交给内核执行。在查找该命令时分为两种情况:
(1) 用户给出了命令的路劲,Shell就沿着用户给出的路径进行查找,若找到则调入并转交给内核执行,若没找到则输出提示信息。
(2) 用户没有给出命令的路径,Shell就在环境变量PATH所制定的路径中依次进行查找,若找到则调入内存,若没有找到则输出提示信息。
此外,Shell还具有如下功能。
♦ 通配符、命令补全、别名机制、命令历史。
♦ 重定向、管道、命令替换、Shell编程等。
1.1.3 Shell元字符
在Shell中有一些具有特殊的意义字符,称为Shell元字符(Shell Metacharacters)。若不以特殊方式指明,Shell并不会把它们当做普通文字符使用。
表1-2中简单介绍了常用的Shell元字符的含义。
表1-2 常用的Shell元字符及含义
元字符 | 含义 |
* | 代表任意字符串 |
? | 代表任意字符 |
/ | 代表根目录或作为路径间隔符使用 |
\ | 转义字符。当命令的参数要用到保留字时,要在保留字前面加上转义字符 |
\<Enter> | 续行符。可以使用续行符将一个命令行分写在多行上 |
$ | 变量值置换,如$PATH表示环境变量PATH的值 |
' | 在'……'中间的字符均被当做字符处理,指令、文件名、保留字等都不在具有原来的意义 |
" | 在"……"中间的字符会被当做文字处理并允许变量值置换 |
` | 命令置换,置换`……`中命令的置换结果 |
< | 输入重定向字符 |
> | 输出重定向字符 |
| | 管道字符 |
& | 后台执行字符。在一个命令之后加上字符“&”,该命令就会以后台方式执行 |
; | 分割顺序执行的多个命令 |
( ) | 在字Shell中执行一组命令 |
{ } | 在当前Shell中执行一组命令 |
! | 执行命令历史记录中的命令 |
~ | 代表登录用户的宿主目录(自家目录) |
1.2 命令格式和通配符
1.2.1 命令格式
Shell命令的一般格式为:
cmd [-options] [arguments]
其中,cmd是命令名;options是选项;arguments是参数,即操作对象。
说明:
♦ 最简单的Shell命令只有命令名,复杂的Shell命令可以有多个选项和参数。
♦ 选项和参数都作为Shell命令执行时的输入,它们之间用空格分隔开。
♦ 单字符参数前使用一个减号(-),单词参数前使用两个减号(--)。
♦ 多个单字符参数前可以只使用一个减号。
♦ 操作对象(arguments)可以是文件也可以是目录,有些命令必须使用多个操作对象,如cp命令必须指定源操作对象和目标操作对象。
♦ 并非所用命令的格式都遵循以上规则,如dd、find等。
1.2.2 目录和文件名的命名规则
在Linux下可以使用长文件或目录名,可以给目录和文件取任何名字,但是必须遵循下列规则:
♦ 除了/之外,所有的字符都合法。
♦ 有些字符最好不用,如空格符、制表符、退格符和字符: ? , @ # $ & () \ | ; ‘’ “” <>等。
♦ 避免使用+、-或.来作为普通文件名的第一个字符。
♦ 大小写敏感。
♦ 以“.”开头的文件或目录是隐含的。
1.2.3 通配符
通配符主要用于用户方便描述目录或文件。表1-3中是常用的通配符及其说明。
表1-3 常用的通配符
通配符 | 说明 |
* | 匹配任何字符和任何数目的字符 |
? | 匹配任何单字符 |
[...] | 匹配任何包含在括号里面的字符 |
[!...] | 匹配任何不包含在括号里的单字符 |
*能匹配文件或目录名中的“.”,但不能匹配首字符是“.”的文件或目录名。要匹配隐含文件应该使用“.*”。
表1-4中列举了一些使用通配符的例子。
表1-4 通配符使用举例
举例 | 说明 |
ls *.c | 列出当前目录下的所用C语言源程序 |
ls /home/*/*.c | 列出/home目录下所有子目录中的所有C语言源程序 |
ls n*.conf | 列出当前目录下的所有以字母n开始的conf文件 |
ls test?.dat | 列出当前目录下以test开始的,随后一个字母是任意的.dat文件 |
ls [abc]* | 列出当前目录下首字符是a或b或c的所有文件 |
ls [!abc]* | 列出当前目录下首字符不是a或b或c的所有文件 |
ls [a-zA-Z]* | 列出当前目录下首字符是字母的所有文件 |
1.3 文件及Linux目录结构
在Linux系统上,文件是被看作是字节序列。这种概念使得所有的系统资源都有了统一的标识,这些资源包括普通文件或目录、磁盘设备、控制台(键盘、显示器)、打印机等。对这些资源的访问和处理都是通过字节序列的方式实现的。Linux系统的文件类型包括:
♦ 普通文件( - )。
♦ 目录( d )。
♦ 符号链接( l )。
♦ 字符设备文件( c )。
♦ 块设备文件( b )。
♦ 套接字( s )。
♦ 命名管道( p )。
普通文件就是字节序列,Linux并没有对其内容规定任何的结构。普通文件可以是程序源代码(C、C++、Python、Java等),可执行文件(文件编辑器、数据库系统、出版工具、绘图工具等)、图片、声音、图像等。Linux不会区别对待这些文件,只有处理这些文件的应用程序才会根据文件的内容为它们赋予相应的含义。
在DOS和Windows环境中,所有的文件后缀名都能表示该文件的类型,如*.exe表示可执行文件,*.bat表示批处理文件。在Linux环境下,只要是可执行文件并具有可执行属性则就能执行,不管其文件名后缀是什么。但是对一些数据文件一般也遵循一些文件名后缀规则,表1-5中列出了一些常用的文件后缀。
表1-5 常用的文件后缀举例
举例 | 说明 |
*.txt | 文本文件 |
*.conf | 配置文件 |
*.html/*.xml/*.yml/*.sql | HTML/XML/YAML/SQL文件 |
*.c/*.cpp | C/C++语言源程序文件 |
*.so/*.ko/*.lib | 模块文件、库文件 |
*.sh/*.php/*.py/*.pl/*.rb | Shell/PHP/Python/Perl/Ruby脚本文件 |
*.rpm | RPM包文件 |
*.tar | tar存档文件 |
*.gz/*.bz2/*.xz | 由gzip/bzip2/xz生成的压缩文件 |
*.tar.gz/*.tgz/*.tar.bz2/*.tbz/*.tar.xz/*.txz | 压缩后的tar包文件 |
*.lock | 用于表示某个程序或某种服务正在运行的锁文件 |
*~ | 备份文件 |
目录文件是由一组目录项组成,目录项可以是对其他文件的指向也可以是其下的子目录指向。
实际上,一个文件的名称是存储在其父目录中的,而并非同文件内容本身存储在一起。
将两个文件名(存储在其父目录的目录项中)指向硬盘上一个存储空间,对两个文件中的任何一个的内容进行修改都会影响到另一个文件,这种链接关系称为硬链接。硬链接文件实际上就是在某目录中创建目录项,从而使不止一个目录可以引用到同一个文件。
符号链接又称软链接,是指将一个文件指向另外一个文件的文件名。
软连接和硬链接的特点:
软链接:
1.软链接是存放另一个文件的路径的形式存在。
2.软链接可以 跨文件系统 ,硬链接不可以。
3.软链接可以对一个不存在的文件名进行链接,硬链接必须要有源文件。
4.软链接可以对目录进行链接。
硬链接:
1. 硬链接,以文件副本的形式存在。但不占用实际空间。
2. 不允许给目录创建硬链接。
3. 硬链接只有在同一个文件系统中才能创建。
4. 删除其中一个硬链接文件并不影响其他有相同 inode 号的文件。
不论是硬链接或软链接都不会将原本的档案复制一份,只会占用非常少量的磁碟空间。
硬链接: 与普通文件没什么不同,
inode
都指向同一个文件在硬盘中的区块软链接: 保存了其代表的文件的绝对路径,是另外一种文件,在硬盘上有独立的区块,访问时替换自身路径。
设备是指计算机中的外围硬件设备装置,即除了CPU和内存以外的所有设备。通常,设备中含有数据寄存器或数据缓存器、设备控制器,用于完成设备同CPU或内存的数据交换。
在Linux下,为了屏蔽用户对设备访问的复杂性,采用了设备文件,即可以通过像访问普通文件一样的方式对设备进行读写访问。
设备文件用来访问硬件设备,包括硬盘、光驱、打印机等。每个硬件设备至少与一个设备文件相关联。设备文件分为字符设备(如键盘)和块设备(如磁盘)。Linux下的设备名以文件系统中的设备文件的形式存在。所有的设备文件存放在/dev目录下。表1-6列出了常用设备文件。
表1-6 常用设备文件说明
设备文件 | 说明 |
/dev/sd* | SCSI/SAS、PATA/SATA、USB硬件设备,如sda1表示第1块硬盘的第1个分区;sda2表示第2快硬盘的第2个分区 |
/dev/sr0 | 光驱设备 |
/dev/console | 系统控制台 |
/dev/tty* | 本地终端设备 |
/dev/pts/* | 伪终端设备 |
/dev/ppp* | ppp设备。ppp(Point-to-Point)协议设备,用于传统的拨号上网。 |
/dev/lp* | 表示并口设备,如lp0表示第1个并口设备;lp1表示第2个并口设备 |
/dev/null | 空设备。可将其视为“黑洞”,所有写入它的内容都会丢失,通常用于屏蔽命令行输出 |
/dev/zero | 零设备。可以产生连续不断的二进制的零流,通常用于创建指定长度的空文件 |
在/dev目录下有许多链接文件,使用这些链接能够方便地使用系统中的设备。例如,可以通过/dev/cdrom而不是/dev/sr0来访问光驱。
套接字和命名管道是Linux环境下实现进程间通信(IPC)对的机制。
命名管道(FIFO)文件允许运行在同一台计算机上的两个进程之间的互相通信。套接字(socket)允许运行在不同计算机上的进程之间相互通信。
套接字和命名管道通常是在进程运行时创建或删除的,一般无需系统管理员干预。
Linux的目录结构遵循从文件系统层次结构标准(File system Hierarchy Standard,FHS)。表1-7中解释了由FHS所规定的存放特定类型的文件位置。
目录名 | 内容说明 |
bin | 存放二进制的可执行文件 |
boot | 存放用于系统引导时使用的各种文件 |
dev | 用于存放设备文件,用户可以通过这些文件访问外部设备 |
etc | 存放系统的配置文件 |
home | 存放所有用户文件的根目录,有一个用户在该目录下就有一个与该用户名相对应的子目录,当用户登录时就进入其用户名对应的字母目录 |
lib/lib64 | 存放跟文件系统中的程序运行所需要的共享库及内核模块 |
lost+found | 存放一些系统检查结果,发现不合法的文件或数据都存放在这里,通常次目录是空的,除非硬盘遭受了不明的损毁 |
mnt | 临时文件系统的挂载点 |
media | 即插即用型存储设备的加载点自动在这个目录下创建,如CD/DVD等 |
opt | 第三方软件的安装目录 |
proc | 是一个虚拟文件系统,存放当前内存的映射,主要用于在不重启机器的情况下管理内核 |
root | 超级用户目录 |
sbin | 类似/bin目录,也存放二进制可执行文件,但是只有root才能访问 |
srv | 系统对外提供服务的目录,如Web虚拟主机等 |
tmp | 用于放置各种临时文件 |
usr | 用于存放系统应用程序 |
var | 用于存放需要随时改变的文件,如系统日志、脱机工作目录等 |
提示:
(1).在Linux环境下,文件是归类存放的。
(2).在不知道自己究竟在做什么的情况下,不要轻易操作操作目录,如/proc、/boot、/etc、/usr、/var等。
(3).用户可以使用“$ man hier”命令获得Linux文件层次结构的说明。