linux 程序,linux新手知识

  linux 程序,linux新手知识

  Linux程序

  Linux程序由两部分组成:可执行文件和脚本。可执行文件是可以由我们的计算机直接运行的程序,它们对应于。Windows下的exe程序。脚本是另一个程序的指令集,要一步一步解释。它们对应于。蝙蝠还是。Windows下的cmd文件。

  Linux下的可执行文件或脚本不需要特殊的文件名或扩展名。文件系统的属性可以用来表明它是一个可运行的程序。在Linux下,我们可以用编译后的程序替换脚本,而不会影响其他程序或调用它们的其他用户。其实两者在用户层面并没有实质性的区别。

  当我们登录Linux系统时,我们与一个Shell程序(通常是Bash)进行交互,这个Shell就像Windows下的命令行一样运行。他通过在指定的目录中搜索返回我们指定的程序名。要搜索的目录存储在名为PATH的Shell变量中。这和Windows类似。这个搜索目录(我们通常可以添加我们自己的目录)是由我们的系统管理员配置的,并且通常包含一个导致标准系统程序被存储的目录。它们通常包含以下目录:

  /bin:二进制文件,系统启动时要使用的程序。

  /usr/bin:用户二进制文件,用户可以使用的标准程序。

  /usr/local:本地二进制文件,要安装的特殊程序。

  以管理员用户(如root)身份登录时,使用的路径变量将包括系统管理程序包含的位置,如/sbin和/usr/sbin。

  可选的系统组件或第三方程序也会安装在/opt子目录下,安装程序会以用户安装脚本的形式添加到PATH变量中。

  这里要注意的是,和Unix一样,Linux中使用冒号(:)来分隔PATH变量中的项,和分号(;)不一样。例如,路径变量的以下示例:

  /usr/local/bin:/usr/bin:/bin:/usr/x11r 6/bin:/usr/games

  c编译器

  在Linux系统上,当我们使用c89、cc或gcc时,我们总是指系统的编译器,通常是GNU C编译器或gcc。在Unix系统上,C编译器通常是cc。

  让我们开始编写、编译和运行我们的第一个Linux程序。也许最好的一个是最著名的HelloWorld。

  以下是Hello.c的源代码:

  #inclue stdio.h

  int main()

  {

  printf( Hello World/n );

  退出(0);

  }

  2编译链接运行程序:

  $gcc -o Hello Hello.c

  $ ./你好

  你好世界

  $

  他是如何工作的?

  我们调用GNU C编译器将我们的C源代码转换成一个可运行的文件。当我们运行这个程序时,他会打印出一个问候语。这是最简单的程序示例,但是如果我们可以更进一步,我们可以编译和运行其他程序示例。如果这个命令不起作用,我们必须确保C编译器已经安装在我们的系统中。比如在很多Linux发行版中,有一个安装选项叫做软件开发,我们必须选择。

  因为这是我们运行的第一个程序,所以我们想指出一些东西。Hello程序通常位于我们用户的主目录中。如果我们的Shell变量不包含对用户主目录的引用,Shell将找不到这个程序。另外,如果PATH变量中的一个目录也包含一个名为Hello的程序,那么这个命令将会运行。如果PATH变量的目录位于用户的主目录之前,也会发生这种情况。为了避免这个问题,我们可以在程序前面加上一个./。这将表明Shell要执行的程序位于我们的当前目录中。

  如果我们不通过-o name选项告知生成的可执行文件的名称,编译器会将生成的可执行文件命名为a.out .(参考汇编输出)。如果我们记得我们已经编译了一个程序但是找不到,那么我们一定要记得寻找a.out文件。在Unix的早期,在系统上玩游戏的人经常以A.out的形式运行这些游戏程序,以避免被系统管理员发现,所以

  系统开发路线图

  对于一个Linux开发者来说,知道一些开发工具和资源在哪里是非常重要的。让我们在下一节看看一些重要的目录和文件。

  程序

  程序将存储在它们的目录中。系统日常使用的程序,包括程序,都位于/usr/bin目录下。系统管理员为主机或本地网络添加的程序通常位于/usr/local/bin或/opt中。

  系统管理员更喜欢/usr/local目录,因为后面添加的一些程序可以保存在这个目录下,从而实现与系统提供的程序的分离。这样保存/usr的组织很有用,这样在更新系统时只需要保留/usr/local目录中的内容。所以我们推荐的方法是把自己编译运行的程序和要访问的文件放在/usr/local目录下。

  其他功能和程序系统有自己的目录结构和程序目录。主要的是X Window系统,通常安装在/usr/X11目录下。

  头文件

  对于C或其他语言的程序,需要使用头文件来提供常量的定义以及系统和库函数调用。对于C,这些头文件位于/usr/include目录及其子目录中。我们也可以在/usr/include/sys和/usr/include/中使用它们。基于我们正在运行的linux的典型头文件可以在Linux目录中找到。其他程序系统和包含文件存储在编译器可以自动找到的目录中。比如X Window系统的头文件在/usr/include/X11目录,GNU C的头文件在/usr/include/g目录。

  我们可以通过为C编译器指定-I标志来指定包含文件是否在子目录中。例如:

  $ gcc-I/usr/open win/include Fred . c

  这将使编译器在编译fred.c文件时在/usr/openwin/include目录中查找头文件。我们还可以在C编译器的手册页中获得更详细的内容。

  我们可以使用grep命令来查找特定定义和函数原型的头文件。如果我们想知道由#define定义并用于从程序返回的退出状态的名称,我们可以简单地输入/usr/include目录并使用grep命令进行相应的搜索:

  $ grep EXIT_*。h

  在这里,grep查找所有以。h表示当前目录中的字符串EXIT\u。在这个例子中,这个命令将在文件stdlib.h中找到我们需要的定义.

  库文件

  库是为代码重用而编写的预编译函数的集合。通常,它们是用于执行共同任务的相关功能的集合。库文件的例子包括一些秘密处理函数(比如curses和ncruses库)和用于数据库访问的库(比如dbm库)。

  标准系统的库文件通常位于/lib和/usr/lib目录中。C编译器(或者更准确地说,链接器)需要被告知要查找哪些库文件。默认情况下,它只查找标准C库。这是电脑慢,CPU贵的时代遗留下来的。将库文件放在标准目录中并希望编译器能够找到它们是不够的。库文件需要遵循特定的命名约定,并由命令行指定。

  文件名通常以lib开头。文件的其余部分表明库是什么(例如,C是指C库,M是指算术库)。最后一部分从。要指示库的类型:传统的静态图书馆。so共享库

  库通常以静态和共享的形式存在。我们可以运行ls /usr/lib来查看运行结果。我们可以通过指定编译器的完整路径或使用-l标志来指定编译器查找的路径。如下例所示:

  $ gcc-o Fred Fred . c/usr/lib/libm . a

  这个命令会告诉编译器fred.c程序生成fred程序,通过同时搜索标准C库和算术库来解决函数引用的问题。我们也可以使用下面的命令来达到同样的结果:

  $ gcc -o弗雷德弗雷德. c -lm

  -lm(L和M之间没有空格)是libm.a库的缩写,位于库目录(/usr/lib)。-lm选项的另一个优点是,如果有共享库,编译器会自动选择共享库。

  虽然可以在标准位置找到头文件形式的库文件,但是我们可以使用-L选项添加另一个目录进行检查。例如:

  $ gcc-o X11 Fred-L/usr/open win/lib X11 Fred . c-lX11

  该命令将使用/usr/openwin/lib目录中的libX11版本库编译和链接x11fred程序。

  静态库:

  最简单的库格式只是一组处于备用状态的目标文件。当一个程序想要使用存储在库中的函数时,它需要包含定义这个函数的头文件。编译器和连接器可以小心地处理它,把程序代码和程序库组成一个单独的可执行程序。我们必须使用-l选项来指示除了标准C运行时之外还需要哪些库文件。

  静态库也称为文档,通常是以结尾的文件名。答:例如,标准C库与X11库/usr/lib/libc.a与/usr/X11/lib/libx11.a .

  我们可以很容易地使用ar(archive)来创建和维护自己的静态库,这样就可以使用gcc -c来编译函数。我们应该尽可能将函数放在单独的源文件中。如果函数需要访问常规数据,我们可以将它们放在同一个源文件中,并在该文件中用静态变量声明它们。

  让我们创建一个只包含两个函数的小型静态库,然后在一个例子中使用它。这个函数叫做fred和bill,它只打印问候。

  1.首先,我们分别创建名为fred.c和bill.c的源文件。下面是第一个文件:

  #包含stdio.h

  void fred(int arg)

  {

  printf(fred:您通过了%d/n ,arg);

  }

  下面是第二个:

  #包含stdio.h

  作废票据(char *arg)

  {

  printf(bill:你通过了%s/n ,arg);

  }

  我们可以分别编译这些函数来创建目标文件,这样它就可以包含在库中。我们可以通过C编译器的-c选项做到这一点,它可以防止C编译器试图创建一个完整的程序。试图创建一个完整的程序会得到一个失败消息,因为我们还没有定义主函数。

  $ gcc -c票据

  $ ls *。o

  比尔奥弗雷德奥

  现在让我们写一个程序来调用bill函数。首先,我们最好为我们的库创建一个头文件。这将在我们的库中声明该函数,并被所有想要使用我们的库的程序包含。我们最好在fred.c和bill.c文件中也包含这个头文件。这将有助于发现错误。

  /*

  *这是lib.h,它为用户声明了函数fred和bill

  */

  作废票据(char *);

  void Fred(int);

  调用程序(program.c)也相当简单。它包含这个库的头文件,并从这个库中调用它的一个函数。

  #包含“lib.h”

  int main()

  {

  比尔(‘你好世界’);

  退出(0);

  }

  现在我们可以编译这个程序并测试它。这一次,我们将展示我们将目标文件指定给编译器,以便编译器可以编译并链接我们之前编译的目标文件bill.o。

  $ cgcc -c程序

  $ cgcc -o program program.o bill.o

  $ ./程序

  比尔:我们经过了你好世界

  $

  现在让我们创建并使用这个库。我们使用ar程序创建文档,并将我们的目标文件添加到其中。这个程序被称为ar,因为它可以创建档案或收藏,并将单个文件放在一个大文件中。在这里,我们应该注意,我们可以使用ar程序来存档任何类型的文件。

  $ ar crv lib foo . a bill o Fred . o

  一张账单

  阿弗雷德

  这样,我们就创建了这个库,并向其中添加了两个目标文件。为了成功地使用这个库,一些系统,尤其是那些由Berkeley Unix开发的系统,需要为这个库创建一个目录。我们可以在这里使用ranlib命令。在Linux中,当我们使用GNU软件开发工具时,这一步是不必要的(但不是有害的)。

  $ ranlib libfoo.a

  现在我们准备好了,随时可以使用。我们可以添加一个文件列表,供编译器用来创建我们的程序,如下所示:

  $ gcc -o程序program.o libfoo.a

  $ ./程序

  比尔:你通过了“你好世界”

  $

  我们也可以使用-l选项来访问我们的库,但是因为它不是任何标准的位置,我们需要使用-L选项来告诉编译器它在哪里:

  $ gcc -o程序program.o -L. -lfoo

  这里,-L选项告诉编译器在当前目录中查找库。lfoo选项告诉编译器使用名为libfoo.a的库.

  要检查目标文件、库或可执行程序中包含哪些函数,我们可以使用nm命令。如果我们查看program和lib.a,我们可以看到库包含fred和bill函数,但程序只包含一个。当这个程序被创建时,它将只包含一个他可以从库中实际使用的函数。它包含一个头文件,声明了库中的所有函数,但最终的程序不会包含整个库文件。

  共享库

  静态库有一个缺点:如果我们想同时运行很多程序,而他们又想使用同一个库中的函数,那么我们就需要在内存中有同一个函数的多个副本,在他们的程序中也有多个副本。这将浪费大量宝贵的内存和磁盘空间。

  许多Unix和Linux系统支持共享库来解决这个问题。共享库与静态库位于同一位置,但它们有不同的文件名后缀。在典型的Linux系统上,标准数学库的共享版本是/usr/lib/libm.so .

  当一个程序想要使用共享库时,它链接共享库的方式是不包含函数代码,而是引用运行时可以访问的共享代码。当结果程序加载到内存中运行时,函数引用调用共享库,这样共享库就会在需要的时候加载到内存中。

  这样,系统只需要在磁盘上维护和保存一个共享库,可以被很多程序同时使用。共享库的另一个优点是它可以独立于依赖它的程序进行更新。需要时,使用从/usr/lib/libm.so到/usr/lib/libm.soN的系统链接。当Linux启动一个程序时,它会决定该程序所需的共享库的版本,从而阻止新版本。

  对于Linux系统,程序会小心翼翼的加载共享库,客户端程序函数引用的,需要为共享库查找的其他位置是由/etc/ld.so.conf文件配置的,有变化时需要由ldconfig生成。

  我们可以通过实用程序ldd检查一个程序所需的共享库。例如,如果我们在示例程序中运行这个程序,我们将得到以下输出:

  $ ldd计划

  libc . so . 6=/lib/libc . so . 6(0x 4002 a000)

  /lib/LD-Linux . so . 2=/lib/LD-Linux . so . 2(0x 40000000)

  在这个例子中,我们可以看到标准的C库是共享的。我们程序的要求版本是6。其他Unix系统将有类似的程序来访问共享库。我们需要检查我们的系统文档以获得更详细的信息。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: