目录
一、shell简介
二、常见的shell版本
三、shell的功能
1、交互式处理命令
2、命令自动补齐
3、历史记录
4、作业控制
5、输入输出重定向
6、别名
7、管道
8、脚本编程
9、文件名替换(globbing)
10、元字符(通配符)
11、进程
四、shell的配置文件和环境变量
1、初始化文件
2、用内置的set和shopt命令设置bash选项
3、提示符
4、搜索路径
5、hash命令
6、source或dot命令
一、shell简介
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。
实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。
二、常见的shell版本
同Linux本身一样,Shell也有多种不同的版本。目前主要有下列版本的Shell:
"Bourne Shell:是贝尔实验室开发的。
"BASH:是GNU的Bourne Again Shell,是GNU操作系统上默认的shell。
"Korn Shell:是对Bourne SHell的发展,在大部分内容上与Bourne Shell兼容。
"C Shell:是SUN公司Shell的BSD版本。
Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。
实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。
二、常见的shell版本
同Linux本身一样,Shell也有多种不同的版本。目前主要有下列版本的Shell:
"Bourne Shell:是贝尔实验室开发的。
"BASH:是GNU的Bourne Again Shell,是GNU操作系统上默认的shell。
"Korn Shell:是对Bourne SHell的发展,在大部分内容上与Bourne Shell兼容。
"C Shell:是SUN公司Shell的BSD版本。
三、shell的功能
shell是用户与内核交互的命令行界面,为了方便用户,shell提供如下功能:
1、交互式处理命令
在命令提示符后输入一条命令后,shell会读入这个命令行并对命令行进行解析,将其分解为词,称作token。token之间用空格或制表符分隔,命令行以换行符结尾。接下来,shell检查第一个词是否为内置命令或磁盘上的可执行程序。如果是内置命令,shell就在自己内部执行它。否则,shell将在路径变量所指的目录中查找这个程序。如果找到了命令的程序,shell就创建一个进程来执行它。之后,shell进入睡眠(或等待)状态直至程序执行完毕。shell会根据需要报告程序的退出状态。此时,屏幕上又会出现命令提示符,整个过程从头开始。命令行的处理顺序如下:
(1) 执行历史命令替代(视情况而定)
(2) 命令行被分解为token(或称“词”)
(3) 更新历史命令(视情况而定)
(4) 引用的处理
(5) 别名替代和函数的定义(视情况而定)
(6) 设置重定向,后台进程和管道
(7) 执行变量替换(如$name,$user等)
(8) 执行命令替换(如`date`代替Today)
(9) 执行称为globbing的文件名替换(如cat abc.??,rm *.c等)
(10) 执行命令
命令被执行时,可以是别名、函数、内置命令或磁盘上的一个可执行程序。别名是原有命令的缩写(昵称),可用于C、TC、bash和Korn shell。函数可用于 Bourne shell(在AT&T System V的第2版中引入)、bash和Korn shell。函数是由像独立的例程一样的指令组织起来的一组命令。别名和函数都在shell的内存空间中定义。内置命令是shell的内部程序,而可执行程序则在磁盘上。shell用路径变量在磁盘上定位可执行程序。执行命令前,shell需要创建一个子进程。程序定位和子进程创建都要花一定的时间。
执行命令前,shell按如下顺序判定命令类型:
(1) 别名
(2) 关键字
(3) 函数
(4) 内置命令
(5) 可执行程序
2、命令自动补齐
不需要输入完整的命令,按Tab键可以自动补齐命令,或者快按ESC两次。
3、历史记录
bash能自动把你输入的命令保存在历史列表缓冲区,缓冲区的大小由HISTSIZE变量控制。这个历史列表保存在你登录的用户home下的.bash_history文件中,你可以通过history和fc命令执行、编辑历史命令。
通过按向上方向键,可以向后遍历近来在该控制台下输入的命令。用向下方向键可以向前遍历。与SHIFT 键连用的话,可以遍历以往在该控制台中的输出。
按Ctrl+r后,bash就进入"reverse-i(ncremental)-search"(向后增量搜索)模式。此时bash将根据你输入的关键字搜索匹配的历史命令。输入关键字后,如果显示的不是你想要的命令,还可以继续按Ctrl+r查找与此匹配的上一条命令。如果你按了向右、向左方向键或,上面的命令将回到普通的命令行,这样就可以进行适当编辑。
4、作业控制
作业控制是bash shell的一项强大功能,可以选择在后台或前台运行作业。一个正在运行的程序称为进程或作业,每个进程有一个进程标识号,即PID。通常,在命令行输入的命令都在前台运行,并且持续运行于前台直至结束,除非按下Ctrl+C或Ctrl+\组合键来发送信号终止它。通过作业控制,可以将一个作业置于后台运行,可以通过Ctrl+D组合键暂停一个作业,这样作业将被发送到后台并挂起,可以使一个暂停的作业在后台运行,可以将一个后台作业送回前台,甚至还可以终止已经在后台或前台运行的作业。下表列出了作业命令的清单。
表1 作业命令清单
命 令 |
含 义 |
bg |
启动被终止的后台作业 |
fg |
将后台作业调到前台 |
jobs |
列出所有正在运行的作业 |
kill |
向指定作业发送kill信号 |
stop |
挂起一个后台作业 |
stty tostop |
当一个后台作业向终端发送输出时就挂起它 |
wait [n] |
等待一个指定的作业并返回它的退出状态,这里n是一个PID或作业号 |
^Z(Ctrl-Z) |
终止(挂起)作业。屏幕上将出现提示符 |
jobs命令的参数 |
含 义 |
%n |
作业号n |
%string |
以string开头的作业名 |
%?string |
作业名包含string |
%% |
当前作业 |
%+ |
当前作业 |
%- |
当前作业前的一个作业 |
-r |
列出所有运行的作业 |
-s |
列出所有挂起的作业 |
5、输入输出重定向
shell启动时继承了3个文件:stdin、stdout和stderr。标准输入通常来自键盘。标准输出和标准错误输出通常被发往屏幕。有些时候,需要从文件读取输入,或者将输出结果和报错信息写入文件。这些都可以通过I/O重定向来实现。下表列出了各种重定向操作符。
表2 重定向操作符
重定向操作符 |
功 能 |
< 文件名 |
重定向输入 |
> 文件名 |
重定向输出 |
>>文件名 |
追加输出 |
2>文件名 |
重定向标准错误输出 |
2>>文件名 |
重定向和追加标准错误输出 |
&>文件名 |
重定向标准输出和标准错误输出 |
>&文件名 |
重定向标准输出和标准错误输出(首选方式) |
2>&1 |
将标准错误输出重定向到输出的去处 |
1>&2 |
将输出重定向到标准错误输出的去处 |
>| |
重定向输出时忽略noclobber |
< >文件名 |
如果是一个设备文件(/dev),使用文件作为标准输入和标准输出 |
exec命令能够在不启动新进程的前提下,将当前正在运行的程序替换为一个新的程序。使用exec命令,不需创建子shell就能改变标准输入和输出。用exec打开文件后,read命令每次都会将文件指针移到文件的下一行,直到文件末尾。如果要再次从头开始读文件,就必须先关闭文件再打开。但是,如果使用cat和sort这类UNIX工具,操作系统会在命令结束后自动关闭文件。
表3 exec命令列表
Exec 命 令 |
功 能 |
exec ls |
ls将顶替shell运行。ls运行结束后,它启动时所在的shell不会返回运行状态 |
exec |
打开文件filea,用于读标准输入 |
exec >filex |
打开文件filex,用于写标准输出 |
exec 3 |
打开文件datfile,将其作为文件描述符3,用于读取输入 |
sort <&3 |
将文件datfile排序 |
exec 4>newfile |
打开文件newfile,将其作为文件描述符4,用于写输出 |
ls >&4 |
将ls的输出结果重定向到newfile |
exec 5<&4 |
将文件描述符5变成文件描述符4的一个副本 |
exec 3<&- |
关闭文件描述符3 |
6、别名
别名是bash shell中用户自定义的命令简写形式。当某条命令要带多个选项和参数,或者命令语法很难记住时,别名就变得很有用。在命令行设置的别名不会被子shell继承。别名的设置通常在文件.bashrc中进行。每个新shell启动时都要执行.bashrc文件,所以,该文件中设置的所有别名都会为新shell复位。别名可以传递给shell脚本,但是这样会导致潜在的移植问题,除非所用的别名是直接定义在脚本中的。
内置命令alias能够列出所有已设置的别名。
alias命令也可用来创建别名。
unalias命令用来删除别名。若要暂时关闭一个别名,可以在别名的名字前加上一个反斜杠。
7、管道
管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中未使用输出重定向)。通过使用管道符“|”来建立一个管道行。
8、脚本编程
当命令不在命令行上执行,而是通过一个文件执行时,该文件就称为shell脚本,脚本以非交互的方式运行。当bash shell以非交互方式运行时,它先查找环境变量BASH_ENV(或ENV),该变量指定了一个环境文件(通常是.bashrc),然后从该文件开始执行。当读取了BASH_ENV文件后,shell就开始执行脚本中的命令。
9、文件名替换(globbing)
计算命令行时,shell会用元字符来缩写能够匹配某个特定字符组的文件名或路径名。将元字符展开为文件名的过程又被称作文件名替换或globbing。如果没有文件名能够跟所用的元字符匹配,shell就会把这个元字符作为一个字面字符。
别名是bash shell中用户自定义的命令简写形式。当某条命令要带多个选项和参数,或者命令语法很难记住时,别名就变得很有用。在命令行设置的别名不会被子shell继承。别名的设置通常在文件.bashrc中进行。每个新shell启动时都要执行.bashrc文件,所以,该文件中设置的所有别名都会为新shell复位。别名可以传递给shell脚本,但是这样会导致潜在的移植问题,除非所用的别名是直接定义在脚本中的。
内置命令alias能够列出所有已设置的别名。
alias命令也可用来创建别名。
unalias命令用来删除别名。若要暂时关闭一个别名,可以在别名的名字前加上一个反斜杠。
7、管道
管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中未使用输出重定向)。通过使用管道符“|”来建立一个管道行。
8、脚本编程
当命令不在命令行上执行,而是通过一个文件执行时,该文件就称为shell脚本,脚本以非交互的方式运行。当bash shell以非交互方式运行时,它先查找环境变量BASH_ENV(或ENV),该变量指定了一个环境文件(通常是.bashrc),然后从该文件开始执行。当读取了BASH_ENV文件后,shell就开始执行脚本中的命令。
9、文件名替换(globbing)
计算命令行时,shell会用元字符来缩写能够匹配某个特定字符组的文件名或路径名。将元字符展开为文件名的过程又被称作文件名替换或globbing。如果没有文件名能够跟所用的元字符匹配,shell就会把这个元字符作为一个字面字符。
表4 shell元字符与文件名替换
元 字 符 |
含 义 |
* |
匹配零个或多个字符 |
? |
匹配一个字符 |
[abc] |
匹配a、b、c这组字符中的一个 |
[!abc] |
匹配a、b、c这组字符以外的某个字符 |
{a,ile,ax} |
匹配一个或一组字符 |
[a–z] |
匹配在a至z这个范围内的某个字符 |
[!a~z] |
匹配不在a至z这个范围内的某个字符 |
\ |
转义或禁用后面那个元字符 |
10、元字符(通配符)
元字符是一种可以用来代表自身以外的内容的特殊字符。shell的元字符也被称作“通配符”。下表列出了shell的元字符及其功能。
元字符是一种可以用来代表自身以外的内容的特殊字符。shell的元字符也被称作“通配符”。下表列出了shell的元字符及其功能。
表5 shell的元字符及其功能
元 字 符 |
含 义 |
\ |
按字面含义解释它后面那个字符 |
& |
在后台处理的进程 |
; |
分隔命令 |
$ |
替换变量 |
? |
匹配单个字符 |
[abc] |
匹配这组字符中的一个。例如,a、b或者c |
[!abc] |
匹配这组字符以外的某个字符。例如,除a、b或者c以外的字符 |
* |
匹配零个或多个字符 |
(cmds) |
在子shell中执行命令 |
{cmds} |
在当前shell中执行命令 |
11、进程
进程是正在运行的程序,可以用它唯一的PID(进程标识,process identification)号来标识。内核负责控制和管理进程。进程由可执行程序、进程的数据和堆栈、程序指针和堆栈指针、寄存器以及程序运行时需要的所有信息组成。
用户登录后,shell这个特殊的程序将自行加载。shell启动后,就生成了一个进程,并且属于某个进程组。进程组用组PID进行标识。任何时候只能有一个进程组拥有终端的控制权,即所谓的在前台运行。当用户登录系统后,shell便控制了终端,等待用户在命令提示符后输入命令。
四、shell的配置文件和环境变量
一个进程的环境包括:变量、打开的文件、当前的工作目录、函数、资源限额、信号等。它定义了可以从一个进程继承到下一个进程的特性,以及对当前工作环境的配置。用户shell的配置定义在shell初始化文件中。
进程是正在运行的程序,可以用它唯一的PID(进程标识,process identification)号来标识。内核负责控制和管理进程。进程由可执行程序、进程的数据和堆栈、程序指针和堆栈指针、寄存器以及程序运行时需要的所有信息组成。
用户登录后,shell这个特殊的程序将自行加载。shell启动后,就生成了一个进程,并且属于某个进程组。进程组用组PID进行标识。任何时候只能有一个进程组拥有终端的控制权,即所谓的在前台运行。当用户登录系统后,shell便控制了终端,等待用户在命令提示符后输入命令。
四、shell的配置文件和环境变量
一个进程的环境包括:变量、打开的文件、当前的工作目录、函数、资源限额、信号等。它定义了可以从一个进程继承到下一个进程的特性,以及对当前工作环境的配置。用户shell的配置定义在shell初始化文件中。
1、初始化文件
登录时,如果在用户的主目录下存在.bash_profile文件,就对其执行source命令。它先设置用户的别名和函数,再设置用户特定的环境变量以及启动脚本。
如果用户没有.bash_profile文件,但有一个名为.bash_login的文件,那么将对这个文件执行source命令,如果也没有.bash_login文件,而有一个.profile文件,就对这个.profile文件执行source命令。
/etc/profile文件 /etc/profile文件是一个系统级的初始化文件,由系统管理员进行设置,在用户登录时执行指定的任务。这个文件在bash shell启动时被执行。
~/.bash_profile文件 如果在用户的主目录下找到~/.bash_profile文件,那它将在/etc/profile文件后被执行source命令。如果~/.bash_profile文件不存在,bash将寻找另外一个用户定义的文件~/.bash_login,然后对它执行source命令,如果~/.bash_login也不存在,bash将对~/.profile(如果它存在)文件执行source命令。只能对这三个文件(~/.bash_profile、~/.bash_login或~/.profile)中的一个执行source命令。bash还将检查用户是否有一个.bashrc文件并对它执行source命令。
BASH_ENV(ENV)变量 从BASH 2.0版开始,BASH_ENV文件简称为ENV文件(和Korn shell一样)。BASH_ENV(ENV)变量在~/.bash_profile文件中设置。将每次交互式bash shell或bash脚本启动时要执行的文件名赋值给该变量。BASH_ENV(ENV)文件包含特定的bash变量和别名。通常命名为.bashrc,也可以是其他名称。当特权选项打开(bash –p或设置-o特权)或使用--norc命令行选项(bash –norc或bash --norc)时,将不处理BASH_ENV(ENV)文件。
.bashrc文件 BASH_ENV(ENV)变量被赋值(按惯例)为名称.bashrc。每次当一个新的或交互式bash shell或bash脚本启动时自动对这个文件执行source命令。它包含那些只属于bash shell的设置。
2、用内置的set和shopt命令设置bash选项
set –o选项 当使用开关-o时,set命令可以设置选项。选项可以用来定制shell环境。它们不是打开就是关闭,通常在BASH_ENV(ENV)文件中设置。
内置shopt(2.x以上版) 在更新版本的bash中,shopt(shell选项)内置命令是set命令的一种替代。shopt在许多方面和set内置命令一样,但它为配置shell增加了更多的选项。
3、提示符
交互式使用时,shell会提示用户进行输入。看到提示符,就可以开始输入命令了。bash shell提供4种提示符:主提示符是美元符号($),次提示符则是一个向右的尖括号(>)。保存第3和第4提示符的变量分别是PS3和PS4,将在以后讨论。交互运行时,shell会显示这两个提示符。注意,我们可以改变提示符的默认值。变量PS1中保存的是主提示符。登录并等待用户输入(通常是一个UNIX/Linux命令)时,它的值——美元符号将出现。变量PS2则保存次提示符,其初值是向右的尖括号(>)。如果用户在将命令输完整之前按了回车键,屏幕上就会显示次提示符。改变主提示符和次提示符的命令将在后面给出。
主提示符 默认的主提示符是美元符(或bash $)。您可以改变自己的主提示符。提示符通常在/etc/bashrc文件或用户的初始化文件.bash_profile或.profile(Bourne shell)中定义。
4、搜索路径
变量PATH被bash用于定位用户在命令行键入的命令。路径是一个用冒号分隔的目录列表,shell用这个路径来查找命令。默认路径是由系统决定的,并且由安装bash的管理员设定。搜索从左向右依次进行。路径末尾的点代表当前工作路径。如果在路径列出的所有目录中都未找到目标命令,shell就会向标准错误输出发送这样一条消息:filename: not found(文件名:未找到)。如果运行的是bash shell,那么路径通常是在.bash_profile文件中设置。如果运行的是sh(Bourne shell)则在.profile文件中设置。
如果路径中未包含句点,执行当前工作目录下的命令或脚本时,必须在脚本的名字前面加上./,例如./program_name,这样脚本才能找到该程序。
5、hash命令
hash命令控制系统内部的一个哈希表,shell用这个表来提高命令查找的效率。有了这个内部哈希表,shell就不必每输入一条命令都去搜索路径。第一次输入某条命令时,shell通过搜索路径找到这条命令,然后将它保存在shell的内存空间的一个表中。再次使用同一命令时,shell通过哈希表来查找它。这样访问命令比必须搜索整个路径要快得多。如果事先知道自己要经常使用某条命令,就可以将它加到哈希表中。也可以从这个表中删除命令。哈希命令的输出结果显示了shell通过该表找到某条命令的次数(hits)以及命令的完整路径名。带-r选项的hash命令将清空这个哈希表。参数--禁止选项检查其余的参数。bash可以自动实现哈希表。我们也可以关闭它,但如果没有特殊的理由的话,建议不要这么做。
6、source或dot命令
source命令(来自C shell)是内置的bash命令。dot命令,简单地说就是一个句点,(来自Bourne shell)是source的另一个名字。两个命令都是以一个脚本名作为参数。shell将在当前shell的环境中执行这个脚本,也就是说,不会为它启动一个子进程。这个脚本中设置的所有参数都将成为当前shell环境的一部分。source(或dot)命令通常被用来重新执行经过修改的初始化文件.bash_profile、.profile等。例如,如果在登录之后修改了.bash_profile中某项设置,比如变量EDITOR或TERM,用source命令重新执行.bash_profile就可以让修改生效。而不必先注销再重新登录进来。像.bash_profile文件或其他类似的shell脚本不需要执行权限就可以用source和dot命令来执行。