veket官方网站论坛

veket

 找回密码
 要注册
搜索
查看: 8339|回复: 16

Shell操作与简易编程

[复制链接]
发表于 2010-4-24 15:24 | 显示全部楼层 |阅读模式
  用户登录进入Linux系统时,可以进入基于X Window的图形视窗系统。当然很多工作可以在图形环境下完成,但是在服务器应用环境下的很多情况需要远程连接到服务器进行管理配置,而且使用命令行模式进行管理更加方便和简单,因此学习Linux,Shell的学习和使用是必不可少的一部分。
  用户登录或运行终端类比程序时,实际进入了Shell。那么,Shell是什么呢?确切一点说,Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。

  Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。因此,对于用户来说,Shell是最重要的实用程序,深入了解和熟练掌握Shell的特性极其使用方法,是用好Linux系统的关键。可以说,Shell使用的熟练程度反映了用户对Linux使用的熟练程度。

  当用户使用Linux时是通过命令来完成所需工作的。一个命令就是用户和Shell之间对话的一个基本单位,它是由多个字符组成并以换行结束的字串。Shell解释用户输入的命令,就像DOS里的 command.com一样不同的是,在DOS中,command.com只有一个,而在Linux下比较流行的Shell有好几个,每个Shell都各有千秋。一般的Linux系统都将bash作为默认的Shell。
 楼主| 发表于 2010-4-24 15:25 | 显示全部楼层

几种流行的Shell

 目前流行的Shell有ash, bash, ksh, csh, zsh等,你可以用下面的命令来查看你自己的Shell类型:

  # echo $SHELL
  $SHELL是一个环境变量,它记录用户所使用的Shell类型。你可以用命令:

  # Shell-name

  来转换到别的Shell,这里Shell-name是你想要尝试使用的Shell的名称,如ash等。这个命令为用户又启动了一个Shell,这个Shell在最初登录的那个Shell之后,称为下级的Shell或子Shell。

  使用命令:

  # exit

  可以退出这个子Shell。

  使用不同的Shell的原因在于它们各自都有自己的特点,下面做一个简单的介绍:

  1.ash

  ash Shell是由Kenneth Almquist编写的,是Linux中占用系统资源最少的一个小Shell,它只包含24个内部命令,因而使用起来很不方便。

  2.bash

  bash是Linux系统默认使用的Shell,它由Brian Fox和Chet Ramey共同完成,是Bourne Again Shell的缩写,内部命令一共有40个。Linux使用它作为默认的Shell是因为它有以下的特色:

  (1)可以使用类似DOS下面的doskey的功能,用上下方向键查阅和快速输入并修改命令。

  (2)自动通过查找匹配的方式,给出以某字串开头的命令。

  (3)包含了自身的帮助功能,你只要在提示符下面键入help就可以得到相关的帮助。

  3.ksh

  ksh是Korn Shell的缩写,由Eric Gisin编写,共有42条内部命令。该Shell最大的优点是几乎和商业发行版的ksh完全相容,这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。

  4.csh

  csh是Linux比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该Shell其实是指向/bin/tcsh这样的一个Shell,也就是说,csh其实就是tcsh。

  5.zch

  zch是Linux最大的Shell之一,由Paul Falstad完成,共有84个内部命令。如果只是一般的用途,是没有必要安装这样的Shell的。
 楼主| 发表于 2010-4-24 15:25 | 显示全部楼层

Shell基础

