《Linux程序设计》读书笔记


1、编译C程序的技巧

    在调用C语言编译器的时候可以通过给出“-I”标志来引用保存在下级子目录或者非标准目录下的头文件,如:
        $ gcc -I /usr/openwin/include fred.c
它会使编译器在/usr/openwin/include的子目录和标准目录两个地方去查找fred.c程序里所包含的头文件。

    用grep查找含有某些特定定义与函数生命的头文件是很方便的。如:
        $ grep EXIT_ *.h
grep命令会在该子目录下的所有名字以.h结尾的文件里查找字符串“EXIT_”。

2、库文件
   
标准的系统库文件一般保存在/lib或/usr/lib子目录中。库文件的名字永远以“lib”这几个字母打头,随后便是函数库说明的部分(比如用c表示
这是一个C语言函数库,用m表示一个数学运算库),文件名的最后部分以一个“.”开始,然后给出这个库文件的类型:静态函数库.a;共享函数库.so
或.sa。
    在通知编译器查找某个库文件的时候,既可以给出其完整的路径名,也可以使用“-l”标志,。如:
        $ cc -o fred fred.c /usr/lib/libm.a

        $ cc -o fred fred.c -lm
-lm代表标准目录库中名为libm.a的函数库。 更详细的解释参见下面的例子。
    虽然库文件与头文件相似,都是被保存在某个标准位置,但我们仍然可以通过“-L”标志给编译器增加搜索子目录库。如:
        $ cc -o x11fred -L/usr/openwin/lib x11fred.c -lX11
该命令在编译和链接程序x11fred时将使用在子目录/usr/openwin/lib中找到的libX11函数库版本。

    2.1 静态库(archive)
    假设现有源文件bill.c和fred.c,则建立静态库的方法:
    (1)编译源文件生成二进制目标文件,需要在调用C编译器时加上“-c”选项以防止生成最终应用程序。
        $ cc -c bill.c fred.c
    (2)为函数库建立一个头文件(lib.h),它的作用是在我们的函数库里对这两个函数进行声明;如果有程序要使用这个函数库,就必须使用include引用。
    (3)调用程序(program.c)引用库函数头文件并调用其中的函数。
    (4)使用ar工具简历档案并把目标代码加入其中。
        $ ar crv libfoo.a bill.o fred.o
  
    另外,某些系统(尤其是Berkley UNIX操作系统发展而来的系统)上,要想成功是用函数库,必须先为这个函数库建立一个内容表:
        $ ranlib libfoo.a

    可以通过使用“-L”选项告诉编译器静态库的位置:
        $ cc -o program program.o -L. -lfoo
“-L.”告诉编译器在当前子目录中查找函数库。“-lfoo”选项告诉编译器使用那个名为libfoo.a的函数库(或者一个名为libfoo.so的共享库,如果有的话)。

    可以使用nm命令查看某个目标代码文件、函数库或者可执行程序里都包含那些函数。

    2.2 共享库
   
如果一个程序使用了共享库,它的连接方式是这样的:它本身不再保存函数的代码,而只保存共享代码的调用线索,共享代码是在运行的时候才加入其中的。对
Linux系统而言,负责加载共享库并解析客户程序中函数调用线索的程序(即共享库动态加载器)是ld.so或ld-linux.so.2;查找共享库的
其他地点是在/etc/ld.so.conf文件里配置的;如果这个文件进行了修改,就需要用ldconfig命令进行处理。
    可以使用ldd程序查看某个程序要求使用的是哪一个共享库:
        $ ldd program

    .so类似于Windows中的.DLL文件,是运行时加入程序的;.sa类似于Windows中的.LIB文件,是加入到可执行文件里面的。

3 基本的Shell命令
3.1 Redirecting Output
    管道重定向:>
    对文件追加:>>
    For
">", by default, if the file already exists, then it will be
overwritten. If you want to change the default behavior, you can use
the command set -o noclobber (or set -C), which sets the noclobber option to prevent a file from being overwritten using redirection. You can cancel this option using set +o noclobber.
    For ">>", outputs are appended to the end of the file.

   
File descriptor 0 is the standard input to a program, file descriptor 1
is the standard output, and file descriptor 2 is the standard error
output. It’s unusual to want to redirect any other than the standard
ones: 0, 1, and 2.

    To redirect the
standard error output, preface the > operator with the number of the
file descriptor you wish to redirect. Because the standard error is on
file descriptor 2, use the 2> operator. This is often useful to
discard error information and prevent it from appearing on the screen.

    The command
     $ kill -HUP 1234 >killout.txt 2>killerr.txt
will put the output and error information into separate files.

    If you prefer to capture both sets of output into a single file, you can use the >& operator to combine the two outputs. Therefore,
     $ kill -1 1234 >killouterr.txt 2>&1
will
put both the output and error outputs into the same file. Notice the
order of the operators. This reads as “redirect standard output to the
file killouterr.txt, and then direct standard error to the same place
as the standard output.” If you get the order wrong, the redirect won’t
work as you expect.

3.2 Redirecting Input
    <

3.3 Pipes
    Processes connected by pipes can run simultaneously and are automatically rescheduled as data flows between them.

3.4 file command
    The best way to check if a file is a script or not is to use the file command — for example, file first or file /bin/bash.

4 Shell Scripts

P60, to be continued...