首页 资格考试linux主要shell敕令、sed、awk应用详解

资格考试linux主要shell敕令、sed、awk应用详解

举报
开通vip

资格考试linux主要shell敕令、sed、awk应用详解资格考试linux主要shell敕令、sed、awk应用详解 1 Linux主要shell命令详解 shell是用户和Linux操作系统之间的接口。Linux中有多种shell,其中缺省使用的是Bash。本章讲述了shell的工作原理,shell的种类,shell的一般操作及Bash的特性。 什么是shell Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。 shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成...

资格考试linux主要shell敕令、sed、awk应用详解
资格考试linux主要shell敕令、sed、awk应用详解 1 Linux主要shell命令详解 shell是用户和Linux操作系统之间的接口。Linux中有多种shell,其中缺省使用的是Bash。本章讲述了shell的工作原理,shell的种类,shell的一般操作及Bash的特性。 什么是shell Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。 shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。 shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。 有一些命令,比如改变工作目录命令cd,是包含在shell内部的。还有一些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的单独的程序。对用户而言,不必关心一个命令是建立在shell内部还是一个单独的程序。 shell 首先检查命令是否是内部命令,若不是再检查是否是一个应用程序(这里的应用程序可以是Linux本身的实用程序,如ls和rm,也可以是购买的商业程序, 如xv,或者是自由软件,如emacs)。然后shell在搜索路径里寻找这些应用程序(搜索路径就是一个能找到可执行程序的目录列 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf )。如果键入的命令 不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息。如果能够成功找到命令,该内部命令或应用程序将被分解为系统调用并传给 Linux内核。 shell的另一个重要特性是它自身就是一个解释型的程序设计语言,shell程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、数组和程序控制结构。shell编程语言简单易学,任何在提示符中能键入的命令都能放到一个可执行的shell程序中。 当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进程提供了命令行提示符。作为默认值(TurboLinux系统默认的shell是BASH),对普通用户用―$‖作提示符,对超级用户(root)用―#‖作提示符。 一旦出现了shell提示符,就可以键入命令名称及命令所需要的参数。shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常结束之前,中止它的执行)。 当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文件结束符(EOF)(按ctrl+d实现),结束登录。 我们来实习一下shell是如何工作的。 $ make work make:***No rule to make target ?work‘. Stop. $ 注释:make是系统中一个命令的名字,后面跟着命令参数。在接收到这个命令后,shell便执行它。本例中,由于输入的命令参数不正确,系统返回信息后停止该命令的执行。 在 例子中,shell会寻找名为make的程序,并以work为参数执行它。make是一个经常被用来编译大程序的程序,它以参数作为目标来进行编译。在 ―make work‖中,make编译的目标是work。因为make找不到以work为名字的目标,它便给出错误信息表示运行失败, 用户又回到系统提示符下。 另外,用户键入有关命令行后,如果shell找不到以其中的命令名为名字的程序,就会给出错误信息。例如,如果用户键入: $ myprog bash:myprog:command not found $ 可以看到,用户得到了一个没有找到该命令的错误信息。用户敲错命令后,系统一般会给出这样的错误信息。 shell的种类 Linux 中的shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和Korn shell(ksh)。三种shell各有优缺点。Bourne shell是UNIX最初使用的shell,并且在每种UNIX上都可以使用。Bourne shell在shell编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。Linux操作系统缺省的shell是Bourne Again shell,它是Bourne shell的扩展,简称Bash,与Bourne shell完全向后兼容,并且在Bourne shell的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含 了很多C shell和Korn shell中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。 C shell是一种比Bourne shell更适于编程的shell,它的语法与C语言很相似。 Linux为喜欢使用C shell的人提供了Tcsh。Tcsh是C shell的一个扩展版本。Tcsh包括命令行编辑、可编程单词补全、拼写校正、历史命令替换、作业控制和类似C语言的语法,它不仅和Bash shell是提示符兼容,而且还提供比Bash shell更多的提示符参数。 Korn shell集合了C shell和Bourne shell的优点并且和Bourne shell完全兼容。Linux系统提供了pdksh(ksh的扩展),它支持任务控制,可以在命令行上挂起、后台执行、唤醒或终止程序。 Linux 并没有冷落其他shell用户,还包括了一些流行的shell如ash、zsh等。每个shell都有它的用途,有些shell是有专利的,有些能从 Internet网上或其他来源获得。要决定使用哪个shell,只需读一下各种shell的联机帮助,并试用一下。 用户在登录到Linux时由/etc/passwd文件来决定要使用哪个shell。例如: # fgrep lisa /etc/passwd lisa:x:500:500:TurboLinux User:/home/lisa:/bin/bash shell被列每行的末尾(/bin/bash)。 由于Bash是Linux上缺省的shell,本章主要介绍Bash及其相关知识。 shell命令 命令行c 用户登录到Linux系统时,可以看到一个shell提示符,标识了命令行的开始。用户可以在提示符后面输入任何命令及参数。例如: $ date 二 11 23 01:34:58 CST 1999 $ 用户登录时,实际进入了shell,它遵循一定的语法将输入的命令加以解释并传给系统。命令行中输入的第一个字必须是一个命令的名字,第二个字是命令的选项或参数,命令行中的每个字必须由空格或TAB隔开,格式如下: $ Command Option Arguments 1. 选项和参数 选项是包括一个或多个字母的代码,它前面有一个减号(减号是必要的,Linux用它来区别选项和参数),选项可用于改变命令执行的动作的类型。例如: $ ls motd passwd $ 这是没有选项的ls命令,可列出当前目录中所有文件,只列出各个文件的名字,而不显示其他更多的信息。 $ ls -l total 2 -rw-r--r-- 2 wzh book 22 Apr 20 20:37 motd -rw-r--r-- 2 wzh book 796 Apr 20 20:37 passwd $ 加入-l选项,将会为每个文件列出一行信息,诸如数据大小和数据最后被修改的时间。 大多数命令都被设计为可以接纳参数。参数是在命令行中的选项之后键入的一个或多个单词,例如: $ ls -l text -rw-r--r-- 2 wzh book 22 Apr 20 20:37 motd -rw-r--r-- 2 wzh book 796 Apr 20 20:37 passwd $ 将显示text目录下的所有文件及其信息。 有些命令,如ls可以带参数,而有一些命令可能需要一些最小数目的参数。例如,cp命令至少需要两个参数,如果参数的数目与命令要求不符,shell将会给出出错信息。例如: $ cp -i mydata newdata 注意:命令行中选项先于参数输入。 2. 命令行特征 命 令行实际上是可以编辑的一个文本缓冲区,在按回车之前,可以对输入的文本进行编辑。比如利用BACKSPACE键可以删除刚键入的字符,可以进行整行删 除,还可以插入字符,使得用户在输入命令,尤其是复杂命令时,若出现键入错误,无须重新输入整个命令,只要利用编辑操作,即可改正错误。 利用上箭头可以重新显示刚执行的命令,利用这一功能可以重复执行以前执行过的命令,而无须重新键入该命令。 bash 保存着以前键入过的命令的列表,这一列表被称为命令历史表。按动上箭头,便可以在命令行上逐次显示各条命令。同样,按动下箭头可以在命令列表中向下移动, 这样可以将以前的各条命令显示在命令行上,用户可以修改并执行这些命令。这一特征将在10.4节中进行详细的论述。 在一个命令行中还可以置入多个命令,用分号将各个命令隔开。例如: $ ls -F;cp -i mydata newdata 也可以在几个命令行中输入一个命令,用反斜杠将一个命令行持续到下一行。 $ cp –i mydata newdata 上面的cp命令是在三行中输入的,开始的两行以反斜杠结束,把三行作为一个命令行。 shell中的特殊字符 shell中除使用普通字符外,还可以使用一些具有特殊含义和功能的特殊字符。在使用它们时应注意其特殊的含义和作用范围。下面分别对这些特殊字符加以介绍。 1. 通配符 通配符用于模式匹配,如文件名匹配、路经名搜索、字符串查找等。常用的通配符有*、?和括在方括号, ,中的字符序列。用户可以在作为命令参数的文件名中包含这些通配符,构成一个所谓的―模式串‖,在执行过程中进行模式匹配。 * 代表任何字符串(长度可以不等),例如:―f*‖匹配以f打头的任意字符串。但应注意,文件名前的圆点(.)和路经名中的斜线(/)必须显式匹配。例如―*‖不能匹配.file,而―.*‖才可以匹配.file。 ? 代表任何单个字符。 ,, 代表指定的一个字符范围,只要文件名中, ,位置处的字符在,,中指定的范围之内,那么这个文件名就与这个模式串匹配。方括号中的字符范围可以由直接给出的字符组成,也可以由表示限定范围的起始字符、终止字符及中间的连字符(-)组成。例如,f ,a- d, 与f ,abcd,的作用相同。Shell将把与命令行中指定的模式串相匹配的所有文件名都作为命令的参数,形成最终的命令,然后再执行这个命令。 下面我们给出表10-1说明这些通配符的具体含义。 表10-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将使用此模式串本身作为参数传给有关命令。这可能就是命令中出现特殊字符的原因所在。 2. 引号 在shell中引号分为三种:单引号,双引号和反引号。 * 单引号 ? 由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。例如: $ string=‘$PATH‘ $ echo $string $PATH $ 可见$保持了其本身的含义,作为普通字符出现。 * 双引号 ― 由双引号括起来的字符,除$、\、‘、和‖这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。对于$来说,就是用其后指定的变量的值来代替这个变量和$;对于\而言,是转义字符,它告诉shell不要对其后面的那个字符进行特殊处理,只当作普通字符即可。可以想见,在双引号中需要在前面加上\的只有四个字符$,\,‘和‖本身。而对‖号,若其前面没有加,则Shell会将它同前一个‖号匹配。 例如,我们假定PATH的值为.:/usr/bin:/bin,输入如下命令: $ TestString,‖$PATH\‖$PATH‖ $ echo $TestString .:/usr/bin:/ bin‖$PATH $ 读者可以自己试一下在第二个双引号之前不加会产生什么结果。 * 反引号 ` 反引号(`)这个字符所对应的键一般位于键盘的左上角,不要将其同单引号(‘)混淆。反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 输出结果取代整个反引号(包括两个反引号)部分。例如: $ 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的特殊字符。Shell为得到``中命令的结果,它实际上要去执行``中指定的命令。执行时,命令中的特殊字符,如$,‖,?等又将具有特殊含义,并且``所包含的可以是任何一个合法的Shell命令,如: $ ls note readme.txt Notice Unix.dir $ TestString,‖`echo $HOME ` ` ls ,nN,*`‖ $ echo $TestString /home/yxz note Notice $ 其他情况,读者可自行试之。 9.1 注释符 在shell编程中经常要对某些正文行进行注释,以增加程序的可读性。在Shell中以字符―#‖开头的正文行表示注释行。 此外还有一些特殊字符如:用于输入/输出重定向与管道的<、>、<<、>>和|;执行后台命令的&;命令执行操作符&&和||及表示命令组的{}将在下面各小节中加以介绍。 9.2 标准输入/输出和重定向 9.2.1 标准输入与输出 我们知道,执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(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系统为输入、输出的传送引入了另外两种机制,即输入/输出重定向和管道。 9.2.2 输入重定向 输入重定向是指把命令(或可执行程序)的标准输入重定向到指定的文件中。也就是说,输入可以不来自键盘,而来自一个指定的文件。所以说,输入重定向主要用于改变一个命令的输入源,特别是改变那些需要大量输入的输入源。 例如,命令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文档的重定向操作符使用<<。它将一对分隔符(本例中用delim表示)之间的正文重定向输入给命令。下例将一对分隔符delim之间的正文作为wc命令的输入,统计出正文的行数、单词数和字符数。 $ wc<this text forms the content >of the here document,which >continues until the end of >text delimter >delim 4 17 98 在< <操作符后面,任何字符都可以作为正文开始前的分隔符,本例中使用delim作为分隔符。here文档的正文一直延续到遇见另一个分隔符为止。第二 个分隔符应出现在新行的开头。这时here文档的正文(不包括开始和结束的分隔符)将重新定向送给命令wc作为它的标准输入。 由于大多数命令都以参数的形式在命令行上指定输入文件的文件名,所以输入重定向并不经常使用。尽管如此,当要使用一个不接受文件名作为输入参数的命令,而需要的输入内容又存在一个文件里时,就能用输入重定向解决问题。 9.2.3 输出重定向 输出重定向是指把命令(或可执行程序)的标准输出或标准错误输出重新定向到指定文件中。这样,该命令的输出就不显示在屏幕上,而是写入到指定文件中。 输 出重定向比输入重定向更常用,很多情况下都可以使用这种功能。例如,如果某个命令的输出很多,在屏幕上不能完全显示,那么将输出重定向到一个文件中,然后 再用文本编辑器打开这个文件,就可以查看输出信息;如果想保存一个命令的输出,也可以使用这种方法。还有,输出重定向可以用于把一个命令的输出当作另一个 命令的输入(还有一种更简单的方法,就是使用管道,将在下面介绍)。 输出重定向的一般形式为:命令>文件名。例如: $ ls > directory.out $ cat directory.out ch1.doc ch2.doc ch3.doc chimp config mail/ test/ $ 将ls命令的输出保存为一个名为directory.out的文件。 注:如果>符号后边的文件已存在,那么这个文件将被重写。 为 避免输出重定向中指定文件只能存放当前命令的输出重定向的内容,shell提供了输出重定向的一种追加手段。输出追加重定向与输出重定向的功能非常相似, 区别仅在于输出追 加重定向的功能是把命令(或可执行程序)的输出结果追加到指定文件的最后,而该文件原有内容不被破坏。 如果要将一条命令的输出结果追加到指定文件的后面,可以使用追加重定向操作符>>。形式为:命令>>文件名。例如: $ ls *.doc>>directory.out $ cat directory.out ch1.doc ch2.doc ch3.doc chimp config mail/ test/ ch1.doc ch2.doc ch3.doc $ 和程序的标准输出重定向一样,程序的错误输出也可以重新定向。使用符号2>(或追加符号2>>)表示对错误输出设备重定向。例如下面的命令: $ ls /usr/tmp 2> err.file 可在屏幕上看到程序的正常输出结果,但又将程序的任何错误信息送到文件err.file中,以备将来检查用。 还可以使用另一个输出重定向操作符(&>)将标准输出和错误输出同时送到同一文件中。例如: $ ls /usr/tmp &> output.file 利用重定向将命令组合在一起,可实现系统单个命令不能提供的新功能。例如使用下面的命令序列: $ ls /usr/bin > /tmp/dir $ wc –w < /tmp/dir 459 统计了/usr/bin目录下的文件个数。 管 道 将一个程序或命令的输出作为另一个程序或命令的输入,有两种方法,一种是通过一个临时文件将两个命令或程序结合在一起,例如上个例子中的/tmp/dir文件将ls和wc命令联在一起;另一种是Linux所提供的管道功能。这种方法比前一种方法更好。 管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中未使用输出重定向)。 通过使用管道符―|‖来建立一个管道行。用管道重写上面的例子: $ ls /usr/bin|wc -w 1789 再如: $ cat sample.txt|grep "High"|wc -l 管道将cat命令(列出一个文件的内容)的输出送给grep命令。grep命令在输入里查找单词High,grep命令的输出则是所有包含单词High的行,这个输出又被送给wc命令,wc命令统计出输入中的行数。假设sample.txt文件的内容如下: Things to do today: Low:Go grocery shopping High:Return movie High:Clear level 3 in Alien vs. Predator Medium:Pick up clothes from dry cleaner那么该管道行的结果是2。 命令替换 命令替换和重定向有些相似,但区别在于命令替换是将一个命令的输出作为另外一个命令的参数。常用命令格式为: command1 `command2` 其中,command2的输出将作为command1的参数。需要注意的是这里的`符号,被它括起来的内容将作为命令执行,执行后的结果作为command1的参数。例如: $ cd `pwd` 该命令将pwd命令列出的目录作为cd命令的参数,结果仍然是停留在当前目录下。 命令和文件名扩展特性 Bash 命令行具有命令和文件名扩展特性。当输入一个还没完成的命令或文件名时,只需键入Tab键就能激活命令和文件名扩展特性,从而完成该命令的剩余输入。如果 有多个命令或文件的前缀相同,Bash将响铃并等待用户输入足够的字符,以便选择唯一的命令或文件名,如果找到,系统将自动补齐搜索到的命令或文件名,用 户按回车键后,系统将执行这条指令。例如: $ cat pre $ cat preface Bash 也能列出当前目录下部分匹配的文件名来完成文件名扩展。如果键入Esc,然后键入?,shell将列出所有与输入的字符串相匹配的文件名。例如下例,在没 有完成的输入后键入Esc ?,shell将列出所有与输入的字符串相匹配的字符串,然后shell回显命令行,根据列出的文件名,可以键入要输入的文件名或按下Tab键来完成文件 名扩展。例如: $ ls document docudrama $ cat doc document docudrama $ cat docudrama ,例,下面是一个目录包含的文件列表: Firebird2.7.tgz Firebird.README Firebird2.60.tgz FireBird Firebird2.60.tgz.README 现在要删除Firebird2.60.tgz.README文件,键入: $ rm –f Fi 系统会发出警报声,并且自动将命令行补全为: $ rm –f Fire 并等待用户进一步输入文件名的后面部分。现在再键入: b 系统再次发出警报声,并且自动将命令行补全为: $ rm –f Firebird 并等待用户进一步输入文件名的后面部分。现在再键入: 2.6 系统再次发出警报声,并且自动将命令行补全为: $ rm –f Firebird2.60.tgz 并等待用户进一步输入文件名的后面部分。现在再键入: . 此时命令将被补全为: $ rm –f Firebird2.60.tgz..README 从 上例可以看到,bash总是尽力根据用户输入的信息来补全命令。当无法根据现有信息补全命令时,则提示用户再给出更多的信息,然后再根据用户的提示来进一 步补全命令。作为用户最好是能够一次性给出足够的信息以便于bash进行命令补全;否则多按几次,时间也就消耗掉了。 命令行编辑 在Bash中可以对命令行进行编辑,以便用户在执行所键入的命令之前能够修改所键入的命令。如果在键入命令时出现拼写错误,只需在运行所键入的命令之前,使用编辑命令来纠正编辑错误,然后执行它,而不用重新输入整行命令。这个功能对以长路径文件名作参数的命令特别有用。 表10-2是对命令行编辑操作的一个总结。 表10-2 命令行编辑操作 命令行编辑操作 功能 Ctrl+b或左箭头键 左移一个字符(移至前一个字符) Ctrl+f或右箭头键 右移一个字符(移至后一个字符) Ctrl+a 移至行首 Ctrl+e 移至行尾 Esc b 左移一个单词 Esc f 右移一个单词 Del 删除光标所在处的字符 Ctrl+d 删除光标所在处的字符 BACKSPACE或Ctrl+h 删除光标左边的字符 Ctrl+k 删除至行尾 命令历史 在Bash 中,history命令能够保存最近所执行的命令。这些命令的历史记录号从1开始,只有有限个命令可以被保存起来,最多500个,即 history命令的历史记录号缺省值为500。要查看最近执行的命令,只要键入history命令,然后键入回车键,最近执行过的命令即按 先后顺序被显 示出来(各条命令前的数字为历史记录号)。 ,例】 $ history 1 cp mydata today 2 vi mydata 3 mv mydata reports 4 cd reports 5 ls … 所有这些命令都被称为事件(event),一个事件表示一个操作已经发生,即一个命令已被执行。这些事件根据它们被执行的先后顺序用数字标识,这一标识称为历史事件号。最后执行的历史事件的事件号最大。每个事件都可由它的历史事件号或命令的初始字符或字符串等确定。 利用history命令能够查询以前的事件,并可把它们显示到命令行上执行这一事件。最简便的方法就是利用上下箭头键,把先前的事件逐次显示到命令行。这个 操作不需要运行history命令就可以执行。按动一下上箭头键,那么上一次执行的一个事件就将出现在命令行上,再按一下,上一次的前一事件又会出现在命 令行上;按动一下下箭头键,将会使当前事件的下一事件出现在命令行上。 Bash也可以通过键入Esc、Tab键来完成对历史事件的字符扩展。和标准命令行扩展特性一样,键入历史事件的部分字符串,然后键入Esc,再键入Tab键,与刚才键入的字符串相匹配的历史事件将自动扩展并回显到命令行处。如果不止一个事件与输入的字符串相匹配,就会听到一声响铃,继续键入字符或字 符串,shell将会唯一确定用户所要键入的历史事件。 还有一个查询和执行历史事件的命令——!命令。在!命令后键入与历史事件相关联的字符,这个关联字符可以是历史事件的历史事件号,也可以是该事件的前几个字符。在下面的例子中,查询到历史事件号为3的事件,然后又用其开头的几个字符去匹配,也查询到该命令。 ,例】 $ !3 mv mydata reports $ !mv mv mydata reports 也可以用一个偏移量(相对于历史事件列表中最后一个事件)来查询历史事件。负的偏移量将从历史事件列表表尾向前偏移。在下面的例子中,历史事件号为2的事件 ―vi mydata‖就是用一个负的偏移量查询到的。必须注意的是,这个偏移量是相对于历史事件列表中的最后一个事件的。在本例中,历史事件列表中最后一个事件 是事件5,历史事件列表中第一个事件为1。从历史事件号为5的事件,往前偏移4,即是历史事件号为2的事件。 ,例】 $ !-4 vi mydata 如果键入!!,则系统默认为上一事件。下面的例子中,用户在命令行上键入!!命令,系统将执行上一事件:―ls‖命令。 ,例】 $ !! ls mydata today reports 也可以用―模式‖来搜索一个历史事件。搜索的―模式‖必须用符号―?‖括起来。下例是用―模式‖―?myd?‖来搜索历史事件号为3的历史事件―vi mydata‖。 ,例】 $ !?myd? vi mydata 1. 查询历史事件 可以在命令行上编辑历史事件列表中的事件。表10-3列出了查询历史事件列表的各种操作。 表10-3 查询历史事件操作 查询历史事件操作 功能 Ctrl+n或向下光标键 移至历史事件列表中当前事件的下一历史事件 Ctrl+p或向上光标键 移至历史事件列表中当前事件的前一历史事件 Esc < 移至历史事件列表表首 Esc > 移至历史事件列表表尾 !event_num 用历史事件号来定位一个历史事件 !characters 用历史事件的字符前缀来查询一个历史事件 !?pattern 用―模式‖来查询历史事件列表中的事件 !-event_num 通过偏移量来定位历史事件 2. 配置history:HISTFILE及HISTSIZE 系统保存的历史事件数被保存在一个特定的系统变量中,这个变量就是HISTSIZE。这个变量的缺省值通常被设置为500。这个值可以被修改。例如: $ HISTSIZE=10 将HISTSIZE的值重新设置为10。 历史事件被保存在一个文件中,文件名由变量HISTFILE指定。通常这个文件的缺省名是.bash_history。通过给变量HISTFILE赋值,可以指定新的文件名。 ,例】 $ echo $HISTFILE /home/lisa/.bash_history $ HISTFILE=‖/home/lisa/newhist‖ $ echo $HISTFILE /home/lisa/newhist 以上操作先显示变量HISTFILE的值,然后赋予它新的值―/home/lisa/newhist‖,以后所有的历史事件将被保存在newhist文件中。 别名 还有一个使工作变得轻松的方法是使用命令别名。命令别名通常是其他命令的缩写,用来减少键盘输入。 命令格式为: alias ,alias-name=‘original-command‘, 其 中,alias-name是用户给命令取的别名,original-command是原来的命令和参数。需要注意的是,由于Bash是以空格或者回车来识 别原来的命令的,所以如果不使用引号就可能导致Bash只截取第一个字,从而出现错误。如果alias命令后面不使用任何参数,则显示当前正在使用的被别 名化的命令及其别名。为命令取的别名在该次登录期间始终有效。如果用户需要别名在每次登录时都有效,那么就将alias命令写到初始化脚本文件中。 ,例,如果经常要键入如下的命令,最好为它建立一个别名来减少工作量。 $ cd /usr/X11/lib/X11 假如为这个长命令建立一个名为goconfig的别名,在Bash提示符下键入如下命令: $ alias goconfig=‘cd /usr/X11/lib/X11‘ 现在,除非您退出Bash,键入goconfig将和原来的长命令有同样的作用。如果想取消别名,可以使用下面的命令: $ unalias goconfig 这是一些很多人认为有用的别名,可以把它们写入初始化脚本文件中来提高工作效率: alias ll=‘ls –l‘ alias log=‘logout‘ alias ls=‘ls –F‘ 如果您是一名DOS用户并且习惯了DOS命令,可以用下面的别名定义使Linux表现得象DOS一样: alias dir=‘ls‘ alias copy=‘cp‘ alias rename=‘mv‘ alias md=‘mkdir‘ alias rd=‘rmdir‘ 注意:在定义别名时,等号两边不能有空格,否则shell不能决定您需要做什么。仅在命令中包含空格或特殊字符时才需要引号。 如果键入不带任何参数的alias命令,将显示所有已定义的别名。 提示符 Bash有两级提示符。第一级提示符是经常见到的Bash在等待命令输入时的情况。第一级提示符的默认值是$符号。如果用户不喜欢这个符号,或者愿意自己定义提示符,只需修改PS1变量的值。例如将其改为: PS1=‖Enter a command:‖ 第二级提示符是当Bash为执行某条命令需要用户输入更多信息时显示的。第二级提示符默 认为>。如果需要自己定义该提示符,只需改变PS2变量的值。例如将其改为: PS2=‖More information:‖ 上面的两个例子都是设定提示符为静态字符串的情况。其实用户也可以使用一些事先已经定 义好的特殊字符。这些特殊字符将使提示符中包含当前时间之类的信息。表10-4列出了最 常用的一些特殊字符及其含义。 表10-4 bash提示符常用特殊字符 特殊字符 说 明 ! 显示该命令的历史编号 # 显示shell激活后,当前命令的历史编号 $ 显示一个$符号,如果当前用户是root则显示#符号 \ 显示一个反斜杠 d 显示当前日期 h 显示运行该shell的计算机主机名 n 打印一个换行符,这将导致提示符跨行 s 显示正在运行的Shell的名称 t 显示当前时间 u 显示当前用户的用户名 W 显示当前工作目录基准名 w 显示当前工作目录 这些特殊字符可以组合起来,为用户提供一些提示符,提供很有用的信息。下面来看几个实 际例子: PS1=‖t‖ 将使提示符变成如下所示: 02:16:15 而 PS1=t 将使提示符变成如下所示: t 若PS1=‖t\‖ 将使提示符变成如下所示: 02:16:30 该例就是使用两个特殊字符的组合得到的。 控制shell的运行方式 Bash 有一些特殊变量,能控制shell以不同的方式工作。例如,变量noclobber能防止在重定向输出时意外地覆盖一个文件。通过set命令可以设置 noclobber变量的有效或无效。set命令有两个参数:一个是指定变量开(on)或关(off)的选项,一个是特殊变量的变量名。要使某一特殊变量 开(有效),用-o选项,要使其关(无效),用+o选项。例如: $ set –o noclobber // 使noclobber变量开 $ set +o noclobber // 使noclobber变量关 三个最常用的shell特殊变量有:ignoreeof、noclobber及noglob。 ignoreeof ignoreeof 变量用来禁止使用ctrl+d来退出shell(ctrl+d不仅用来退出shell,而且可以终止用户直接输往标准输出上的输入。该操作经常在一些 shell实用命令中使用,例如实用命令cat。在这些实用程序操作中,非常容易误操作而意外地退出shell。ignoreeof特殊变量正是用来防止 这种意外的退出。例如: $ set –o ignoreeof 之后,用户只能用logout或exit命令退出shell。 noclobber noclobber变量可以在重定向输出时保护已存在的文件,防止被意外地覆盖。在下例中,用户设置noclobber为有效,在重定向时,用户试图去覆盖已经存在的文件myfile,此时系统将返回一个错误信息。 ,例, $ set –o noclobber $ cat preface>myfile bash: myfile: cannot overwrite existing file $ noglob 设置noglob变量后,shell将不扩展文件名中一些特殊的字符或字符串。如字符*、?、,,等将不再作为通配符。如果用户希望列出结尾为?的文件名 answer?,可通过如下步骤:首先,用户使noglob变量为无效,然后再列出文件名。可以看到,目前命令行上的问号?被认为是文件名中的一个字符, 而不再被看作通配符。 $ set –o noglob $ ls answer? answer? 子shell与export命令 用 户登录到Linux系统后,系统将启动一个用户shell。在这个shell中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程 序。运行shell脚本程序时,系统将创建一个子shell。此时,系统中将有两个shell,一个是登录时系统启动的shell,另一个是系统为运行脚 本程序创建的shell。当一个脚本程序运行完毕,它的脚本shell将终止,可以返回到执行该脚本之前的shell。从这种意义上来说,用户可以有许多 shell,每个shell都是由某个 shell(称为父shell)派生的。 在子shell中定义的变量只在该子shell内有效。如 果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,这个定义的变量只是该脚本程序内的一个局部变量,其他的shell不能引用它,要使某 个变量的值可以在其他shell中被改变,可以使用export命令对已定义的变量进行输出。 export命令将使系统在创建每一个新的shell时定义这个变量的一个拷贝。这个过程称之为变量输出。 ,例,在本例中,变量myfile是在dispfile脚本程序中定义的。然后用export命令将变量myfile输出至任何子shell,例如当执行printfile脚本程序时产生的子shell。 dispfile脚本程序清单: /**************begin dispfile**************/ myfile=‖List‖ export myfile echo ―Displaying $myfile‖ pr –t –n $myfile printfile /**************end dispfile***************/ printfile脚本程序清单: /**************begin printfile**************/ echo ―Printing $myfile‖ lpr $myfile& /**************end printfile**************/ $dispfile Displaying List 1 screen 2 modem 3 paper Printing List $ 定制Bash 在本节中已经介绍了很多定制Bash的方法,但是迄今为止,这些方法都只是对当前Bash对话有用。只要用户退出登录,所做的一切改变都会丢失。所以应该在Bash的初始化文件中做永久性的修改。 用户可以将每次启动Bash所需要执行的命令放入初始化文件中,最常见的命令就是alias命令和变量定义两种。系统中的每个用户在其主目录中都有一个.bash_profile文件,Bash每次启动时都将读取该文件,其中包含的所有命令都将被执行。 下面便是默认.bash_profile文件的代码: #.bash_profile #Get the aliases and functions if ,-f ~/.bashrc ,;then .~/.bashrc fi #User specific environment and startup programs PATH=$PATH:$HOME/bin ENV=$HOME/.bashrc USERNAME=‖‖ Export USERNAME ENV PATH 10 Linux bash shell脚本语法入门 10.1 基础 #!/bin/bash //bash脚本第一句都是这个,他会让系统指定以bash来解释这个脚本 # //shell脚本注释符号 10.2 变量和使用 HOME="/home" //注意赋值不要有空格 a=123 HOME_LIST=$(ls /home) //把命令的执行结果赋值给变量 ehco $HOME //$ 符号是获得变量HOME的值 a=a+1 系统变量: $0 这个程序的执行名字 $n 这个程序的第n个参数值,n=1...9 $* 这个程序的所有参数 $# 这个程序的参数个数 $$ 这个程序的PID $! 执行上一个背景指令的PID $? 上一个指令的返回值 10.3 if语句 if [ "22" -lt "33" ] then //注意空格 echo "22 less than 33" else echo "no" fi //if语句的结束 10.4 case语句 echo "enter a number" read ans //读取一个变量read case $ans in 1) echo "you numer is $ans" ;; //注意符号是两个 ; 2) echo "you number is 2" ;; [3-9]) echo "you number is $ans" ;; *) //*通配符 echo "others" esac 10.5 比较运算符 运算符 描述 示例 文件比较运算符 -e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ] -d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ] -f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ] -L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ] -r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ] -w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ] -x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ] filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ] filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ] 字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法) -z string 如果 string 长度为零,则为真 [ -z "$myvar" ] -n string 如果 string 长度非零,则为真 [ -n "$myvar" ] string1 = string2 如果 string1 与 string2 相同,则为真 [ "$myvar" = "one two three" ] string1 != string2 如果 string1 与 string2 不同,则为真 [ "$myvar" != "one two three" ] 算术比较运算符 num1 -eq num2 等于 [ 3 -eq $mynum ] num1 -ne num2 不等于 [ 3 -ne $mynum ] num1 -lt num2 小于 [ 3 -lt $mynum ] num1 -le num2 小于或等于 [ 3 -le $mynum ] num1 -gt num2 大于 [ 3 -gt $mynum ] num1 -ge num2 大于或等于 [ 3 -ge $mynum ] 10.6 bash中几种循环 6.1. for name [ in word ] ; do list ; done 6.2. for (( expr1 ; expr2 ; expr3 )) ; do list ; done //注意有2层括号 6.3 while [expr] do list; done 其中list简单说就是一串由操作符(operator ;、&、&&、||) 分各给出一个简单例子: 1. for filename in $(ls) do cat $filename done 2. for((i=0; i<10; i++)) do echo $i done 3. x=1 sum=0 while [ $x -le 10 ] //注意[ ] 两边的空格 do let sum=sum+$x //shell中算术计算使用let let x=x+1 done echo $sum 10.7 shell 编程中使用到得if语句内判断参数 –b 当file存在并且是块文件时返回真 -c 当file存在并且是字符文件时返回真 -d 当pathname存在并且是一个目录时返回真 -e 当pathname指定的文件或目录存在时返回真 -f 当file存在并且是正规文件时返回真 -g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真 -h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效 -k 当由pathname指定的文件或目录存在并且设置了―粘滞‖位时返回真 -p 当file存在并且是命令管道时返回为真 -r 当由pathname指定的文件或目录存在并且可读时返回为真 -s 当file存在文件大小大于0时返回真 -u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真 -w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。 -o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。 UNIX Shell 里面比较字符写法: -eq 等于 -ne 不等于 -gt 大于 -lt 小于 -le 小于等于 -ge 大于等于 -z 空串 = 两个字符相等 != 两个字符不等 -n 非空串 ------------------------------------------------------------------------- 更为详细的说明: 运算符 描述 示例 文件比较运算符 -e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ] -d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ] -f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ] -L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ] -r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ] -w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ] -x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ] filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ] filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ] 字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法) -z string 如果 string 长度为零,则为真 [ -z $myvar ] -n string 如果 string 长度非零,则为真 [ -n $myvar ] string1 = string2 如果 string1 与 string2 相同,则为真 [ $myvar = one two three ] string1 != string2 如果 string1 与 string2 不同,则为真 [ $myvar != one two three ] 算术比较运算符 num1 -eq num2 等于 [ 3 -eq $mynum ] num1 -ne num2 不等于 [ 3 -ne $mynum ] num1 -lt num2 小于 [ 3 -lt $mynum ] num1 -le num2 小于或等于 [ 3 -le $mynum ] num1 -gt num2 大于 [ 3 -gt $mynum ] num1 -ge num2 大于或等于 [ 3 -ge $mynum ] 脚本示例: #!/bin/bash # This script prints a message about your weight if you give it your # weight in kilos and hight in centimeters. if [ ! $# == 2 ]; then echo "Usage: $0 weight_in_kilos length_in_centimeters" exit fi weight="$1" height="$2" idealweight=$[$height - 110] if [ $weight -le $idealweight ] ; then echo "You should eat a bit more fat." else echo "You should eat a bit more fruit." fi # weight.sh 70 150 You should eat a bit more fruit. # weight.sh 70 150 33 Usage: ./weight.sh weight_in_kilos length_in_centimeters 位置参数 $1, $2,..., $N,$#代表了命令行的参数数量, $0代表了脚本的名字, 第一个参数代表$1,第二个参数代表$2,以此类推,参数数量的总数存在$#中,上面的例子显示了怎么改变脚本,如果参数少于或者多余2个来打印出一条消息。 执行,并查看情况。 # bash -x tijian.sh 60 170 + weight=60 + height=170 + idealweight=60 + '[' 60 -le 60 ']' + echo 'You should eat a bit more fat.' You should eat a bit more fat. 其中-x用来检查脚本的执行情况。 10.8 DOS/Windows和Linux/Unix间文件格式和字符集 转换 DOS/Windows和Linux/Unix的文件换行回车格式不同,基于 DOS/Windows的文本文件在每一行末尾有一个 CR (回车)和 LF (换行),而 UNIX 文本只有一个换行。 1 )、把Dos/Windows 下的文件移至Linux/Unix系统 虽然很多程序不在乎 DOS/Windows格式的 CR/LF文本文件,但是有几个程序却在乎——最著名的是 bash ,只要一遇到回车,它就会出问题。以下 sed调用将把 DOS/Windows格式的文本转换成可信赖的 UNIX 格式: $ sed -e 's/.$//' mydos.txt > myunix.txt 该脚本的工作原理很简单:替代规则表达式与一行的最末字符匹配,而该字符恰好就是回车。我们用空字符替换它,从而将其从输出中彻底删除。如果使用该脚本并注意到已经删除了输出中每行的最末字符,那么,您就指定了已经是 UNIX格式的文本文件。也就没必要那样做了~ 2 )、把Linux/UNIX文本移至 Windows系统,使用以下脚本执行必需的格式转换: $ sed -e 's/$/\r/' myunix.txt > mydos.txt 在该脚本中,'$' 规则表达式将与行的末尾匹配,而 '\r' 告诉 sed在其之前插入一个回车。在换行之前插入回车,立即,每一行就以 CR/LF结束。请注意,仅当使用 GNU sed 3.02.80 或以后的版本时,才会用 CR 替换 '\r'. 10.9 iconv 的使用方法 iconv---编码转换 用法: iconv [选项...] [文件...] 有如下选项可用: 输入/输出格式规范: -f, --from-code=名称 原始文本编码 -t, --to-code=名称 输出编码 信息: -l, --list 列举所有已知的字符集 输出控制: -c 从输出中忽略无效的字符 -o, --output=FILE 输出文件 -s, --silent 关闭警告 --verbose 打印进度信息 -?, --help 给出该系统求助列表 --usage 给出简要的用法信息 -V, --version 打印程序版本号 例子: iconv -c -f utf-8 -t gb2312 aaa.txt >bbb.txt 这个命令读取aaa.txt文件,从utf-8编码转换为gb2312编码,忽略无效的字符,其输出定向到bbb.txt文件。 utf-8 和 gb2312 在 windows 上看是一样的。在linux下是有区别的。粘贴、复制utf-8编码的字都会改变其编码,变为gb2312(windows下)。只有通过ftp 才能保证它的编码不变化 10.10 命令格式:ftp [-v][-d][-i][-n][-g][-s:filename][-a][-w:windowsize][c omputer] 说说他们的含义吧。 -v 不显示远程服务器响应 -n 禁止第一次连接的时候自动登陆 -i 在多个文件传输期间关闭交互提示 -d 允许调试、显示客户机和服务器之间传递的全部ftp命令 -g 不允许使用文件名通配符,文件名通配符的意思是说允许在本地文件以及路径名中使用通配字符 -s:filename 指定包含ftp命令的文本文件。在ftp命令启动后将自动运行这些命令。在加的参数里不能有空格。 -a 绑定数据连接时,使用任何的本地端口 -w:windowsize 忽略默认的4096传输缓冲区 computer 指定要连接的远程计算机的ip地址 1) ? 说明:显示ftp命令的说明。后面可以加参数,是加需要解释的命令名,不加则显示包含所有命令列表。 2) ! 说明:功能是在本地计算机上运行指定命令。 如! command 其中command就是你要运行的命令,如果不加command这个参数的话,则显示本地命令提示, 这时你输入exit命令就能返回到ftp了。 3)$ macro,ame[args] 说明:执行宏定义macro,name。 4) append 说明:使用当前文件类型设置,将本地文件附加到远程计算机中。大概格式是append local-file [remote-file] 其中local-file是说指定要添加的本地文件。remote-file是说指定要将local-file附加到远程计算机文件,要是省了这个,则是使用本地文件名做远程文件名。 5)account[password] 说明:提供登录远程系统成功后访问系统资源所需的补充口令。 6)ascii 说明:默认情况下,将文件传输类型设置为ASCII 7)bell 说明:响玲开关,意思是文件传输完成后是否有玲声提醒。默认是关闭的。 8)binary 说明:将文件传输类型设置为二进制。 9)bye 说明:结束和远程计算机的ftp会话,也就是安全断开,退出ftp. 10)cd 说明:更改远程计算机上的工作目录。 如cd data 其中data是要进入的远程计算机的目录。 12)cdup 说明:进入远程主机目录的父目录。 13)chmod modefile,name 说明:将远程主机文件file,name的存取方式设置为mode。 如 chmod 777 a.out。 14)cr 说明:使用asscii方式传输文件时,将回车换行转换为回行。 15)close 说明:结束与远程服务器的ftp会话,并返回命令解释程序。 16)dir 说明:显示远程的文件以及子目录列表。 如dir data local-file其中data是指定要查看列表的目录,没指定的话就是当前目录。local-file 是指定要保存列表的本地文件,不指定的话就在屏幕输出。 17)debug 说明:调试开关,打开的时候打印每个发送到远程计算机的命令,命令前有——>默认情况是关闭的。 18)disconnnect 说明:与远程计算机断开连接,但还保持着ftp命令提示符。 19)delete remote,file 说明:删除远程主机文件。 20)disconnection 说明:同close。 21)form format 说明:将文件传输方式设置为format,缺省为file方式。 22)get 说明:使用当前文件传输类型,把远程的文件拷贝到本地计算机上。 如get remote-file local-fileremote-file是指定要复制的文件,local-file是指定本地计算机上的文件名,没有指定的话则个remote-file同名。 23)glob 说明:文件名通配开关 24)hash 说明:转换每个传输数据快的散列标记打印(#).数据快的大小是2048字节。默认情况下是关闭的, 25)help 说明:显示ftp命令的解释,如help commmand 其中command就是你要解释的命令,如果不加command这个参数的话就会显示所有命令的列表 26)idle[seconds] 说明:将远程服务器的休眠计时器设为[seconds]秒。 27)image 说明:设置二进制传输方式(同binary) 28)lcd 说明:更改本地计算机的本地目录,在默认的时候是启动ftp的目录.这个不要觉得没用啊,在你使用ftp的时候为了传递文件不是常改变本地和远程计算机的目录吗? 如lcd [directory] 其中[directory]是指定要进入的本地计算机的目录,如果你不加这个参数,就会显示出本地计算机的工作目录. 29)literal 说明:向远程ftp服务器发送协商参数,报告. 如lireral argument [...] 其中argument是指定要发送给远程服务器的协商参数。 30)ls 说明:显示远程目录的文件和字目录. 如ls remote-directory local-file其中remote-directory是指要查看的列表的目录,不指定的话显示的是当前工作目录。local-file是指定要保存列表的本地文件.不指定的话是在屏幕上输出. 11 Shell基本命令 11.1 ls 列出目录下的文件,不同类型的文件颜色不同,例 如蓝色是文件夹,白色是文件 [root@restoretmp steph]# ls file.html public_html test [root@restoretmp steph]# 参数: ls -a 列出所有文件,包括隐藏文件 [root@restoretmp steph]# ls -a . .. .bash_logout .bash_profile .bashrc file.html public_html test [root@restoretmp steph]# ls -l 列出所有者 size 文件权限 修改日期 ls -R 递归列出所有子目录的内容 11.2 cd 转移目录 cd /home/steph 将转移到/home/steph cd .. 上移一个目录 cd 回到根目录 cd dir 改变目录位置至d i r目录下。 cd user 改变目录位置至用户的工作目录。 cd .. 改变目录位置至当前目录的父目录。 cd ../user 改变目录位置至相对路径 user 的目录下。 cd /../.. 改变目录位置至绝对路径的目录位置下。 11.3 建立新文件和文件夹 touch new-filename 建立新文件 mkdir new-directory 建立新目录 11.4 删除文件和目录 rm -r filename 删除名为 filename的文件 rmdir foldername 删除名为foldername的目录 rm –r file? 删除文件名中有五个字符且前四个字符为file 的所有文件。 rm –r f* 删除文件名中以 f 为字首的所有文件。 11.5 修改文件夹权限 1. 改变文件或目录的读、写、执行权限 语法:chmod [-R] mode name name :文件名或目录名。 mode: 3个8位数字或r w x的组合。r- read (读),w - wri te (写),x - execute (执行),u - user (当前用户),g - group(组) ,o - other(其他用户) 。 chmod 755 dir1对于目录dir1,设定成任何使用者皆有读取及执行的权利,但只有所有者可做修改。 chmod 700 file1 对于文件f i l e 1,设定只有所有者可以读、写和执行的权利。 chmod u+x file2 对于文件f i l e 2,增加当前用户可以执行的权利。 chmod g+x file3 对于文件f i l e 3,增加工作组使用者可执行的权利。 chmod o-r file4 对于文件f i l e 4,删除其他使用者可读取的权利。 2(改变文件或目录的所有权 语法:chown [-R] 用户名 name name:文件名或目录名。 例如 : chown user file1 将文件 file1 改为用户user 所有。 chown -R user dir1 将目录 d i r 1及其子目录下面的所有文件改为用户user 所有。 11.6 压缩和解压缩文件gzip 和 gunzip 压缩: gzip filename 文件即会被压缩,并被保存为 filename.gz 解压缩: gunzip filename.gz filename.gz 会被删除,而继之以 filename 可以通过命令man gip 和man gunzip获得命令的详细说明. zip 和 unzip 要使用 zip 来压缩文件,在 shell 提示下键入下面的命令: zip -r filename.zip filesdir 在这个例子里,filename.zip 代表你创建的文件,filesdir 代表你想放置新 zip 文件的目录。-r 选项指定你想递归地(recursively)包括所有包括在 filesdir 目录中的文件。 要解压缩 zip 文件的内容,键入以下命令: unzip filename.zip 你可以使用 zip 命令同时处理多个文件和目录,方法是将它们逐一列出,并用空格间隔: zip -r filename.zip file1 file2 file3 /usr/work/school 上面的命令把 file1、file2、 file3、以及 /usr/work/school 目录的内容(假设这个目录存在)压缩起来,然后放入 filename.zip 文件中。 11.7 tar 把多个文件或目录打包成一个文件,或者把已经 打包的文件展开 %tar cvf RMS RMStar 把目录打包成一个文件 %tar xvf RMStar 把打包的文件展开。 11.8 compress 把文件压缩成后缀为.Z的压缩文件 %compress RMStar uncompress 把后缀为.Z的压缩文件解压缩 %uncompress RMStar.Z 11.9 df -k 查看各文件系统剩余的空间,-k说明单位是千字 节(kb) 11.10 使用 l o g o u t命令退出shell。 11.11 更改帐号密码 语法:passwd Old password: <输入旧密码> New password: <输入新密码〉 Retype new password: <再输入一次密码> 11.12 联机帮助 语法: man 命令 man ls 11.13 远程登录 语法:rlogin 主机名 [-l 用户名] rlogin aa 远程登录到工作站 aa 中。 rlogin aa -l user 使用 user 帐号登录到工作站 aa 中。 语法:telnet 主机名 或 telnet IP地址 telnet aa telnet 130.129.21.250 11.14 复制文件 语法: cp [-r] 源地址 目的地址 cp file1 file2 将文件 file1 复制成 f i l e 2。 cp file1 dir1 将文件 file1 复制到目录 dir1 下,文件名仍为 f i l e 1。 cp /tmp/file1 . 将目录 /tmp 下的文件 file1 复制到当前目录下,文件名仍为 f i l e 1。 cp /tmp/file1 file2 将目录 /tmp 下的文件 file1 复制到当前目录下,文件名为f i l e 2。 cp -r dir1 dir2 复制整个目录。 11.15 移动或更改文件、目录名称 语法:mv 源地址 目的地址 mv file1 dir1 将文件 f i l e 1移到目录 dir1 下,文件名仍为 f i l e 1。 mv dir1 dir2 将目录 dir1 更改为目录 d i r 2。 11.16 列出当前所在的目录位置 语法: pwd 11.17 查看文件内容 语法: cat文件名 cat file1以连续显示方式,查看文件名 file1 的内容。 11.18 分页查看文件内容 语法: more 文件名 或 cat 文件名 | more more file1 以分页方式查看文件名 file1 的内容。 cat file1 | more 以分页方式查看文件名 file1 的内容。 11.19 查看目录所占磁盘容量 语法: du [-s] 目录 du dir1 显示目录 dir1 的总容量及其子目录的容量(以KB 为单位)。 du -s dir1 显示目录 dir1 的总容量。 11.20 检查自己所属的工作组名称 语法:groups 11.21 改变文件或目录工作组所有权 语法:chgrp [-R] 工作组名 name name:文件名或目录名 chgrp vlsi file1 将文件 file1 的工作组所有权改为 vlsi 工作组所有。 chgrp -R image dir1 将目录d i r 1及其子目录下面的所有文件,改为 image 工作组所有。 11.22 改变文件或目录的最后修改时间 语法:touch name name:文件名或目录名。 11.23 文件的链接 同一文件,可拥有一个以上的名称,也就是把一个文件进行链接。 语法:ln 老文件名 新文件名 例如 : ln file1 file2 将文件 f i l e 2链接至文件 f i l e 1。 语法:ln -s 老文件名 新文件名 例如 : ln -s file3 file4 将文件 file4 链接至文件f i l e 3。 11.24 文件中字符串的查寻 语法:grep string file grep abc file1 寻找文件f i l e 1中包含字符串 abc 所在行的文本内容。 11.25 查寻文件或命令的路径 语法:whereis command 显示命令的路径。 语法:which command 显示命令的路径,及使用者所定义的别名。 语法:whatis command 显示命令功能的摘要。 语法:find search-path -name filename -print 搜寻指定路径下某文件的路径 。 例如 : find / -name file1 -print 自根目录下寻找文件 file1 的路径。 11.26 比较文件或目录的内容 语法:diff [-r] name1 name2 name1 name2:可同时为文件名或目录名。 diff file1 file2 比较文件file1 与 file2 内各行的不同之处。 diff -r dir1 dir2 比较目录 dir1 与 dir2 内各文件的不同之处。 11.27 文件打印输出 用户可用 .login 文件中的 setenv PRINTER来设定打印机名。 setenv PRINTER sp 设定自sp打印机打印资料。 一般文件的打印 语法:lpr [-P打印机名] 文件名 例如: lpr file1 或 lpr -Psp file1 自 s p打印机打印文件 f i l e 1。 语法:enscript [-P打印机名] 文件名 例如: enscript file3 或 enscript -Psp file3 自 s p打印机打印文件 f i l e 3。 11.28 troff 文件的打印 语法:p t r o ff [-P打印机名] [-man][-ms] 文件名 例如: ptroff -Psp -man /usr/man/man1/lpr1 以troff 格式,自 sp 打印机打印lpr1 命令的使用说明。 打印机控制命令 1(检查打印机状态、打印作业顺序号和用户名 语法:lpq [-P打印机名] lpq 或 lpq -Psp 检查 sp 打印机的状态。 2. 删除打印机内的打印作业( 用户仅可删除自己的打印作业 ) 语法:lprm [-P打印机名] 用户名 或 作业编号 lprm user或lprm -Psp user 删除s p打印机中用户user 的打印作业,此时用户名必须为u s e r。 lprm -Psp 456 删除 sp 打印机上编号为 456 的打印作业。 11.29 进程控制 1(查看系统中的进程 语法:ps [-aux] 例如: p s或ps -x 查看系统中,属于自己的进程。 ps -au 查看系统中,所有用户的进程。 ps -aux 查看系统中,包含系统内部的及所有用户的进程。 2. 结束或终止进程 语法:kill [-9] PID PID:利用 ps 命令所查出的进程号。 例如: kill 456或kill -9 456 终止进程号为456的进程。 3. 在后台执行进程的方式 语法:命令 & cc file1.c & 将编译 file1.c 文件的工作置于后台执行。 语法:按下 C o n t r o l + Z键,暂停正在执行的进程。键入b g命令,将暂停的进程置于后台继续执行。 cc file2.c ^ Z S t o p p e d b g 4. 查看正在后台中执行的进程 语法:j o b s 5. 结束或终止后台中的进程 语法:kill %n n:利用j o b s命令查看出的后台作业号 kill % 终止在后台中的第一个进程。 kill %2 终止在后台中的第二个进程。 11.30 shell变量 1. 查看shell变量的设定值 语法:set 查看所有shell变量的设定值。 语法:echo $变量名 显示指定的shell变量的设定值。 2. 设定shell变量 语法:set var = value set term="vt100" 设定shell变量 term为VT100型终端。 3. 删除shell变量 语法:unset var unset PRINTER 删除shell变量 PRINTER 的设定值。 11.31 别名 1. 查看所定义的命令的别名 语法: alias 查看自己目前定义的所有命令,及所对应的别名。 语法: alias name 查看指定的name 命令的别名。 alias dir 查看别名dir所定义的命令。 ls -atl 2. 定义命令的别名 语法: alias name?command line‘ 例如: alias dir ?ls -l‘ 将命令 ls - l 定义别名为 d i r。 3. 删除所定义的别名 语法: unalias name 例如: unalias dir 删除别名 dir 的定义。 unalias * 删除所有别名的设定。 11.32 历史命令 1. 设定命令记录表的长度 语法: set history = n set history = 40 设定命令记录表的长度为 40 (可记录执行过的前面 40 个 命令)。 2. 查看命令记录表的内容 语法: h i s t o r y 3. 使用命令记录表 语法: !! 重复执行前一个命令。 语法: ! n n:命令记录表的命令编号。 语法: ! s t r i n g 重复前面执行过的以 string 为起始字符串的命令。 例如: ! c a t 重复前面执行过的以 cat 为起始字符串的命令。 4. 显示前一个命令的内容 语法: ! !:p 5. 更改前一个命令的内容并执行 语法: ^oldstring ^newstring 将前一个命令中 oldstring 的部份改成 n e w s t r i n g并执 行。 例如: find . -name file1.c -print ^ f i l e 1 . c ^ c o r e find . -name core -print 11.33 管道命令的使用 语法:命令1 | 命令2 将命令1的执行结果送到命令2,做为命令2的输入。 例如: ls -Rl | more 以分页方式列出当前目录及其子目录下所有文件的名称。 cat file1 | more 以分页方式列出文件 file1 的内容。 11.34 输入/输出控制 1. 标准输入的控制 语法:命令 < 文件 将文件做为命令的输入。 例如: mail -s ―mail test‖ 电子邮件地址 < file1 将文件file 当做信件的内容,主 题名称为 mail test,送给收信人。 2. 标准输出的控制 语法:命令 > 文件 将命令的执行结果送至指定的文件中。 例如: ls -l > list 将执行 ―ls -l‖ 命令的结果写入文件list 中。 语法:命令>! 文件 将命令的执行结果送至指定的文件中,若文件已经存在,则覆盖。 例如: ls -lg >! list 将执行 ―ls - lg‖ 命令的结果覆盖写入文件 list 中。 语法:命令 >& 文件 将命令执行时屏幕上所产生的任何信息写入指定的文件中。 例如: cc file1.c >& error 将编译 file1.c 文件时所产生的任何信息写入文件 error 中。 语法:命令>> 文件 将命令执行的结果附加到指定的文件中。 ls - lag >> list 将执行 ―ls - lag‖ 命令的结果附加到文件 list 中。 语法:命令 >>& 文件 将命令执行时屏幕上所产生的任何信息附加到指定的文件中。 cc file2.c >>& error 将编译 file2.c 文件时屏幕所产生的任何信息附加到文件error 中。 11.35 查看系统中的用户 语法: who 或 f i n g e r 语法: w 语法: finger 用户名 或 finger 用户名@域名 改变用户名 语法: su 用户名 例如: su user 进入用户user 的帐号。 p a s s w r o d : <输入用户user 的密码> 11.36 查看用户名 语法: who am i 查看登录时的用户名。 语法: w h o a m i 查看当前的用户名。若已执行过s u命令,则显示出此用户的用 户名。 11.37 查看当前系统上所有工作站的用户 语法: rusers 按Ctrl+C> 结束 11.38 与某工作站上的用户交谈 语法: talk 用户名@主机名或talk 用户名@ I P地址 例如: 1) 可先利用 rusers 指令查看网络上的用户; 2) 假设自己的帐号是 ddd ,在工作站 aaa上使用,现在想要与 bbb 上的ccc 交谈。 talk ccc@bbb 可按Ct r l + C结束。 11.39 检查网络是否连通 语法:ping 主机名或ping IP地址 11.40 vi vi是在工作站上广泛使用的编辑软件。对初学者而言, 常因其特殊的使用方法,而不得其门而入;对已经在使用 vi 的使用者来说,也 常见因对 vi 的不熟悉或不够了解,而无法发挥出 vi 强大的编辑能力,以下将 简单介绍 vi 的使用方法。不必死记硬背,多实际操作几次就能记住常用的命令。 11.40.1 进入vi 直接执行 vi编辑程序即可: %vi test 此刻屏幕上会出现 vi 的编辑屏幕,同时 vi 会将文件复制一份至内存中的缓冲区 (buffer) 。 vi会保留在硬盘中的文件不变,而先对缓冲区的文件作编辑,编辑完成后,使用者可决定是否要取代原来旧有的文件。 11.40.2离开vi 若在输入模式下,则先利用《ESC》进入指令模式,而后即可选用下列指令 离开vi。 :q! 离开vi,并放弃刚在缓冲区内编辑的内容。 :wq 将缓冲区内的资料写入硬盘中,并离开vi。 :ZZ 同wq。 :x 同wq。 :w 将缓冲区内的资料写入硬盘中,但并不离开vi。 :q 离开vi,若文件被修改过,则会被要求确认是否放弃修改的内容。 此指令可与:w 配合使用。 11.40.3vi 的操作模式 vi 提供两种操作模式:输入模式(insert mode)和指令模式(command mode) 。当使用者进入 vi 后,即处在指令模式下,此刻键入的任何字符都被视为 指令。在此模式下可进行删除、修改等动作。若要输入资料,则需进入输入 模式。 11.40.4输入模式 如何进入输入模式 a (append) 由光标之后加入资料。 A 由该行之末加入资料。 i (insert) 由光标之前加入资料。 I 由该行之首加入资料。 o (open) 新增一行于该行之下以供输入资料。 O 新增一行于该行之上以供输入资料。 如何离开输入模式 《ESC》 结束输入模式。 11.40.5指令模式 光标的移动 h 向左移一个字符。 j 向上移一个字符。 k 向下移一个字符。 l 向右移一个字符。 0 移至该行之首 ?$ 移至该行之末。 ^ 移至该行的第一个字符处。 H 移至屏幕的第一列。 M 移至屏幕的中间那列。 L 移至屏幕的最后一列。 G 移至该文件的最后一列。 + 移至下一列的第一个字符处。 - 移至上一列的第一个字符处。 ( 移至该句之首。 (注一) ) 移至该句之末。 { 移至该段落之首。 (注二) } 移至该段落之末。 nG 移至该文件的第 n 列。 n+ 移至光标所在位置之后的第 n 列。 n- 移至光标所在位置之前的第 n 列。 会显示该行的行号、文件名称、文件中最末行的行号、光标 所在行号占总行号的百分比。 注一:句子(sentence)在vi中是指以『~』、『.』或『,』结束的一串字。 注二:段落(paragraph)在vi中是指以空白行隔开的文字。 11.40.6屏幕的移动 屏幕往下卷一页。 屏幕往上卷一页。 屏幕往下卷半页。 屏幕往上卷半页。 屏幕往下卷一行。 屏幕往上卷一行。 11.40.7删除、复制及修改指令介绍 (此单元较少使用) d(delete)、c(change)和y(yank)这一类的指令在 vi 中的指令格式为: Operator + Scope = command (运算子) (范围) 运算子: d 删除指令。删除资料,但会将删除资料复制到内存缓冲区。 y 将资料(字组、行列、句子或段落)复制到缓冲区。 p 放置(put)指令,与 d 和 y 配和使用。可将最后delete或yank的资 料放置于光标所在位置的行列下。 c 修改(change)指令,类似delete与insert的组合。删除一个词组、句 子等的资料,并插入新输入的资料。 范围: e 由光标所在位置至该字符串的最后一个字符。 w 由光标所在位置至下一个字符串的第一个字符。 b 由光标所在位置至前一个字符串的第一个字符。 ?$ 由光标所在位置至该行的最后一个字符。 0 由光标所在位置至该行的第一个字符。 ) 由光标所在位置至下一个句子的第一个字符。 ( 由光标所在位置至该句子的第一个字符。 { 由光标所在位置至该段落的最后一个字符。 } 由光标所在位置至该段落的第一个字符。 11.40.8整行动作 dd 删除整行。 D 以行为单位,删除光标后的所有字符。 cc 修改整行的内容。 yy yank整行,使光标所在该行复制到内存缓冲区。 11.40.9删除与修改 x 删除光标所在该字符。 X 删除光标所在之前一字符。 dd 删除光标所在该行。 r 用接于此指令之后的字符取代(replace)光标所在字符。 如: ra 将光标所在字符以 a 取代之。 R 进入取代状态,直到《ESC》为止。 s 删除光标所在的字符,并进入输入模式直到《ESC》。 S 删除光标所在的该行资料,并进入输入模式直到《ESC》。 11.40.10 移动与复制 利用 delete 及 put 指令可完成资料移动的目的。 利用 yank 及 put 指令可完成资料复制的目的。 yank 和 delete 可将指定的资料复制到内存缓冲区,而通过 put 指令 可将缓冲区内的资料复制到屏幕上。 例: 移动一行 (在该行执行 dd (光标移至目的地 (执行 p 复制一行 (在该行执行 yy (光标移至目的地 (执行 p 11.40.11 指令重复 在指令模式中,可在指令前面加入一数字 n,则此指令动作会重复执行 n 次。 例: 删除10行 (10dd 复制10行 (10yy (光标移至目的地 (p 指标往下移10行 (10j 取消前一动作(Undo) 即复原执行上一指令前的内容。 u 恢复最后一个指令之前的结果。 U 恢复光标该行的所有改变。 11.40.12 查找 在vi中可查找某一字符串,使光标移至该处。 /字符串 往光标之后寻找该字符串。 ?字符串 往光标之前寻找该字符串。 n 往下继续寻找下一个相同的字符串。 N 往上继续寻找下一个相同的字符串。 11.40.13 资料的连接 J 句子的连接。将光标所在的下一行连接至光标该行的后面。 若某行资料太长亦可将其分成两行,只要将光标移至分开点,进入输入模式 (可利用 a、i等指令)再按《Enter》即可。 环境的设定 :set nu 设定资料的行号。 :set nonu 取消行号设定。 :set ai 自动内缩。 :set noai 取消自动内缩。 11.40.14 自动内缩(automatic indentation) 在编辑文件或程序时,有时会遇到需要内缩的状况,『:set ai』即提供自 动内缩的功能,用下例解释: (vi test ((进入编辑屏幕后) this is the test for auto indent 《Tab》start indent ? :set ai (设自动内缩) 《Tab》data 《Tab》data 《Tab》data ? :set noai (取消自动内缩) the end of auto indent. (注: 可删除《Tab》字符。 11.40.15 ex指令 读写资料 :w 将缓冲区的资料写入硬盘中。 :10,20w test 将第10行至第20行的资料写入test文件。 :10,20w>>test 将第10行至第20行的资料加在test文件之后。 :r test 将test文件的资料读入编辑缓冲区的最后。 删除、复制及移动 :10,20d 删除第10行至第20行的资料。 :10d 删除第10行的资料。 :%d 删除整个编辑缓冲区。 :10,20co30 将第10行至第20行的资料复制至第30行之后。 :10,20mo30 将第10行至第20行的资料移动至第30行之后。 11.40.16 字符串搜寻与取代 s(substitute)指令可查找某行列范围。 g(global)指令则可查找整个编辑缓冲区的资料。 s指令以第一个满足该条件的字符串为其取代的对象,若该行有数个满足该条 件的字符串,也仅能取代第一个,若想取代所有的字符串则需加上g参数。 :1,?$s/old/new/g 将文件中所有的『old』改成『new』。 :10,20s/^/ / 将第10行至第20行资料的最前面插入5个空白。 :%s/old/new/g 将编辑缓冲区中所有的『old』改成『new』。 11.40.17 恢复编辑时被中断的文件 在编辑过程中,若系统当掉或连线中断,而缓冲区的资料并还未 被写回硬盘时,当再次回到系统,执行下列指令即可回复中断前 的文件内容。 %vi -r filename 编辑多个文件 vi还提供同时编辑多个文件的功能,方法如下: %vi file1 file2 .. 当第一个文件编辑完成后,可利用『:w』将该缓冲区存档,而后 再利用 『:n』载入下一个文件。 12 使用 sed 编辑器 sed 编辑器是 Linux 系统管理员的工具包中最有用的资产之一, 因此,有必要彻底地了解其应用 Linux 操作系统最大的一个好处是它带有各种各样的实用工具。存在如此之多不同的实用工具,几乎不可能知道并了解所有这些工具。可以简化关键情况下操作的一个实用工具是 sed。它是任何管理员的工具包中最强大的工具之一,并且可以证明它自己在关键情况下非常有价值。 sed 实用工具是一个“编辑器”,但它与其它大多数编辑器不同。除了不面向屏幕之外,它还是非交互式的。这意味着您必须将要对数据执行的命令插入到命令行或要处理的脚本中。当显示它时,请忘记您在使用 Microsoft Word 或其它大多数编辑器时拥有的交互式编辑文件功能。sed 在一个文件(或文件集)中非交互式、并且不加询问地接收一系列的命令并执行它们。因而,它流经文本就如同水流经溪流一样,因而 sed 恰当地代表了流编辑器。它可以用来将所有出现的 "Mr. Smyth" 修改为 "Mr. Smith",或将 "tiger cub" 修改为 "wolf cub"。流编辑器非常适合于执行重复的编辑,这种重复编辑如果由人工完成将花费大量的时间。其参数可能和一次性使用一个简单的操作所需的参数一样有限,或者和一个具有成千上万行要进行编辑修改的脚本文件一样复杂。sed 是 Linux 和 UNIX 工具箱中最有用的工具之一,且使用的参数非常少。 sed 的工作方式 sed 实用工具按顺序逐行将文件读入到内存中。然后,它执行为该行指定的所有操作,并在完成请求的修改之后将该行放回到内存中,以将其转储至终端。完成了这一行上的所有操作之后,它读取文件的下一行,然后重复该过程直到它完成该文件。如同前面所提到的,默认输出是将每一行的内容输出到屏幕上。在这里,开始涉及到两个重要的因素—首先,输出可以被重定向到另一文件中,以保存变化;第二,源文件(默认地)保持不被修改。sed 默认读取整个文件并对其中的每一行进行修改。不过,可以按需要将操作限制在指定的行上。 该实用工具的语法为: sed [options] '{command}' [filename] 在这篇文章中,我们将浏览最常用的命令和选项,并演示它们如何工作,以及它们适于在何处使用。 替换命令 sed 实用工具以及其它任何类似的编辑器的最常用的命令之一是用一个值替换另一个值。用来实现这一目的的操作的命令部分语法是: 's/{old value}/{new value}/' 因而,下面演示了如何非常简单地将 "tiger" 修改为 "wolf": $ echo The tiger cubs will meet on Tuesday after school | sed 's/tiger/wolf/' The wolf cubs will meet on Tuesday after school $ 注意如果输入是源自之前的命令输出,则不需要指定文件名—同样的原则也适用于 awk、sort 和其它大多数 Linux\UNIX 命令行实用工具程序。 多次修改 如果需要对同一文件或行作多次修改,可以有三种方法来实现它。第一种是使用 "-e" 选项,它通知程序使用了多条编辑命令。例如: $ echo The tiger cubs will meet on Tuesday after school | sed -e ' s/tiger/wolf/' -e 's/after/before/' The wolf cubs will meet on Tuesday before school $ 这是实现它的非常复杂的方法,因此 "-e" 选项不常被大范围使用。更好的方法是用分号来分隔命令: $ echo The tiger cubs will meet on Tuesday after school | sed ' s/tiger/wolf/; s/after/before/' The wolf cubs will meet on Tuesday before school $ 注意分号必须是紧跟斜线之后的下一个字符。如果两者之间有一个空格,操作将不能成功完成,并返回一条错误消息。这两种方法都很好,但许多管理员更喜欢 另一种方法。要注意的一个关键问题是,两个撇号 (' ') 之间的全部内容都被 解释为 sed 命令。直到您输入了第二个撇号,读入这些命令的 shell 程序才会 认为您完成了输入。这意味着可以在多行上输入命令—同时 Linux 将提示符从 PS1 变为一个延续提示符(通常为 ">")—直到输入了第二个撇号。一旦输入了 第二个撇号,并且按下了 Enter 键,则处理就进行并产生相同的结果,如下所 示: $ echo The tiger cubs will meet on Tuesday after school | sed ' > s/tiger/wolf/ > s/after/before/' The wolf cubs will meet on Tuesday before school $ 全局修改 让我们开始一次看似简单的编辑。假定在要修改的消息中出现了多次要修改的项 目。默认方式下,结果可能和预期的有所不同,如下所示: $ echo The tiger cubs will meet this Tuesday at the same time as the meeting last Tuesday | sed 's/Tuesday/Thursday/' The tiger cubs will meet this Thursday at the same time as the meeting last Tuesday $ 与将出现的每个 "Tuesday" 修改为 "Thursday" 相反,sed 编辑器在找到一个 要修改的项目并作了修改之后继续处理下一行,而不读整行。sed 命令功能大体 上类似于替换命令,这意味着它们都处理每一行中出现的第一个选定序列。为了 替换出现的每一个项目,在同一行中出现多个要替换的项目的情况下,您必须指 定在全局进行该操作: $ echo The tiger cubs will meet this Tuesday at the same time as the meeting last Tuesday | sed 's/Tuesday/Thursday/g' The tiger cubs will meet this Thursday at the same time as the meeting last Thursday $ 请记住不管您要查找的序列是否仅包含一个字符或词组,这种对全局化的要求都是必需的。 sed 还可以用来修改记录字段分隔符。例如,以下命令将把所有的 tab 修改为空格: sed 's/ / /g' 其中,第一组斜线之间的项目是一个 tab,而第二组斜线之间的项目是一个空格。作为一条通用的规则,sed 可以用来将任意的可打印字符修改为任意其它的可打印字符。如果您想将不可打印字符修改为可打印字符—例如,铃铛修改为单词 "bell"—sed 不是适于完成这项工作的工具(但 tr 是)。 有时,您不想修改在一个文件中出现的所有指定项目。有时,您只想在满足某些条件时才作修改—例如,在与其它一些数据匹配之后才作修改。为了说明这一点,请考虑以下文本文件: $ cat sample_one one 1 two 1 three 1 one 1 two 1 two 1 three 1 $ 假定希望用 "2" 来替换 "1",但仅在单词 "two" 之后才作替换,而不是每一行的所有位置。通过指定在给出替换命令之前必须存在一次匹配,可以实现这一点: $ sed '/two/ s/1/2/' sample_one one 1 two 2 three 1 one 1 two 2 two 2 three 1 $ 现在,使其更加准确: $ sed ' > /two/ s/1/2/ > /three/ s/1/3/' sample_one one 1 two 2 three 3 one 1 two 2 two 2 three 3 $ 请再次记住唯一改变了的是显示。如果您查看源文件,您将发现它始终保持不变。您必须将输出保存至另一个文件,以实现永久保存。值得重复的是,不对源文件作修改实际是祸中有福—它让您能够对文件进行试验而不会造成任何实际的损害,直到让正确命令以您预期和希望的方式进行工作。 以下命令将修改后的输出保存至一个新的文件: $ sed ' > /two/ s/1/2/ > /three/ s/1/3/' sample_one > sample_two 该输出文件将所有修改合并在其中,并且这些修改通常将在屏幕上显示。现在可以用 head、cat 或任意其它类似的实用工具来进行查看。 脚本文件 sed 工具允许您创建一个脚本文件,其中包含从该文件而不是在命令行进行处理的命令,并且 sed 工具通过 "-f" 选项来引用。通过创建一个脚本文件,您能够一次又一次地重复运行相同的操作,并指定比每次希望从命令行进行处理的操作详细得多的操作。 考虑以下脚本文件: $ cat sedlist /two/ s/1/2/ /three/ s/1/3/ $ 现在可以在数据文件上使用脚本文件,获得和我们之前看到的相同的结果: $ sed -f sedlist sample_one one 1 two 2 three 3 one 1 two 2 two 2 three 3 $ 注意当调用 "-f" 选项时,在源文件内或命令行中不使用撇号。脚本文件,也称为源文件,对于想重复多次的操作和从命令行运行可能出错的复杂命令很有价值。编辑源文件并修改一个字符比在命令行中重新输入一条多行的项目要容易得多。 限制行 编辑器默认查看输入到流编辑器中的每一行,且默认在输入到流编辑器中的每一行上进行编辑。这可以通过在发出命令之前指定约束条件来进行修改。例如,只在此示例文件的输出的第 5 和第 6 行中用 "2" 来替换 "1",命令将为: $ sed '5,6 s/1/2/' sample_one one 1 two 1 three 1 one 1 two 2 two 2 three 1 $ 在这种情况下,因为要修改的行是专门指定的,所以不需要替换命令。因此,您可以灵活地根据匹配准则(可以是行号或一种匹配模式)来选择要修改哪些行(从根本上限制修改)。 禁止显示 sed 默认将来自源文件的每一行显示到屏幕上(或重定向到一个文件中),而无论该行是否受到编辑操作的影响,"-n" 参数覆盖了这一操作。"-n" 覆盖了所有的显示,并且不显示任何一行,而无论它们是否被编辑操作修改。例如: $ sed -n -f sedlist sample_one $ $ sed -n -f sedlist sample_one > sample_two $ cat sample_two $ 在第一个示例中,屏幕上不显示任何东西。在第二个示例中,不修改任何东西,因此不将任何东西写到新的文件中—它最后是空的。这不是否定了编辑的全部目的吗,为什么这是有用的,它是有用的仅因为 "-n" 选项能够被一条显示命令 (-p) 覆盖。为了说明这一点,假定现在像下面这样对脚本文件进行了修改: $ cat sedlist /two/ s/1/2/p /three/ s/1/3/p $ 然后下面是运行它的结果: $ sed -n -f sedlist sample_one two 2 three 3 two 2 two 2 three 3 $ 保持不变的行全部不被显示。只有受到编辑操作影响的行被显示了。在这种方式下,可以仅取出这些行,进行修改,然后把它们放到一个单独的文件中: $ sed -n -f sedlist sample_one > sample_two $ $ cat sample_two two 2 three 3 two 2 two 2 three 3 $ 利用它的另一种方法是只显示一定数量的行。例如,只显示 2-6 行,同时不做其它的编辑修改: $ sed -n '2,6p' sample_one two 1 three 1 one 1 two 1 two 1 $ 其它所有的行被忽略,只有 2-6 行作为输出显示。这是一项出色的功能,其它任何工具都不能容易地实现。Head 将显示一个文件的顶部,而 tail 将显示一个文件的底部,但 sed 允许从任意位置取出想要的任意内容。 删除行 用一个值替换另一个值远非流编辑器可以执行的唯一功能。它还具有许多的潜在功能,在我看来第二种最常用的功能是删除。删除与替换的工作方式相同,只是它删除指定的行(如果您想要删除一个单词而不是一行,不要考虑删除,而应考虑用空的内容来替换它—s/cat//)。 该命令的语法是: '{what to find} d' 从 sample_one 文件中删除包含 "two" 的所有行: $ sed '/two/ d' sample_one one 1 three 1 one 1 three 1 $ 从显示屏中删除前三行,而不管它们的内容是什么: $ sed '1,3 d' sample_one one 1 two 1 two 1 three 1 $ 只显示剩下的行,前三行不在显示屏中出现。对于流编辑器,一般当它们涉及到全局表达式时,特别是应用于删除操作时,有几点要记住: 1. 上三角号 (^) 表示一行的开始,因此,如果 "two" 是该行的头三个字符, 则 2. sed '/^two/ d' sample_one 将只删除该行。 3. 美元符号 ($) 代表文件的结尾,或一行的结尾,因此,如果 "two" 是该 行的最后三个字符,则 4. sed '/two$/ d' sample_one 将只删除该行。 将这两者结合在一起的结果: sed '/^$/ d' {filename} 删除文件中的所有空白行。例如,以下命令将 "1" 替换为 "2",以及将 "1" 替 换为 "3",并删除文件中所有尾随的空行: $ sed '/two/ s/1/2/; /three/ s/1/3/; /^$/ d' sample_one one 1 two 1 three 1 one 1 two 2 two 2 three 1 $ 其通常的用途是删除一个标题。以下命令将删除文件中所有的行,从第一行直到 第一个空行: sed '1,/^$/ d' {filename} 添加和插入文本 可以结合使用 sed 和 "a" 选项将文本添加到一个文件的末尾。实现方法如下: $ sed '$a\ > This is where we stop\ > the test' sample_one one 1 two 1 three 1 one 1 two 1 two 1 three 1 This is where we stop the test $ 在该命令中,美元符号 ($) 表示文本将被添加到文件的末尾。反斜线 (\) 是必需的,它表示将插入一个回车符。如果它们被遗漏了,则将导致一个错误,显示 该命令是错乱的;在任何要输入回车的地方您必须使用反斜线。 要将这些行添加到第 4 和第 5 个位置而不是末尾,则命令变为: $ sed '3a\ > This is where we stop\ > the test' sample_one one 1 two 1 three 1 This is where we stop the test one 1 two 1 two 1 three 1 $ 这将文本添加到第 3 行之后。和几乎所有的编辑器一样,您可以选择插入而不是添加(如果您希望这样的话)。这两者的区别是添加跟在指定的行之后,而插 入从指定的行开始。当用插入来代替添加时,只需用 "i" 来代替 "a",如下所示: $ sed '3i\ > This is where we stop\ > the test' sample_one one 1 two 1 This is where we stop the test three 1 one 1 two 1 two 1 three 1 $ 新的文本出现在输出的中间位置,而处理通常在指定的操作执行以后继续进行。 读写文件 重定向输出的功能已经演示过了,但需要指出的是,在编辑命令运行期间可以同步地读入和写出文件。例如,执行替换,并将 1-3 行写到名称为 sample_three 的文件中: $ sed ' > /two/ s/1/2/ > /three/ s/1/3/ > 1,3 w sample_three' sample_one one 1 two 2 three 3 one 1 two 2 two 2 three 3 $ $ cat sample_three one 1 two 2 three 3 $ 由于为 w (write) 命令指定了 "1,3",所以只有指定的行被写到了新文件中。无论被写的是哪些行,所有的行都在默认输出中显示。 修改命令 除了替换项目之外,还可以将行从一个值修改为另一个值。要记住的是,替换是对字符逐个进行,而修改功能与删除类似,它影响整行: $ sed '/two/ c\ > We are no longer using two' sample_one one 1 We are no longer using two three 1 one 1 We are no longer using two We are no longer using two three 1 $ 修改命令与替换的工作方式很相似,但在范围上要更大些—将一个项目完全替换为另一个项目,而无论字符内容或上下文。夸张一点讲,当使用替换时,只有字符 "1" 被字符 "2" 替换,而当使用修改时,原来的整行将被修改。在两种情况下,要寻找的匹配条件都仅为 "two"。 修改全部但„„ 对于大多数 sed 命令,详细说明各种功能要进行何种修改。利用感叹号,可以在除指定位置之外的任何地方执行修改—与默认的操作完全相反。 例如,要删除包含单词 "two" 的所有行,操作为: $ sed '/two/ d' sample_one one 1 three 1 one 1 three 1 $ 而要删除除包含单词 "two" 的行之外的所有行,则语法变为: $ sed '/two/ !d' sample_one two 1 two 1 two 1 $ 如果您有一个文件包含一系列项目,并且想对文件中的每个项目执行一个操作,那么首先对那些项目进行一次智能扫描并考虑将要做什么是很重要的。为了使事情变得更简单,您可以将 sed 与任意迭代例程(for、while、until)结合来实现这一目的。 比如说,假定您有一个名为 "animals" 的文件,其中包含以下项目: pig horse elephant cow dog cat 您希望运行以下例程: #mcd.ksh for I in $* do echo Old McDonald had a $I echo E-I, E-I-O done 结果将为,每一行都显示在 "Old McDonald has a" 的末尾。虽然对于这些项目的大部分这是正确的,但对于 "elephant" 项目,它有语法错误,因为结果应当为 "an elephant" 而不是 "a elephant"。利用 sed,您可以在来自 shell 文件的输出中检查这种语法错误,并通过首先创建一个命令文件来即时地更正它们: #sublist / a a/ s/ a / an / / a e/ s/ a / an / /a i/ s / a / an / /a o/ s/ a / an / /a u/ s/ a / an / 然后执行以下过程: $ sh mcd.ksh 'cat animals' | sed -f sublist 现在,在运行了 mcd 脚本之后,sed 将在输出中搜索单个字母 a (空格,"a",空格)之后紧跟了一个元音的任意位置。如果这种位置存在,它将把该序列修改为空格,"an",空格。这样就使问题更正后才显示在屏幕上,并确保各处的编辑人员在晚上可以更容易地入睡。结果是: Old McDonald had a pig E-I, E-I-O Old McDonald had a horse E-I, E-I-O Old McDonald had an elephant E-I, E-I-O Old McDonald had a cow E-I, E-I-O Old McDonald had a dog E-I, E-I-O Old McDonald had a cat E-I, E-I-O 提前退出 sed 默认读取整个文件,并只在到达末尾时才停止。不过,您可以使用退出命令提前停止处理。只能指定一条退出命令,而处理将一直持续直到满足调用退出命令的条件。 例如,仅在文件的前五行上执行替换,然后退出: $ sed ' > /two/ s/1/2/ > /three/ s/1/3/ > 5q' sample_one one 1 two 2 three 3 one 1 two 2 $ 在退出命令之前的项目可以是一个行号(如上所示),或者一条查找/匹配命令: $ sed ' > /two/ s/1/2/ > /three/ s/1/3/ > /three/q' sample_one one 1 two 2 three 3 $ 您还可以使用退出命令来查看超过一定标准数目的行,并增加比 head 中的功能更强的功能。例如,head 命令允许您指定您想要查看一个文件的前多少行—默认数为 10,但可以使用从 1 到 99 的任意一个数字。如果您想查看一个文件的前 110 行,您用 head 不能实现这一目的,但用 sed 可以: sed 110q filename 处理问题 当使用 sed 时,要记住的重要事项是它的工作方式。它的工作方式是:读入一行,在该行上执行它已知要执行的所有任务,然后继续处理下一行。每一行都受给定的每一个编辑命令的影响。 如果您的操作顺序没有十分彻底地考虑清楚,那么这可能会很麻烦。例如,假定您需要将所有的 "two" 项目修改为 "three",然后将所有的 "three" 修改为 "four": $ sed ' > /two/ s/two/three/ > /three/ s/three/four/' sample_one one 1 four 1 four 1 one 1 four 1 four 1 four 1 $ 最初读取的 "two" 被修改为 "three"。然后它满足为下一次编辑建立的准则,从而变为 "four"。最终的结果不是想要的结果—现在除了 "four" 没有别的项目了,而本来应该有 "three" 和 "four"。 当执行这种操作时,您必须非常用心地注意指定操作的方式,并按某种顺序来安排它们,使得操作之间不会互相影响。例如: $ sed ' > /three/ s/three/four/ > /two/ s/two/three/' sample_one one 1 three 1 four 1 one 1 three 1 three 1 four 1 $ 这非常有效,因为 "three" 值在 "two" 变成 "three" 之前得到修改。 标签和注释 可以在 sed 脚本文件中放置标签,这样一旦文件变得庞大,可以更容易地说明正在发生的事情。存在各种各样与这些标签相关的命令,它们包括: 1. : 冒号表示一个标签名称。例如: 接下来的步骤 2. :HERE 访问并收藏 Linux 技术中心 以冒号开始的标签可以由 "b" 和 "t" 命令处 理。 阅读 Dale Dougherty 和 Arnold Robbins 3. b {label} 充当 "goto" 语句的作用,将处理发nd的著作 sed & awk, 2 送至前面有一个冒号的标签。例如, (O'Reilly & Edition Associates 出版4. b HERE 社)。 将处理发送给行 :HERE 如果紧跟 b 之后没有指定任何标签,则处理转至脚本文件的末尾。 5. t {label} 只要自上次输入行或执行一次 "t" 命令以来进行了替换操 作,就转至该标签。和 "b" 一样,如果没有给定标签名,则处理转至脚 本文件的末尾。 6. # 符号作为一行的第一个字符将使整行被当作注释处理。注释行与标签不 同,不能使用 b 或 t 命令来转到注释行上。
本文档为【资格考试linux主要shell敕令、sed、awk应用详解】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_180829
暂无简介~
格式:doc
大小:152KB
软件:Word
页数:0
分类:互联网
上传时间:2018-02-23
浏览量:22