Linux中的Shell简介

Shell从字面上翻译是外壳,它是一个壳层,而这个壳层介于用户与操作系统(Kernel)间,负责将用户的命令解释为操作系统可以接受的低级语言,以及将操作系统相应的信息以用户可以了解的方式来显示,如缺少它,则用户与操作系统将完全被阻隔而无法沟通。

一、Shell基本概念

每个人在成功登陆Linux后,系统会出现不同的提示符号,例如#$或是~等,然后开始输入需要的命令,若是命令正确,系统就会依据命令的要求来执行,直到注销系统为止。在登陆到注销期间,输入的每个命令都会经过解释及执行,而这个负责的机制是shell

用户的命令分为两大类:程序和Shell内置的命令。

判断命令属于Shell的内置命令还是属于程序,可以利用find命令来判断,如果find命令没有任何响应,则表示该命令为Shell内置的命令,若是显示搜索的结果,则该命令为程序。

[root@localhost root]# find /-name grep –print

/bin/grep ----- 找到grep表示它为程序

[root@localhost root]# find /-name fg –print

---找不到fg表示它为Shell内置的命令

也可以使用type命令来查看某命令是内置命令还是程序。

注意:不仅Linux系统中有Shell的概念,在其他的操作系统上也有,如DOS中的command.com,以及Microsoft Windows中的GUIGraphical User Interface)。

Shell的种类很多,都集中在/etc/shells文件中,可使用cat命令来查看支持的Shell

[root@localhost root]# cat /etc/shells

虽然每种Unix/Linux系统可以兼容的Shell有很多,常用有3种:Bourne ShellC Shell以及KornShell。每种Shell命令名称和登录时出现的提示符号都不同,如下表:

Shell名称

开发者

命令名称

登录符号

Bourne

S.R.Bourne

/bin/sh

$

C

Bill Joy

/bin/csh

%

Kron

David G. Korn

Ksh

$

1Bourne shell

最初的UNIX shell是由Stephen R. Bourne20世纪70年代中期在新泽西的AT&T贝尔实验室编写的,就是Bourne shellBourne shell 是一个交换式的命令解释器和命令编程语言。

2C shell

Bill Joy20世纪80年代早期,在Berkeley的加利福尼亚大学开发了C shell。它主要是为了让用户更容易的使用交互式功能,并把ALGOL风格的语法结构变成了C语言风格。它新增了命令历史、别名、文件名替换、作业控制等功能。

3Korn shell

有很长一段时间,只有两类shell供人们选择,Bourne shell用来编程,C shell用来交互。为了改变这种状况,AT&Tbell实验室David Korn开发了Korn shellksh结合了所有的C shell的交互式特性,并融入了Bourne shell的语法。因此,Korn shell广受用户的欢迎。它还新增了数学计算,进程协作(coprocess)、行内编辑(inline editing)等功能。Korn Shell 是一个交互式的命令解释器和命令编程语言.它符合POSIX--一个操作系统的国际标准.POSIX不是一个操作系统,而是一个目标在于应用程序的移植性的标准--在源程序一级跨越多种平台。

4)变更Shell

因为Linux上可以支持的Shell很多,所有可以依照个人的习惯来使用不同的shell。要查看目前所使用的Shell或是系统默认的Shell,最简单的方式就是使用echo命令来查询系统的“SHELL”环境变量,用法如下:

[root@localhost root]# echo $SHELL

/bin/bash

或是

[root@localhost root]# echo $ {SHELL}

/bin/bash

注意:以上的方法只能显示用户登录时使用的Shell,而无法显示出更换过的Shell

若要变更使用的Shell,只要执行该Shell程序名称,即可切换到不同的Shell,以下是各式Shell变更的方法:

[root@localhost root]# /bin/bash

[root@localhost root]# /bin/sh

Sh—2.05b#/bin/ash

#/bin/bsh

#/bin/tcsh

[root@localhost ~]#/bin/csh

[root@localhost ~]#/bin/bash2

注意:在一般情况下,如果要执行“exit”命令会立即注销系统。但由默认的Shell切换到其他的Shell后,无论切换多少次数,在切换后再执行“exit”都不会注销系统。只会跳离目前的Shell,并回到上一层Shell

