免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1293 | 回复: 0
打印 上一主题 下一主题

GNULinux应用程序编程——第十九章: GNU/Linux命令 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-26 23:38 |只看该作者 |倒序浏览
翻译自——GNULinux应用程序编程(GNU/Linux Application Programming) by M.Tim Jones
第十九章:  GNU/Linux命令
在这一章中我们将介绍
标准输入输出和错误流
调用Shell脚本
重定向
GNU/Linux重要命令的讨论
介绍
  在这一章中,我们将学习GNU/Linux Shell的基础知识还有经常使用的重要命令。
重定向
  让我们首先来看一个在GNU/Linux Shell使用中一个基本的主题——输入输出重定向。
  重定向的概念十分的简单——将我们的输入输出重定向到非默认的事物上。例如,大多数命令的标准输出将被重定向到Shell窗口上。我们可以使用“>”——重定向标志符来重新定向一个命令的输出。
  例如:ls -la将会产生一个文件列表并将结果显示在Shell窗口上。
我们可以将这个列表重定向到一个文件上:ls -la > ls-out.txt
本来应该显示在Shell窗口上的列表被打印在了文件ls-out.txt上。
  除了可以从键盘上接收输入,我们还可以从其它源接受输入。例如:命令cat简单地显示它的标准输入(或者被命名在命令行上的文件)到它的标准输出。我们可以用”
  在这里,为了简单化我们取用它们的缩写名。描述符stdin一般来说是键盘,而stdout和stderr则为终端或者是Shell窗口(程序结果是stdout,程序错误、警告和状态则为stderr)。输出描述符被分开是为了追求向用户显示信息时的更大的弹性。虽然stdout和stderr共享着相同的默认输出设备,但是它们可以根据开发者的需要而分开。
  回想我们先前的讨论——我们可以将stdout重新定向到一个文件上。就像:
Prog > out.txt
  Prog的输出将会重新定向到文件out.txt。注意——如果我们要将我们的输出添加到out.txt而不是完全地将整个文件替换我们将使用双定向,就像:
Prog >> out.txt
  我们只能像这样重新定向出错输出:
Prog 2> err-out.txt
  注意——我们在这里使用一个常数来代表stderr。在表19.1我们展示了为我们的三个标准输入输出流描述符所定义的文件描述符。
  如果我们想要把stdout和stderr都定向到一个文件(out.txt),我们可以这么做:
Prog 1> out.txt 2>&1
表19.1:标准输入输出描述符的文件描述符
描述符 描述
0 标准输入(stdin)
1 标准输出(stdout)
2 标准出错(stderr)
  相反,我们也可以将标准输出重定向到标准出错描述符:
Prog 1>&2
  我们也可以将输出重定向到独特的文件。例如,如果我们想要将stdout定向到out.txt而stderr定向到err.txt,我们可以这么做:
Prog 1> out.txt 2> err.txt
  为了证实描述符路程安排正如我们所希望的,在清单19.1的脚本可以用来测试:
清单 19.1:描述符路程安排测试脚本
                                                                                
1:  #!/bin/bash
2:  echo “stdout test” >&1
3:  echo “stderr test” >&2
                                                                                
最后考虑其它证明重定向顺序的例子:
  Prog 2>&1 1>out.txt
在这个例子当中,我们将stderr定向到了stdout然后将stdout(不包括stderr)定向到了文件out.txt。它巩固了将stdout和stderr都定向到文件out.txt的效果。
环境变量
环境变量是一个包含被Shell和其它应用程序使用的内容的对象。存在着一系列标准环境变量,比如PWD变量,而用户可以为自己的应用程序创建自己的环境变量(或者改变业已存在的环境变量)。我们可以通过echo命令来查看PWD变量。
注意:一个进程可以看做为一个环境而且它继承了来自它父母的环境变量(比如Shell——它也是一个进程)。一个进程和脚本也可以有本地变量。
  $echo $PWD
  PWD=/home/sensen
  $
