1.3 Shell的使用基础
由于在C语言开发中常常需要和Shell打交道,本小节将简要介绍Shell的基本使用方法,终端的运行界面可以参考图1.5,以下仅仅给出在其中进行操作的相应字符串。
1.3.1 Shell命令的标准格式
Shell和用户交互是以字符串形式存在的命令和命令输出反馈的方式进行的,在Linux命令行中输入的第一个字符串必须是一个命令的名字,第二个字符串是命令的选项或参数,命令行中的每个字符串必须由空格键或Ta键隔开,格式如下。
$ 命令 选项 参数
或者
# 命令 选项 参数
提示符“$”和“#”可区分用户的不同权限,“$”表示普通用户权限,而“#”代表的是root用户(超级用户)权限。选项是包括一个或多个字母的代码,它前面有一个减号(减号是必要的,Linux用它来区别选项和参数),选项可用于改变命令执行的动作的类型。
注意:在Ubuntu操作系统中,用户不能直接使用root权限,只能通过sudo命令来暂时获得root权限。
命令行实际上是一个可以编辑的文本缓冲区,在按回车键之前,可以对输入的文本进行编辑。例如,可以利用“BackSpace”键删除刚键入的字符,可以进行整行删除,还可以插入字符。用户在输入命令(尤其是复杂命令)时,若出现输入错误,无须重新输入整个命令,只要利用编辑操作,即可改正错误。
利用向上的箭头键可以重新显示刚执行的命令,利用这一功能可以重复执行以前执行过的命令,而无须重新键入该命令。
一个标准的Shell命令和命令的反馈输出如下(这是用ls命令查看当前文件夹下文件列表的执行结果)。
alloeat@Ubuntu:/$ ls
bin cdrom etc host initrd.img.old lost+found mnt proc run selinux sys usr vmlinuz
boot dev home initrd.img lib media opt root sbin srv tmp var vmlinuz.old
1.3.2 Shell的通配符
在Shell中除使用普通字符外,还可以使用一些具有特殊含义和功能的字符,称为通配符,在使用它们时应注意其特殊的含义和作用范围。
Shell的通配符主要用于模式匹配,如文件名匹配、路径名搜索、字串查找等。常用的通配符有“*”、“?”和括在方括号“[ ]”中的字符序列等。用户可以在作为命令参数的文件名中包含这些通配符,构成一个所谓的“模式串”,以在执行过程中进行模式匹配。这3个通配符的含义分别如下。
“”代表任意长度的字串。例如,“L”匹配以L开头的任意字串。但应注意,文件名中的圆点(.)和路径名中的斜线(/)必须是显式的,即不能用通配符替代它们。例如,“”不能匹配.c,而“.”才可以匹配.c。
“?”代表任何单个字符。
“[ ]”指定了模式串匹配的字符范围,只要文件名中“[ ]”处的字符在指定的范围之内,那么这个文件名就与该模式串匹配。方括号中的字符范围可以由字符串组成,也可以由表示限定范围的起始字符、终止字符及中间连字符(-)组成。例如,f [a-d] 与f [abcd]的作用相同。
Shell把与命令行中指定的模式串相匹配的所有文件名都作为命令的参数,形成最终的命令,然后再执行这个命令。如果目录中没有与指定的模式串相匹配的文件名,那么Shell将使用此模式串本身作为参数传给命令(这正是命令中出现特殊字符的原因所在)。
表1.1列举了这些通配符的具体实例及含义。
需要注意的是,中间连字符(-)仅在方括号内有效,表示字符范围。若在方括号外面,就成为普通字符了,而“”和“?”则只在方括号外有效,若出现在方括号之内,它们也失去通配符的功能,成为普通字符了。例如,模式 L[?]abc中只有一对方括号是通配符,而“”和“?”均为普通字符,因此,它匹配的字串只能是Labc和L?abc。
【例1.1】是一个使用“*”通配符来让“ls”命令只显示当前文件夹中文件名中带“exam”,扩展名为“.c”的文件的命令和对应输出。
【例1.1】“*”通配符应用实例。
alloeat@Ubuntu:~/chapter4Exam$ ls
copytest.txt exam3write.c~ examaccess.c~ examcopy examfcntl.c exammkdir.c~ examtest examvim.c
exam1open exam4read.c examchdirgetcwd examcp.c examlseek examopendir examumask foo
exam1open.c exam4read.c~ examchdirgetcwd.c examcp.c~ examlstat examopendir.c examumask.c lseektest.txt
exam1open.c~ exam5lseek.c examchdirgetcwd.c~ examcpoy examlstat.c examopendir.c~ examumask.c~ renamebar
exam2create.c exam5lseek.c~ examchmod examdup examlstat.c~ examrename examutime testdir
exam2create.c~ examaccess examchmod.c examdup.c exammkdir examrename.c examutime.c thpic.c
exam3write.c examaccess.c examchmod.c~ examfcntl exammkdir.c examrename.c~ examutime.c~
alloeat@Ubuntu:~/chapter4Exam$ ls exam*.c
exam1open.c exam4read.c examchdirgetcwd.c examdup.c exammkdir.c examumask.c
exam2create.c exam5lseek.c examchmod.c examfcntl.c examopendir.c examutime.c
exam3write.c examaccess.c examcp.c examlstat.c examrename.c examvim.c
1.3.3 Shell中的引号
在Shell中可以使用的引号包括单引号、双引号和反引号3种。
1.单引号
由单引号括起来的字符都作为普通字符使用。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。例如,下面的一系列命令:
alloeat@Ubuntu:~/chapter4Exam$ string='$PATH'
alloeat@Ubuntu:~/chapter4Exam$ echo $string
$PATH
可见,单引号中的“$”保持了其本身的含义,作为普通字符出现,而在一般情形下,“$”符号的含义是引用变量的值,PATH本身是一个Linux系统中的环境变量,其值是一系列的目录,当用户运行某个程序时,Linux在这些目录下进行搜寻。可以使用下面的命令查看变量PATH的值。
#echo $PATH
2.双引号
双引号的作用与单引号类似,区别在于它没有那么严格。单引号告诉Shell忽略所有的特殊字符,而双引号只要求忽略大多数特殊字符。具体来说,不会忽略括在双引号中的3种特殊字符,即$、\和` ,即双引号会解释字符串的特别意义,而单引号则直接使用字符串。如果使用双引号将字符串赋给变量并反馈它,实际上与直接反馈变量并无差别。如果要查询包含空格的字符串,经常会用到双引号。
看看【例1.2】中的应用实例。
【例1.2】双引号应用实例。
alloeat@Ubuntu:/$ x=* //定义字符变量x
alloeat@Ubuntu:/$ echo $x //显示x的值
bin boot cdrom dev etc home host initrd.img initrd.img.old lib lost+found media mnt opt proc root run sbin selinux srv sys tmp usr var vmlinuz vmlinuz.old
alloeat@Ubuntu:/$ echo '$x' //单引号
$x
alloeat@Ubuntu:/$ echo "$x" //双引号
*
从【例1.2】中,可以清楚地看出无引号、单引号和双引号之间的区别。
第一种情况,显示变量x的值。由于x的值,即字符“*”匹配了当前目录(root目录)下的所有文件名,故显示变量x的值时,会显示当前目录的所有文件名。
第二种情况,使用了单引号。单引号中的字符保持其本身的含义,这种情况最简单。
最后一种情况,使用了双引号。双引号告诉Shell在引号内照样进行变量名替换,所以Shell把$x替换为,因为双引号中不做文件名替换(忽略掉了非特殊字符),所以就把“”作为要显示的值传递给echo命令,作为echo命令的参数。
另外,从例子中还可以看到Shell赋值的先后次序:Shell先进行变量替换,然后进行文件名替换,最后把这些替换值作为参数传递给命令。
3.反引号
反引号“`”字符所对应的键一般位于键盘的左上角,不要将其同单引号“'”混淆。反引号括起来的字串被Shell解释为命令行。在执行时,Shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。例如:
alloeat@Ubuntu:/$ pwd
/
alloeat@Ubuntu:/$ string="current directory is `pwd`"
alloeat@Ubuntu:/$ echo $string
current directory is /
Shell执行echo命令时,首先执行pwd中的命令pwd,并使用输出结果“/”取代pwd部分,最后输出替换后的整个结果。
利用反引号的这种功能可以进行命令置换,即把反引号括起来的执行结果赋值给指定变量。再例如:
alloeat@Ubuntu:/$ today=`date`
alloeat@Ubuntu:/$ echo today is $today
today is 2012年 08月 03日 星期五 16:58:54 CST
另外,反引号还可以嵌套使用。但需要注意的是,嵌套使用时内层的反引号必须用反斜线(\)将其转义。
1.3.4 Shell中的注释符
在Shell编程或Linux的配置文档中,经常要对某些正文行进行注释,以增加程序的可读性。在Shell中以字符 “# ”开头的正文行表示注释行。