切换Shell的方法很简单,但它只是临时性的变更,待用户注销再度登陆后,又会回到系统默认的Shellbash)。变更默认的shell,可以使用chsh命令(change Shell,其使用方法很简单,以下是将用户默认的shell变更为tcsh的范例:

[root@localhost root]# /usr/bin/chsh

Changing shell for root.

New shell [/bin/bash]: /bin/tcsh

Shell changed.

或是

[root@localhost root]# /usr/bin/chsh –s /bin/tcsh root

Changing shell for root.

Shell changed.

二、Shell功能概念

RHEL 6.4默认的Shellbash(BourneAgain SHell),它除了担任用户与Kernel间沟通的管道之外,具备以下特性:

交互式处理(IntercativeProcessing

命令补全功能

查阅历史记录命令 ---history

别名(Alias)功能

后台处理(BackgroundProcessing

输入/输出重新导向(Input/Output Redirection

管道(Pipes

1.交互式处理(Intercative Processing

自从用户登陆系统开始,Shell就会出现提示符号(视Shell与用户身份的不同会有不同的符号,)并且等待用户命令的输入。在接收来自用户输入的命令后,依命令的不同来执行,在执行完毕后,Shell会将结果回传给用户,并且再次显示提示符号,以等待用户下一次的输入。一直持续到执行exitCtrl+D来注销Shell才会结束,这种沟通方式称为交互式处理。

2.命令补全功能

是指用户输入命令时,并不需要输入完整的命令,而系统会自动找出最符合的名称,这种功能可以节省经常输入长串命令的时间。

例如:

/root目录下有个名为ImportantCommand.txt的文件,如果要查看其内容,并不需要输入完整的文件名,只要输入开头的几个字母,例如cat /root/Im,然后按Tab键一次,或是快速按Esc键两次,系统则会自动补足完全的命令。

若有多个文件都与所输入的前缀相同,则当按第一次Tab键时,系统并不会出现任何信息,若是再按一次Tab键,系统则会显示所有符合输入前缀的文件名称。

[root@localhostroot]# cat p----连按2次Tab键盘

passwd.txtpassword.txt puzzle.txt

若忘记命令的全名,例如用来制作引导盘的mkbootdisk,而只记得命令的开头字母,例如只记得以mk开头,则可以仅输入mk,然后连按两次Tab键,系统也会列出所有符合条件的命令名称,

[root@localhostroot]# mk-----连按二次Tab键

3.查阅历史记录命令 --- history

1> 每当在Linux系统上输入命令并按下Enter键后,这个命令就会存放在命令记录表(Command history)中,根据bash的默认值,这个记录表就是~/.bash_history文件。这个文件的保存记录定义在“HISTSIZE ”环境变量中,默认的记录为1000笔,可以直接打开~/.bash_history文件,或是输入“history | less”命令来查看目前的命令记录。

[root@localhostroot]# history| less

1 ls/root

2mkdir anhui

3 cd

…… --------一共记录着1000个记录

2> 可以使用“historyn”命令,要查阅最近的命令记录,如最近3笔记录的范例:

[root@localhostroot]# history5

506 history 5 -----“506”为记录号码

505 ls –al

504 manmkbootdisk

……

3> 还有一种执行命令最快的方式就是使用命令记录号码,在命令记录中,每个命令都会赋予一个记录号码,可以利用这个号码来指定欲执行的旧命令,使用这个方法的语法为“!nnn,例如:

[root@localhostroot]# !561 ---中间没有空格

注意:除此之外,“!!”表示重复上一个命令(与按向上方键再按Enter键一样),如果输入“!ls”则会执行最后一次以ls开头的命令,以次类推……

4.别名(Alias)功能

是指提供用户自行定义为简单的字符串,以替换复杂的命令选项,或是多个命令的连续组合,这可为用户量身定做自己习惯的操作命令。

举例,在DOS系统中通过“dir”命令来显示目录中的内容,而在Linux中必须输入“ls -l若是希望以dir来替换量身ls–l,则可以使用别名的功能,范例如下:

[root@localhost root]# alias dir=’ls –l’ ---- “=”前后都不允许有空格

[root@localhostroot]# dir /home/jack

若想知道目前系统中所有的别名命令有哪些,可以直接使用alias命令,而不需任何的参数:

[root@localhostroot]# alias

Alias cp=’cp -i’

Alias dir=’ls -l’

Alias mv=’mv -i’

Alias rm=’rm -i’

…….

注意: mv=’mv-i’,它的意思是指,当执行rm这个命令时,其实系统实际执行的命令是rm –i,也就是交互式模式进行。这是处于安全考虑,可以在系统真正删除文件前,需经过再次确认,这可以避免系统直接删除文件可能产生的错误。

若想取消刚才定义的别名,使用unalias命令来取消此别名。

[root@localhostroot]# unalias

5.后台处理(Background Processing

Linux是多用户多任务的操作系统,它可以允许多用户或是多个程序同时在系统上执行,但因为Shell使用交互式的模式,所有目前执行的命令会一直掌握着控制权,一直到程序结束为止,此程序为前台程序(Foreground)。但执行前台工作的模式,无法使个别的用户使用Linux支持的多任务功能(同时间执行多个命令或程序)来增加效率。鉴于此,利用后台处理的方式来解决上述问题。

一般将比较耗时的工作放在后台进行,如下载或编译内核等,在处理后台程序期间,用户仍然可以和Shell继续沟通,以下达其他的命令。

1执行后台程序很简单,只要在输入命令时,在命令的后面加上&”(念成Ampersand),然后再按Enter命令,系统即会开始以后台的方式执行该命令,但画面并不会显示任何信息,而且Shell又会回到提示符号,以等待用户下一个命令的输入。

注意:若是目前已在执行某个命令,就无法使用“&”来将它加入后台执行,此时需先按Ctrl+z”键来暂停这个程序的运行,然后再直接输入“bg”命令,便可将此工作放入后台执行

2)若要查看目前系统上正在执行的后台程序,可以输入“jobs”命令。

[root@localhost root]# jobs

[1]- Running find / -name lyrics.txt –print &

[2]+ Running find / -name cometrue.txt –print &

6.管道(Pipes

管道的功能可以将数个简单的命令集合在一起,来执行一个较复杂的工作,除了第一个和最后一个命令之外,每个命令的输入都是前一个命令的输出,而每个命令的输出也将成为下个命令的输入。例如:

[root@localhostroot]# ls –l/usr/bin | grep lib | less

常用的特殊字符及控制组合键

Shell中,可以使用许多字符来指定特殊的范围或功能,以下是在Shell上可能会使用的字符。

万用字符“*(任一字符)

*”是最常用的替代字符,它可以表示空字符串、单一字符或是多字符的字符串。例如:“ls –l /etc/m*

万用字符“? (任一字符)

?”字符只能代表单一字符(不包含空字符),例如以下的范例会显示出目前目录下以“file”开头,并且另外加上任一字符的文件名称(包括目录名称)[root@localhost root]# ls –al ./file?

替换命令字符“

利用两个符号包含的内容在shell中代表命令,也就是说包含的内容并不会以一般字符串来处理,例如:“echo‘date’”会显示出目前的日期和时间,而不是印出“date”这个字符串。

分隔多个命令“;

如果要执行一连串的命令,可以一次输入多个命令,而在命令间以“;”来区隔,以上的范例表示先执行“ls -al”命令,然后接着执行“cat ./file”。

[root@localhostroot]# ls –alcat ./file

命令修改“^

Shell中,“^”符号表示修改的功能,有时输入一连串的命令后,发现其中出现一个小错误,此时就可以使用“^”来修改命令。

例如原本要执行cat ./file1 file2 file3 file4 file5,可以错误输入为cat ./file01 file2 file3 file4 file5,此时便可以以下的范例来修改:

[root@localhostroot]# ^01^1^

注释“#

通常在设Shell脚本或是设置文件中,“#”符号是用来注释,因此该行也就不会被执行,起到方便管理的作用。

[root@localhostroot]# cat/etc/services

# /etc/services

# $Id: services, v 1.22 2001/07/1520:59:24 notting Exp $

# Network services, Internet style

指定字符范围“[ ]

使用“[]”是个很弹性的范围指定方式,若需要指定某些特定的字符或数字,可以直接将该字符或字符写入“[]”中,或是利用“-”符号来表示特定的范围,例如[abcdef][a-f]表示相同的范围、[012345][1-5]都表示056个数字,范例如下:

[root@localhostroot]# ls –alfile[1-2].txt

[root@localhostroot]# ls –alfile[12].txt

排除指定字符范围“[! ]

[! ]”的用法正好与“[]”相反,若是在中括号中加入“!”,则表示排除指定的范围,例如,[abcdef][a-f]表示排除056个数字,范例如下:

[root@localhostroot]# ls–al file[1-2].txt

下表是常用的组合键,可以使用它们来控制Shell的活动。

组合键

说明

Ctrl+C

中止目前的命令

Ctrl+\

中止目前的命令

Ctrl+D

输入结束

Ctrl+Z

暂停目前的命令

Ctrl+M

与按Enter键功能相同

Ctrl+S

暂停屏幕输出

Ctrl+Q

恢复屏幕输出

Ctrl+U

将命令行整行删除

Ctrl+?

删除最后一个字符(与DEL键功能相似)

三、Shell环境变量介绍与设置

所谓环境变量(Environment Variables)是Shell中用来存储系统信息的变量,这些变量可供在Shell中执行的程序使用,不同的shell会有不同的环境变量名称以及环境变量值的设置方法。

1要显示环境变量名称及环境变量值,可以使用“set”命令(这是bash使用的命令,若shelltcsh,需使用“setnv”命令),以下为默认的环境变量及重要项目的说明:

[root@localhostroot]# set

BASH=/bin/bash -----目前使用的shell类型

BASH_ENV=/root/.bashrc

BASH_VERSINFO=([0]=’2’ [1]=”05” [2]=”8”[3]=”1” [4]=”release”[5]=”i386-redhat-linux-gnu”)

BASH_VERSION=$’2.05.8(1)-release’ ----目前使用的shell版本编号

COLORS=/etc/DIR/COLORS

COLUMNS=80

DIRSTACK=()

EUID=0

GROUPS=()

HISTFILE=/root/ .bash_history --- 记录文件位置

HISTFILESIZE=1000 ----- 记录文件最大的记录行数上限

HOSTSIZE=1000 ----记录文件的容量上限

HOME=/root --- 默认的用户登录根目录

HOSTNAME=linux1.happy.com ---服务器网域名称

HOSTTYPE=I386 -----服务器名称

IFS=$’ \t\n’ ----默认的分隔符

2若要查看目前的变量值如何,可以使用“echo”命令,并在变量名称前面加上一个“$”符号即可,范例如下:

[root@localhost root]# echo $PS1

[\U@\H \w]\s

[root@localhost root]# echo $HOME

/root

3若是要修改其中的变量值,只要直接输入“变量名称=变量值”的格式既可。例如要将屏幕显示的行数由24行变更为50行,并且确认变更是否成功,范例如下:

[root@localhost root]# LINE=50

[root@localhost root]# echo $LINES

50

4Linux一个很好的设计是允许自行定义环境变量,但是在定义时必须遵守以下的规则:

变量的名称只能由字母和数字组成,而不可以数字开头,若名称太长,则可以用“_”搁开。

虽然系统预定的变量均为大写,但自定义定量可以使用大小写。

定义变量时需以“变量名称=变量值”的格式来设置,同时在等号(=)两端不可与空格连接。

如果变量中包含特殊符号,例如%或空格,则需在符号前加入“\

注意:若取消已定义好的变量,需使用“unset”,例如“unset CUSTOM1”

5有关“PS1变量的说明,所谓PS1是指用户进入Shell时的提示符号。目前的默认值是:

PS1=$’[\\U@\\H \\W]\\$ ’

而显示出来的提示符为[root@localhost root]#

在设置值中,若要出现特殊符号(包含空格符),例如@,则必须在此符号前加入“\,除此之外,还可以使用下表的符号预先定义的设置方式。

符号

说明

\h

显示主机名

\w

显示目前所在的目录

\$

若是root用户,则会出现“#”提示符号,如果是一般用户则出现$

\t

显示目前的时间,格式为时:分:秒

\d

显示今天的日期,格式为星期:月:日

\s

显示Shell名称

\u

显示目前的用户名称

\#

显示命令的序号

\!

显示命令的历史序号

\\

显示印出\

xxx

显示字符串xxx

6) 若要设置一个较为符合需求的提示符号,可以使用以上介绍的方法来自行定义,以下是一个自定义提示符号的范例:

[root@localhostroot]# PS1=$’{\Happy.com\\d\\h \\ }\\$ ‘

{linux1.happy.comappy.comFri Oct 26linux1 \ }#