环境变量PWD能够鉴别我们当前的工作目录。我们可以通过delcare或者export这两个bash自带命令来创建我们自己的环境变量。
一个脚本可以使得子进程能够访问父进程的环境变量,但是必须输出(export)它们。一个脚本不能反输出给父进程。让我们看一看几个例子。通过特别的参数bash自带命令declare可以用来声明变量。而bash自带命令export可以创建一个变量并可以在环境中标识并传送给它的子进程。这些命令的举例说明如下:
  $declare –x myvar=”Hello”
  $echo $myvar
  Hello
  $export myothervar=”Hi”
  $echo $myothervar
  Hi
  $
GNU/Linux上存在着一系列其它十分有用的环境变量。例如:如果没有参数提供给export,它将会显示所有当前环境可访问的变量(通过命令declare和set也可以显示)。
脚本调用
当我们调用一个命令或者脚本的时候,命令和脚本必须是在我们的二进制路径(PATH环境变量)来使得它可以被发现。我们可以通过echo查看PATH环境变量来查看我们的路径:
  $echo $PATH
  /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/sensen/bin
如果我们已经创建了一个处于所定义的路径之外的脚本(比如说在我们当前工作目录),那么我们只能这么调用它:
  ./script.sh
“./”告诉命令解释器我们调用的Shell脚本位于当前目录。否则的话我们将会得到一个告诉我们脚本找不到的错误消息。
注意:两个特殊目录文件的存在在Linux开发中是十分重要的。“.”文件代表当前目录,而“..”则代表上一个目录(父目录)。例如,如果我们提供了命令cd .,结果是不会有任何改变的,因为我们将我们的当前目录改变为当前目录。而命令cd ..则改变当前目录到上一个目录。这些特殊文件可以通过命令ls –la来查看当前子目录来看到。
如果想不需要如此,我们可以更新我们的路径环境变量来添加我们的当前工作子目录:
  $export PATH=$PATH:./
  $echo $PATH
  /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/sensen/bin:./
脚本文件script.sh现在可以被直接调用而不需要添加前缀“./”。
注意:文件链接是用来提供其它文件的参照符号的特殊文件。有这样的两种链接存在:硬链接和软链接(亦被称为象征链接)。一个硬链接是指向一个已经存在的文件的在目录文件里的一个新入口。硬链接和原始文件之间是难以区别的。硬链接的问题是它们和它们所链接的对象必须是在同一个文件系统。软链接是一个一般的文件包含有一个指向一个实际文件的指针。软链接可以是绝对的(以全路径指向一个文件)或者是相对的(从当前位置开始的相对路径)。软链接是可以移动的,同时保持对原始文件的链接。注意:特殊文件“.”和“..”实际上是对绝对目录的链接。
  命令ln可以用来创建软链接。