命令行中输入的第一个字必须是一个命令的名字,第二个字是命令的选项或参数,命令行中的每个字必须由空格或Tab隔开,格式如下:

  $ 命令 选项 参数
  选项是包括一个或多个字母的代码,它前面有一个减号(减号是必要的,Linux用它来区别选项和参数),选项可用于改变命令执行的动作的类型。例如:

  [root@start root]# ls

  anaconda-ks.cfg Desktop GNUstep pic

  这是没有选项的ls命令,可列出当前目录中的所有文档,但只列出各个文档的名字,而不显示其他更多的信息。

  [root@start root]# ls -l

  total 16

  -rw-r--r-- 1 root root 1282 10月10日 2002 anaconda-ks.cfg

  drwx------ 4 root root 4096 3月17日15:53 Desktop

  drwxr-xr-x 3 root root 4096 10月10日 2002 GNUstep

  drwxr-xr-x 3 root root 4096 3月17日16:29 pic

  加入-l选项,将会对每个文档列出详细信息,诸如资料大小和资料最后被修改的时间等。

  大多数命令都被设计为可以接纳参数。参数是在命令行中的选项之后键入的一个或多个单词,例如

  [root@start root]# ls -l pic

  total 760

  -rw-r--r-- 1 root root 74402 3月17日10:09 1.jpg

  -rw-r--r-- 1 root root 64094 3月17日10:33 2.jpg

  -rw-r--r-- 1 root root 55293 3月17日10:43 3.jpg passwd

  将显示pic目录下的所有文档及其信息。

  有些命令,如ls可以带参数,而有一些命令可能需要一些最小数目的参数。例如,cp命令至少需要两个参数,如果参数的数目与命令要求不符,Shell将会报错。例如:

  [root@start root]# cp anaconda-ks.cfg /tmp/

  注意:命令中选项应该先于参数输入。

  命令行实际上是可以编辑的一个文本缓冲区,在按回车之前,可以对输入的文本进行编辑。比如利用【BackSpace】键可以删除刚键入的字符,可以进行整行删除,还可以插入字符,使得用户在输入命令(尤其是复杂命令)时,若出现键入错误,无需重新输入整个命令,只要利用编辑操作,即可改正错误。

  利用上箭头可以重新显示刚执行的命令,利用这一功能可以重复执行以前执行过的命令,而无需重新键入该命令。

  bash保存着以前键入过的命令的列表,该列表被称为命令历史表。按动上箭头,便可以在命令行上逐次显示各条命令。同样,按动下箭头可以在命令列表中向下移动,这样可以将以前的各条命令显示在命令行上,用户可以修改并执行这些命令。

  在一个命令行中还可以置入多个命令,用分号将各个命令隔开,这些命令将按顺序执行。例如:

  [root@start root]# date;ls

  日3月17 16:56:35 CST 2002

  anaconda-ks.cfg Desktop GNUstep pic

  也可以在几个命令行中输入一个命令,用反斜杠将一个命令行持续到下一行。如:

  $ cp -i \

  mydata \

  newdata

  上面的cp命令分3行输入的,开始的两行以反斜杠结束,把第3行作为一个命令行。

  Shell中除使用普通字符外,还可以使用一些具有特殊含义和功能的特殊字符。在使用它们时应注意其特殊的含义和作用范围。下面分别对这些特殊字符加以介绍。
 楼主| 发表于 2010-4-24 15:26 | 显示全部楼层

Shell特殊字符

  通配符

  通配符用于模式匹配,如文件名匹配、路径名搜索、字串查找等。常用的通配符有(*),(?)和括在方括号[ ]中的字符序列。用户可以在作为命令参数的文件名中包含这些通配符,构成一个所谓的“模式串”,以在执行过程中进行模式匹配。
  * 代表任何字串(长度可以不等),例如:f*匹配以f打头的任意字串。但应注意,文件名前的圆点(.)和路径名中的斜线(/)必须显式匹配。例如“*”不能匹配.file,而“.*”才可以匹配.file。

  ? 代表任何单个字符。

  [ ] 代表指定的一个字符范围,只要文件名中[ ]位置处的字符在[ ]中指定的范围之内,那么这个文件名就与这个模式串匹配。方括号中的字符范围可以由直接给出的字符组成,也可以由表示限定范围的起始字符、终止字符及中间的连字符(-)组成。例如,f [a- d] 与f [abcd]的作用相同。Shell将把与命令行中指定的模式串相匹配的所有文件名都作为命令的参数,形成最终的命令,然后再执行这个命令。

  表3-1说明这些通配符的具体含义。

  表3-1 通配符的含义