基本GNU/Linux命令
既然我们已经懂得了基本的重定向和标准输入输出描述符(stdin,stdout和stderr),让我们来研究更多的有用的GNU/Linux命令。我们将以一个互动的方式来研究这些命令,而不是仅仅告诉你这个命令是干什么的和它的所有可用选项。这些命令没有特别的顺序,因此你可以根据你的需要来独立地研究每一个命令。
tar
GNU tar命令(Tape Archive)是一个十分有用的通用存档压缩程序。tar的目标可以是文件也可以是目录(目录的内容是被递归聚集的)。让我们来看一看对tar的使用同时研究它的多个选项。
我们可以创建一个新的存档文件:
tar cf mytar.tar mydir/
我们指定了两个选项来创建目录mydir的存档。C选项指令tar创建一个新的带有名字(通过f选项鉴别)mytar.tar的新存档。最后一个参数为文件清单和(或者)要存档的目录。
现在我们想要获取我们的tar文件(也可以叫做tarball)然后重建子目录和它的内容(也可以叫做提取选项)。我们要这么做只需简单地打上:
tar xf mytar.tar
如果我们只要知道我们的tarball的内容而不想要必须去将内容解档(unarchive),我们可以这么做:
tar tf mytar.tar
它将列出所有文件以及文件的完整目录路径。
通过添加v或者详细选项我们可以看到当tar程序工作时它的操作。对于创建和提取存档,我们可以这样使用详细选项:
tar cvf mytar.tar mydir/
tar xvf mytar.tar
tar的一个最重要的方面为对tarball的自动压缩。通过使用z选项创建和提取存档都可以自动进行:
tar czf mytar.tgz mydir/
tar xzf mytar.tgz
一个压缩的tarball需要更多的时间来创建和存档提取,但是这样同样十分有益,特别是当想要在因特网上传送一堆文件的时候。
cut
通过使用两种详细说明中的一个我们可以使用GNU/Linux cut程序快速地截掉文件中每一行的要素。用户可以通过字段表示或者编号字符序列来定义所需数据。
让我们首先来看一看cut程序的基本格式然后再通过几个例子来看一下怎么使用它。就像我们前面所说,cut程序是以两种模式来操作。在第一个模式中,cut通过一个界定字符和基于字段的详细说明来提取:
cut -f[spec] -d[delimiter] file
在第二个模式中,cut通过基于字符位置的详细说明来提取:
cut -c[spec] file
spec是一列以逗号分隔的排列。一个排列可以表格19.2所展示的来描述。
表格19.2:cut程序的排列Spec
排列 意义
n 第n个字符(-c)或者字段(-f)
n- 第n个字符(-c)或者字段(-f)(到末端为止)
n-m 从第n个字符到第m个字符(-c)或者字段(-f)
-m 从开头到m个字符(-c)或者字段(-f)
现在让我们来看一看几个cut程序的例子。我们先使用在清单19.2中的例子探讨基于字段的cut
清单19.2:基于字段的cut的例子文件(passwd)                                       
bob:x:500:500::/home/bob:/bin/bash
sally:x:501:501::/home/sally:/bin/bash
jim:x:502:502::/home/jim:/bin/tcsh
dirk:x:503:503::/home/dirk:/bin/ash                                                        
我们将用cut进行互动地实验,现在只看一看命令同时还有指定了指定说明以后cut将会产生什么。首先我们想要截掉和显示第一个字段(名字)。这是cut的一个简单的例子:
$cut –f1 –d: passwd
bob
sally
jim
dirk
$
在这个例子中,我们详细说明了使用冒号字符作为界定字符来截掉字段1(-f1)。如果我们想要知道home目录而非用户名,我们可以简单地更改字段来指向passwd的第六个字段:
$cut –f6 –d: passwd
/home/bob
/home/sally
/home/jim
/home/dirk
$
我们同样可以提取某几个字段,比如用户名(字段1)和所喜欢的Shell(字段7):
$cut –f1,7 –d: passwd
bob:/bin/bash
sally:/bin/bash
jim:/bin/tcsh
dirk:/bin/ash
$
排序对cut来说是十分重要的。例如在前面的例子当中如果我们这么指定——-f7,1,结果将会是一样的(在原文件中的段排序将会被保留)。
现在让我们来看一下指定字符位置的几个例子。在这些例子中,我们将从其它命令输送输入。命令来说列出某个目录的内容,例如:
$ls –la
Total 20
drwxrwxr-x 2 sensen  sensen  4096  Feb 17 20:08 .
drwxr-xr-x  6 sensen  sensen   4096  Feb 15 20:47 ..
-rw-rw-r--  1 sensen   sensen   6229  Feb 16 17:59 ch12.txt
-rw-r—r--  1 sensen   sensen    145  Feb 17 20:02 passwd
如果我们只对文件大小、更改日期和文件名感兴趣,我们可以这么做:
$ls –la | cut –c38-
4096  Feb  17 20:08 .
4096  Feb  15 20:47 ..
6229  Feb  16 17:59 ch12.txt
  145  Feb  17 20:02 passwd
$
如果我们只对文件的大小和名字感兴趣,那么我们可以:
$ls –la | cut –c38-42,57-
4096.
4096..
6229ch12.txt
  145passwd
$

注意:在这个例子中两个cut的结果的区域没有包括它们之间的空格。这是因为cut只是简单地分割文件的区域而不去显示这些区域之间的空格。如果我们对空格有兴趣,我们可以像下面这样来更改命令(从数据本身获取空格)
$ls –la | cut –c38-43,57-
4096 .
4096 ..
6229 ch12.txt
  145 passwd
$
程序cut是十分简单的,但是它又是一个十分有用且灵活的程序。程序cut并非唯一,稍后我们将看一看sed和awk的文字过滤和文字处理功能。