模  式  串
       

含    义

*
       

当前目录下所有文档的名称

*Text*
       

当前目录下所有文件名中包含有Text的文件的名称

[ab-dm]*
       

当前目录下所有以a, b, c, d, m开头的文件的名称

[ab-dm]?
       

当前目录下所有以a, b, c, d, m开头且后面只跟有一个字符的文件的名称

/usr/bin/??
       

目录/usr/bin下所有名称为两个字符的文件的名称

  特别需要注意的是,连字符(-)仅在方括号内有效,表示字符范围,如在方括号外面就成为普通字符了。而“*”和“?”只在方括号外面是通配符,若出现在方括号之内,它们也失去通配符的能力,成为普通字符了。例如,模式- a[*?]abc中只有一对方括弧是通配符,“*”和“?”均为普通字符,因此,它匹配的字串只能是- a*abc和- a?abc。

  最后说明一下使用通配符时需要注意的一些问题。由于“*”,“?”和[ ]对于Shell来说具有比较特殊的意义,因此在正常的文件名中不应出现这些字符。特别是在目录名中不要出现它们,否则Shell匹配起来可能会无穷递归下去。另外要注意的一点是:如果目录中没有与指定的模式串相匹配的文件名,那么Shell将使用此模式串本身作为参数传给有关命令。这可能就是命令中出现特殊字符的原因所在。

  引号

  在Shell中引号分为3种:单引号,双引号和反引号。

  1.单引号

  由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。例如:

  # string='$PATH'

  # echo $string

  #PATH

  可见,$保持了其本身的含义,作为普通字符出现。

  2.双引号

  由双引号括起来的字符,除$, \, '和"这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。对于$来说,就是用其后指定的变量值来代替这个变量和$;对于 \ 而言,是转义字符,它告诉Shell不要对其后面的那个字符进行特殊处理,只当做普通字符即可。可以想见,在双引号中需要在前面加上 \ 的只有4个字符$, \, '和"本身。而对 " 号,若其前面没有加 \ ,则Shell会将它同前一个 " 号匹配。

  例如,我们假定PATH的值为.:/usr/bin:/bin,输入如下命令:

  # String="$PATH\\\"\$PATH"

  # echo $TestString

  .:/usr/bin:/ bin\"$PATH

  读者可以自己试一下在第二个双引号之前不加 \ 会产生什么结果。

  3.反引号

  反引号(`)字符所对应的键一般位于键盘的左上角,不要将其同单引号(')混淆。反引号括起来的字串被Shell解释为命令行,在执行时,Shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。例如:

  # pwd

  /home/xyz

  # string="current directory is `pwd`"

  # echo $string

  current directour is /home/xyz

  Shell执行echo命令时,首先执行`pwd`中的命令pwd,并将输出结果/home/xyz取代`pwd`部分,最后输出替换后的整个结果。

  利用反引号的这种功能可以进行命令置换,即把反引号括起来的执行结果赋值给指定变量。例如:

  # today=`date`

  # echo Today is $today

  Today is Mon Apr 15 16:20:13 CST 1999

  反引号还可以嵌套使用。但需注意,嵌套使用时内层的反引号必须用反斜线(\)将其转义。例如:

  # abc=`echo The number of users is \`who| wc-l\``

  # echo $abc

  The number of users is 5

  注释符

  在Shell编程或Linux的配置文档中,经常要对某些正文行进行注释,以增加程序的可读性。在Shell中以字符 # 开头的正文行表示注释行。
 楼主| 发表于 2010-4-24 15:27 | 显示全部楼层

标准输入与输出

  执行一个Shell命令行时通常会自动打开3个标准文档,即标准输入文档(stdin),通常对应终端的键盘;标准输出文档(stdout)和标准错误输出文档(stderr)都对应终端的屏幕。进程将从标准输入文档中得到输入资料,将正常输出资料输出到标准输出文档,而将错误信息送到标准错误文档中。

  我们以cat命令为例。cat命令的功能是从命令行给出的文件中读取资料,并将这些资料直接送到标准输出。若使用如下命令

  # cat config

  将会把文档config的内容依次显示到屏幕上。但是,如果cat的命令行中没有参数,它就会从标准输入中读取资料,并将其送到标准输出。例如:

  # cat

  Hello world

  Hello world

  Bye

  Bye

  用户输入的每一行都立刻被cat命令输出到屏幕上。

  另一个例子,命令sort按行读入文档正文(当命令行中没有给出文件名时,表示从标准输入读入),将其排序,并将结果送到标准输出。下面的例子是从标准输入读入一个采购单,并将其排序。

  # sort

  bananas

  carrots

  apples

  apples

  bananas

  carrots

  这时我们在屏幕上得到了已排序的采购单。直接使用标准输入/输出文档存在以下问题:

  输入资料从终端输入时,用户输入的资料只能用一次。下次再想用这些资料时就得重新输入。而且在终端上输入时,若输入有误修改起来不是很方便。输出到终端屏幕上的信息只能看不能动。我们无法对此输出做更多处理,如将输出作为另一命令的输入进行进一步的处理等。为了解决上述问题,Linux系统为输入、输出的传送引入了另外两种机制,即输入/输出重定向和管道。

  1.输入重定向

  输入重定向是指把命令或可执行程序的标准输入重定向到指定的文件中。也就是说,输入可以不来自键盘,而来自一个指定的文件。所以说,输入重定向主要用于改变一个命令的输入源,特别是改变那些需要大量输入的输入源。例如,命令wc统计指定文档包含的行数、单词数和字符数。如果仅在命令行上键入:

  # wc

  wc将等待用户告诉它统计什么,这时Shell就好像死了一样,从键盘键入的所有文本都出现在屏幕上,但并没有什么结果,直至按下【Ctrl+D】,wc才将命令结果显示在屏幕上。如果给出一个文档名作为wc命令的参数,如下例所示,wc将返回该文档所包含的行数、单词数和字符数。

  # wc /etc/passwd

  20 23 726 /etc/passwd

  另一种把/etc/passwd文档内容传给wc命令的方法是重定向wc的输入。输入重定向的一般形式为:命令<文件名。可以用下面的命令把wc命令的输入重定向为/etc/passwd文件:

  # wc < /etc/passwd

  20 23 726

  另一种输入重定向称为here文档,它告诉Shell当前命令的标准输入来自命令行。here文档的重定向操作符使用<<。它将一对分隔符号(分隔符号是由<<符号后的单词来定义的,本例中我们用eof来表示)之间的正文作为标准输入定向给命令。下例将一对分隔符号 eof之间的正文作为wc命令的输入,统计出正文的行数、单词数和字符数。

  [root@mail root]# wc << eof

  > hello

  > world

  > are you here?

  > eof

  3 5 26

  在<<操作符后面,任何字符或单词都可以作为正文开始前的分隔符号,本例中使用eof就作为分隔符号。here文档的正文一直延续到遇见另一个分隔符号为止。第二个分隔符号应出现在新行的开头。这时here文档的正文(不包括开始和结束的分隔符号)将重新定向送给命令wc作为它的标准输入。

  由于大多数命令都以参数的形式在命令行上指定输入档的文件名,所以输入重定向并不经常使用。尽管如此,当要使用一个不接受档名作为输入参数的命令,而需要的输入内容又存在一个文档里时,就能用输入重定向解决问题。
您需要登录后才可以回帖 登录 | 要注册

本版积分规则

QQ|手机版|Archiver|veket官方网站论坛 ( 粤ICP备 11052856 )

GMT+8, 2024-5-5 09:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表