paste
命令paste是从一个或者多个文件获取数据然后将它们连接到一个新的数据流中(默认显示到stdout上)。考虑一下在清单19.3和19.4中的文件:
清单:水果文件                                                               
Apple
Orange
Banana
Papaya                                                                        
清单:工具文件                                                                 
Hammer
Pencil
Drill
Level                                                                           
使用paste程序我们可以将这些文件连接在一起:
$paste fruits.txt tools.txt
Apple Hammer
Orange  Pencil
Banana  Drill
Papaya  Level
$
如果我们并不想在我们的连贯的要素之间使用制表符而是要某个分隔符,我们可以通过使用-d选项指定新的一个。例如,我们可以使用一个:冒号来代替:
$paste –d: fruits.txt tools.txt
Apple:Hammer
Orange:Pencil
Banana:Drill
Papaya:Level
相比以垂直的方式配对连贯的要素,我们也可以通过使用-s选项用水平的方式配对它们。
$paste –s fruits.txt tools.txt
Apple  Orange  Banana  Papaya
Hammer  Pencil  Drill  Level
$
注意:如果需要的话,我们可以指定更多的文件。
现在让我们来看一看最后一个阐明paste程序的例子。回想一下我们对于cut的讨论——变更提取自于文件的字段的顺序是不可能的。下面的一个短小的脚本提供了列举文件名然后列举文件的大小的效用。
清单:19.5简单的递归的使用cut和paste的ls程序                                 
#!/bin/bash
ls –l | cut –c38-42 > /tmp/filesize.txt
ls –l | cut -57- > /tmp/filename.txt
paste /tmp/filename.txt /tmp/filesize.txt                                                
在这个例子中,我们首先从命令ls -l截掉文件的大小然后将结果保存到/tmp/filesize.txt。我们提取文件名接下来将它们保存到/tmp/filename.txt。然后,使用paste命令将结果合并起来并将顺序倒转。执行脚本,结果如下:
$./newls.sh
Fruits.txt   27
Newls.sh     133
Tools.txt   26
$
注意:既然对于临时文件来说在清单19.5中使用目录/tmp是十分有用。临时文件可以写到目录/tmp中去是因为在系统启动时/tmp目录并不保持稳固,对/tmp中的文件的清除是一个每天或者是一周一次的进程。

Sort
程序sort在以某个已定义的顺序排列中排列一个数据文件上十分有用。在最简单的状况
中,对于sort来说关键的是文件的开头,我们指定的文件。以在清单19.4中展示的文件tools.txt为例。我们可以这样简单地进行排列:
$sort tools.txt
Drill
Hammer
Level
Pencil
$
我们可以通过向命令行添加选项-r来以颠倒的顺序来排列这个文件。
我们还可以基于一个用户定义的键值来进行排列。看一下在清单19.6中的简单的文本文件。这个文件共有五行三列没有一个已经预先排列过的。
清单19.6排列所需的样品文件                                                     
5 11 eee
4  9 ddd
3 21 aaa
2 24 bbb
1  7 ccc                                                                        


为了指定一列来排序,我们可以使用-k(key)选项。key代表了
我们要求对文件进行排序的那一列。我们可以通过使用逗号分隔指定不止一个key。基于第一列进行排序,我们可以将key指定为一列(即使不这样,默认的也是一列)。
$sort –k 1 table.txt
7 ccc
24 bbb
21 aaa
9 ddd
11 eee
$
要对第二列进行排序,另一个选项被要求用来执行数字排序。在
阿拉伯数字之前的空格字符是十分重要的,因此将会排除一个数字排序。因此,我们将使用-n选项来强制执行一个数字排序。例如:
$sort –k 2 –n table.txt
7 ccc
  9 ddd
11 eee
21 aaa
24 bbb
$
万一发生空格或者制表符都没有被使用另一个十分有用的选项允许指定一个新的分隔
符。选项-t允许我们使用一个不同的分隔符——比如:-t:指定冒号字符作为字段分隔符。
find
程序find是一个功能强大但又十分复杂的程序,它允许在文件系统中基于指定的标准搜索文件。我们将举例说明一些更为有用的模式胜过去看大量过剩的find可用的选项来进行敷衍。
在当前子目录中寻找所有以.c和.h结尾的文件,可以使用下面的命令:
find . –name ‘*.[ch]’ –print
字符‘.’指定了在当前子目录中开始。选项-name的参数是指我们要搜索什么,在本例中——任何(‘*’)以c或者h结尾的文件。最后我们指定-print来显示结果到标准输出上。
对每一个搜索结果我们可以使用选项-exec来执行一个命令。这允许我们对在搜索中发现的每一个文件调用一个命令。例如,如果我们想要将所有发现的文件的文件许可改变为只读,我们可以这么做:
find . –name ‘*.[ch]’ –exec chmod 444 {} \;
通过使用修饰符type我们还可以限制文件的类型。例如,如果我们只要查看一般文件(在搜索源文件中经常发生的事情),我们可以这么做:
find . –name ‘*.[ch]’ –type f –print
选项-type的参数f代表了一般文件。我们同样可以明确为查看目录,象征链接(软链接),或者特别的设备。表格19.3提供了可用的type修饰符。
表格19.3:find可用的Type修饰符
修饰符 描述
b 块设备(block device)
c 字符设备
d 目录
p 管道(叫做FIFO)
f 一般文件
l 软链接
s 套接字(Socket)
最后一个find十分有用的功能为鉴别在一个目录中在一段时间里被更改过的文件。下面的命令(使用了mtime)鉴别在指定的时间范围(24小时的倍数)里被修改过了的文件。下面的命令将鉴别在最近的一天里被修改了的文件:
find -name ‘*’ –type f –mtime -1 –print
为了寻找在最近一星期中被修改了的文件,我们可以将mtime的参数更改为 -7。选项atime可以被用来指定最近访问的文件。而选项ctime则用来指定最近状态被改变了的文件。
wc
程序wc在计算在一个文件中的字符数,词数或者行数上是十分有用的。
下面的例子可以用来说明wc的功能:
wc -m file.txt   #Count characters in file.txt
wc -w file.txt   #Count words in file.txt
wc -l file.txt    #Count lines in file.txt
三种计算可以通过累积参数来同时输出,比如:
wc -l -w -m file.txt
无需考虑标记的顺序,输出顺序永远为行、词、字符。
grep
命令grep允许在指定的模式之下搜索一个或者多个文件。命令grep的格式是十分复杂的,但是相对简单的例子是十分有用的。让我们来谈一谈几个简单的例子然后讨论一下它们的用处。
在最简单的形式中,我们可以以一个指定的字符串来搜索一个单一文件,比如:
grep “the” file.txt
这个例子的结果是——在标准输出中显示的每一行都包含了单词-“the”。除了指定一个单一文件,我们也可以通过通配符来检查多个文件,比如:
grep “the” *.txt
在这个例子当中,命令将会以字符串“the”来搜查所有在子目录之下的以.txt结尾的文件。
当使用了通配符之后,找到匹配字符串的文件的文件名将在输出它的包含有所需字符串的行到标准输出之前先被输出到标准输出。
如果在文件中的包含有匹配字符串的行的位置十分重要的话,那么可以使用选项-n:
grep -n “the” *.txt
每一次所要搜索的字符串被找到,文件名和行号将会在行的前面显示。如果我们只对那个匹配字符串是否在文件中被找到感兴趣的话,我们可以使用选项-l来简单地输出文件名而非字符串所在的行,比如:
grep -l “the”*.txt
当我们要在某个文件中特定地搜查单词。选项-w对于限制为仅对整个词进行搜查上是十分有用的:
grep -w “he” *.txt
这个选项在我们搜查“he”的时候十分有用;我们同时还会发现单词“the”的出现。而选项-w限制了搜查仅仅对单词进行匹配,所以“the”和“there”将不会和“he”进行匹配。

总结
在这一章中,我们探索了一些在GNU/Linux Shell中的基本命令。标准输入输出描述符已经被研究过了(stdin、stdout和stderr),同时还有重定向和命令管道。我们还介绍了调用Shell脚本的方法,还包括了添加当前工作目录到默认搜索路径。最后,我们举例说明在GNU/Linux中一些十分有用的命令,包括tar(文件存档),find(文件搜索),grep(字符串搜索)以及其它十分有用的文本处理命令(cut、paste和sort)。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/6957/showart_347695.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP