zoukankan      html  css  js  c++  java
  • debian programming guid




    Debian Reference (version 1)


    不要用“test”命名可执行的测试文件。test 是一个 shell 的内建命令。


    13.1 从哪儿开始

    参考资源:

    更详细的文档可以从GNU获得打印版本。

    接下来的四个小节中包含了用不同的编程语言编写的脚本样例,该脚本创建一个包含用户帐户信息的文本文件,调用一组进程如 newusers 程序,将这些信息加入到 /etc/passwd。每个脚本均需要一个输入文件,该文件应包含格式如 first_name last_name password 的行。(这些脚本并不创建真正的用户目录。)


    13.2 Shell

    理解类 Unix 系统如何工作的最好方法就是阅读 shell 脚本。在此,我们就 shell 编程做个简单的介绍。 参阅 Shell Mistakes 来学习更多的错误。


    13.2.1 Bash – GNU 标准交互式 shell

    Bash 参考资源:

    • bash(1)

    • info bash

    • LDP BASH Programming - Introduction HOWTO 作为开始信息。

    • mc file:///usr/share/doc/bash/examples/ file:///usr/share/doc/bash/

      (安装 bash-doc 软件包阅读样例文件。)

    • Learning the bash Shell, 2nd edition (O'Reilly)

    一个简短的程序样例(从标准输入端创建帐户信息供 newusers 使用):

         #!/bin/bash
    # (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain
    pid=1000;
    while read n1 n2 n3 ; do
    if [ ${n1:0:1} != "#" ]; then
    let pid=$pid+1
    echo ${n1}_${n2}:password:${pid}:${pid}:,,,/home/${n1}_${n2}:/bin/bash
    fi
    done

    13.2.2 POSIX shells

    Debian 中有几个软件包提供了 POSIX shell:

    • dash (Sarge)

      • Priority: optional

      • Installed-Size: 176

      • 到目前为止最小和最快的 – 最适合用在初始化安装中

    • ash (Woody)

      • Priority: optional

      • Installed-Size: 180

      • 较小和较快的 – 比较适合用在初始化安装中

    • bash

      • Essential: yes

      • Priority: required

      • Installed-Size: 580

      • 较大和多特征的 – 应用了许多扩展

    • pdksh

      • Priority: optional

      • Installed-Size: 408

      • 完全跟 AT&T 的 ksh 类似

    如果你想编写具有通用性的 shell 脚本,最好写 POSIX shell 脚本。可将 /bin/sh 链接到 ash 或(dash)来测试脚本的 POSIX 兼容性。 避免用 bash 化 或 zsh 化的思维去编写脚本。 例如,应避免:

    • if [ foo == bar ] ; then ...

    • diff -u file.c{.orig,}

    • mkdir /foo{bar,baz}

    本文档的 shell 描述,只适用于 POSIX 类型的 shell,不适用于包括 tcsh 在内的 csh 类型。


    13.2.3 Shell 参数

    几个需要记住的特殊参数

         $0      = shell 名称或 shel 脚本名称
    $1 = 第一个(1)shell 参数
    ...
    $9 = 第九个(9)shell 参数
    $# = 位置参数的个数
    "$*" = "$1 $2 $3 $4 ... $n"
    "$@" = "$1" "$2" "$3" "$4" ... "$n"
    $? = 最近执行的命令的退出状态
    $$ = 当前 shell 脚本的 PID
    $! = 最近启动的后台作业的 PID

    需要记住的基本扩展参数

             形式        如果设置了 var      如果没有设置 var
    ${var:-string} $var string
    ${var:+string} string null
    ${var:=string} $var string
    (并且执行 var=string)
    ${var:?string} $var (返回 string 然后退出)

    在此,冒号“:”在所有运算表达式中事实上均是可选的。

    • 有“:” = 运算表达式测试“存在”和“非空”。

    • 没有“:” = 运算表达式仅测试“存在”。

    需要记住的替换参数

             形式        	结果
    ${var%suffix} 删除位于 var 结尾的 suffix 最小匹配模式
    ${var%%suffix} 删除位于 var 结尾的 suffix 最大匹配模式
    ${var#prefix} 删除位于 var 开头的 prefix 最小匹配模式
    ${var##prefix} 删除位于 var 开头的 prefix 最大匹配模式

    13.2.4 Shell 重定向

    需要记住的基本重定向(redirection)运算符(在此[n]表示定义文件描述符的可选 参数):

         [n]> file     重定向标准输出(或 n)到 file
    [n]>> file 重定向标准输出(或 n)到 file
    [n]< filefile重定向到标准输入(或 n)。
    [n1]>&n2 重定向标准输出(或 n1) 到n2
    2> file >&2 重定向标准输出和错误输出到 file
    | command 将标准输出通过管道传递给 command
    2>&1 | command 将标准输出或错误输出通过管道传递给 command

    在这里:

    • stdin: 标准输入 (文件描述符 = 0)

    • stdout: 标准输出 (文件描述符 = 1)

    • stderr: 标准错误 (文件描述符 = 2)

    shell 允许你通过使用 exec 内嵌一个任意的文件描述符来打开文件。

         $ echo Hello >foo
    $ exec 3<foo 4>bar # 打开文件
    $ cat <&3 >&4 # 重定向标准输入到 3,标准输出到 4
    $ exec 3<&- 4>&- # 关闭文件
    $ cat bar
    Hello

    在这里, n<&-n>&- 表示关闭文件描述符 n


    13.2.5 Shell 条件表达式

    每条命令均可返回一个退出状态,这个状态值可用于条件表达式:

    • 成功:0 (True)

    • 错误:1–255 (False)

    注意该用法,返回值0用来表示“true”与计算机其它领域中常见的转换是不同的。另外`['等阶于使用test命令进行参数 赋值`]'相当于一个条件表达式。

    需要记住的常用基本条件表达式

         command && if_success_run_this_command_too || true
    command || if_not_success_run_this_command_instead

    if [ conditional_expression ]; then
    if_success_run_this_command
    else
    if_not_success_run_this_command
    fi

    当 shell 使用 -e 调用的时候, 需要使用 || true 来确保这个 shell 不会在本行意外退出。

    在条件表达式中使用的文件比较运算符有:

         -e file         file 存在则返回True。
    -d file file 存在且是一个目录则返回 True。
    -f file 如果 file 存在且是一个普通文件则返回 True。
    -w file 如果 file 存在且可写则返回 True。
    -x file 如果 file 存在且可执行则返回 True。
    file1 -nt file2 如果 file1file2 新则返回 True。(指修改日期)
    file1 -ot file2 如果 file1file2 旧则返回 True。(指修改日期)
    file1 -ef file2 如果两者是相同的设备和具有相同的结点(inode)数则返回 True。

    条件表达式中使用的字符串比较运算符有:

              -z str    如果 str 长度为零则返回 True。
    -n str 如果 str 长度为非零则返回 True。
    str1 == str2 如果字符串相等则返回 True。
    str1 = str2 如果字符串相等则返回 True。
    (使用"=="代替"="符合严格意义上的 POSIX 兼容)
    str1 != str2 如果字符串不相等则返回 True。
    str1 < str2 如果 str1 排在 str2 之前则返回 True(与当前位置有关)。
    str1 > str2 如果 str1 排在 str2 之后则返回 True(与当前位置有关)。

    条件表达式中的算术整数比较运算符有-eq-ne-lt-le-gt-ge


    13.2.6 命令行处理

    shell按如下的方式处理脚本:

    • 用这些元字符将其分割成 tokens:SPACE, TAB, NEWLINE, ;, (, ), <, >, |, &

    • 如果不在"..."或'...'内就检查 keyword(循环检查)

    • 如果不在"..."或'...'内就扩展 alias(循环检查)

    • 如果不在"..."或'...'内就扩展 bracea{1,2} -> a1 a2

    • 如果不在"..."或'...'内就扩展 tilde, ~user -> user's home directory

    • 如果不在'...'内就扩展 parameter, $PARAMETER

    • 如果不在'...'内就扩展 command substitution, $(command)

    • 如果不在"..."或'...'内就用 $IFS 分割成 words

    • 如果不在"..."或'...'内就扩展 pathname *?[]

    • 查找 command

      • function

      • built-in

      • file in $PATH

    • 循环

    在双单号内单引号将失效。

    在 shell 里执行 set -x 或者使用 -x 选项调用 shell, 该 shell 将会显示出所有执行的命令。 这对调试非常有用。


    13.3 Awk

    Awk的参考资源:

    • Effective awk Programming, 3rd edition (O'Reilly)

    • Sed & awk, 2nd edition (O'Reilly)

    • mawk(1)gawk(1)

    • info gawk

    简短的程序样例(创建 newusers 命令输入):

         #!/usr/bin/awk -f
    # Script to create a file suitable for use in the 'newusers' command,
    # from a file consisting of user IDs and passwords in the form:
    # first_name last_name password
    # Copyright (c) KMSelf Sat Aug 25 20:47:38 PDT 2001
    # Distributed under GNU GPL v 2, or at your option, any later version.
    # This program is distributed WITHOUT ANY WARRANTY.

    BEGIN {
    # Assign starting UID, GID
    if ( ARGC > 2 ) {
    startuid = ARGV[1]
    delete ARGV[1]
    }
    else {
    printf( "Usage: newusers startUID file\n" \
    " where:\n" \
    " startUID is the starting userid to add, and\n" \
    " file is an input file in form:\n" \
    " first_name last_name password\n" \
    )
    exit
    }

    infile = ARGV[1]
    printf( "Starting UID: %s\n\n", startuid )
    }

    /^#/ { next }

    {
    ++record
    first = $1
    last = $2
    passwd = $3
    user= substr( tolower( first ), 1, 1 ) tolower( last )
    uid = startuid + record - 1
    gid = uid
    printf( "%s:%s:%d:%d:%s %s,,/home/%s:/bin/bash\n", \
    user, passwd, uid, gid, first, last, user \
    )
    }

    Debian 中有两个软件包提供了 POSIX awk

    • mawk

      • Priority: required

      • Installed-Size: 228

      • 较小和较快 – 适于默认安装

      • 编译时的限制存在

        • NF = 32767

        • sprintf buffer = 1020

    • gawk

      • Priority: optional

      • Installed-Size: 1708

      • 较大和多特征的 – 应用了许多扩展

        • System V Release 4 version of UNIX

        • Bell Labs awk

        • GNU-specific


    13.4 Perl

    运行于类 Unix 系统上的解释器

    Perl 参考资源:

    简短的程序样例(创建 newusers 命令输入):

         #!/usr/bin/perl
    # (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain
    $pid=1000;
    while (<STDIN>) {
    if (/^#/) { next;}
    chop;
    $pid++;
    ($n1, $n2, $n3) = split / /;
    print $n1,"_",$n2,":", $n3, ":",$pid,
    ":",$pid,",,,/home/",$n1,"_",$n2,":/bin/bash\n"
    }

    安装 Perl 模块 module_name

         # perl -MCPAN -e 'install module_name'

    13.5 Python

    一个不错的面向对象的解释器。

    Python 参考资源:

    简短的程序样例(创建 newusers 命令输入):

         #! /usr/bin/env python
    import sys, string

    # (C) Osamu Aoki Sun Aug 26 16:53:55 UTC 2001 Public Domain
    # Ported from awk script by KMSelf Sat Aug 25 20:47:38 PDT 2001
    # This program is distributed WITHOUT ANY WARRANTY.

    def usages():
    print \
    "Usage: ", sys.argv[0], " start_UID [filename]\n" \
    "\tstartUID is the starting userid to add.\n" \
    "\tfilename is input filename. If not specified, standard input.\n\n" \
    "Input file format:\n"\
    "\tfirst_name last_name password\n"
    return 1

    def parsefile(startuid):
    #
    # main filtering
    #
    uid = startuid
    while 1:
    line = infile.readline()
    if not line:
    break
    if line[0] == '#':
    continue
    (first, last, passwd) = string.split(string.lower(line))
    # above crashes with wrong # of parameters :-)
    user = first[0] + last
    gid = uid
    lineout = "%s:%s:%d:%d:%s %s,,/home/%s:/bin/bash\n" % \
    (user, passwd, uid, gid, first, last, user)
    sys.stdout.write(lineout)
    +uid

    if __name__ == '__main__':
    if len(sys.argv) == 1:
    usages()
    else:
    uid = int(sys.argv[1])
    #print "# UID start from: %d\n" % uid
    if len(sys.argv) > 1:
    infilename = string.join(sys.argv[2:])
    infile = open(infilename, 'r')
    #print "# Read file from: %s\n\n" % infilename
    else:
    infile = sys.stdin
    parsefile(uid)

    13.6 Make

    Make 参考资源:

    • info make

    • make(1)

    • Managing Projects with make, 2nd edition (O'Reilly)

    简单自动变量:

    语法规则:

         target: [ prerequisites ... ]
    [TAB] command1
    [TAB] -command2 # ignore errors
    [TAB] @command3 # suppress echoing

    在此[TAB]代表一个 TAB 符。 在完成 make 变量代换后,shell 将逐行进行解释。在行尾使用 \ 可以续行。使用 $$ 可将 $ 加入到 shell 脚本的环境变量中。

    适用于 targetprerequisites 的隐含的等价规则:

         %: %.c header.h

    or,

         %.o: %.c header.h

    在此,target 包含了 % 字符(确切地说是其中之一),% 可匹配实际的 target 文件名中任何非空子串。prerequisites 同样也使用 % 来显示它们的名字是如何关联到实际的 target 文件名的。

    Suffix rules 方法来定义 make 的隐含规则(implicit rules)已经过时。GNU make 因为兼容性的考虑仍支持它,但只要有可能就应该使用与之等价的模版规则(pattern rules):

         old suffix rule --> new pattern rule
    .c: --> % : %.c
    .c.o: --> %.o: %.c

    上述规则所使用的自动变量:

         foo.o: new1.c new2.c old1.c new3.c
    $@ == foo.o (target)
    $< == new1.c (first one)
    $? == new1.c new2.c new3.c (newer ones)
    $^ == new1.c new2.c old1.c new3.c (all)
    $* == `%' matched stem in the target pattern.

    变量参考:

         foo1 := bar    # One-time expansion
    foo2 = bar # Recursive expansion
    foo3 += bar # Append
    SRCS := $(wildcard *.c)
    OBJS := $(foo:c=o)
    OBJS := $(foo:%.c=%.o)
    OBJS := $(patsubst %.c,%.o,$(foo))
    DIRS = $(dir directory/filename.ext) # Extracts "directory"
    $(notdir NAMES...), $(basename NAMES...), $(suffix NAMES...) ...

    执行make -p -f/dev/null可查看内部自动规则。


    13.7 C

    准备工作:

         # apt-get install glibc-doc manpages-dev libc6-dev gcc

    C参考资源:


    13.7.1 简单 C 编程(gcc)

    一个简单的例子,将 example.c 和库函数 libm 编译成可执行文件 run_example

         $ cat > example.c << EOF
    #include <stdio.h>
    #include <math.h>
    #include <string.h>

    int main(int argc, char **argv, char **envp){
    double x;
    char y[11];
    x=sqrt(argc+7.5);
    strncpy(y, argv[0], 10); /* prevent buffer overflow */
    y[10] = '\0'; /* fill to make sure string ends with '\0' */
    printf("%5i, %5.3f, %10s, %10s\n", argc, x, y, argv[1]);
    return 0;
    }
    EOF
    $ gcc -Wall -g -o run_example example.c -lm
    $ ./run_example
    1, 2.915, ./run_exam, (null)
    $ ./run_example 1234567890qwerty
    2, 3.082, ./run_exam, 1234567890qwerty

    在此,sqrt() 链接库函数 libm 需要 -lm 选项。真正的库函数是位于 /lib/ 下的 libm.so.6,它是 libm-2.1.3.so 的一个符号链接。

    看看输出文本中最后的参数,尽管指定了 %10s,它还是多于10个字符。

    使用不带边界检查的指针内存操作函数如 sprintfstrcpy 会妨碍缓冲区溢出侦测,故使 用snprintfstrncpy


    13.7.2 调试


    13.7.2.1 使用 gdb 进行调试

    准备工作:

         # apt-get install gdb

    gdb参考资源:

    使用 -g 选项编译程序就可使用 gdb 进行调试。许多命令都可以缩写。Tab 扩展功能和在 shell 中的一样。

         $ gdb program
    (gdb) b 1 # 在line 1 设置断点
    (gdb) run arg1 arg2 arg3 # 运行程序
    (gdb) next # 下一行
    ...
    (gdb) step # 前进一步
    ...
    (gdb) p parm # 打印 parm
    ...
    (gdb) p parm=12 # 设置其值为 12

    在 Emacs 环境下调试程序,参阅编 辑器命令总汇(Emacs,Vim), 第 11.3.4 节

    Debian 系统上所有默认安装的二进制文件都已经进行了 strip 操作, 调试符号已经被移除。 为了能够让 gdb 对 Debian 软件包进行调试, 相关的软件包需要使用下面的方法重新打包:

    • 编辑 debian/control 来改变软件包的 版 本

    • 检查打包脚本,确保使用 CFLAGS=-g-Wall 来编译二进制文件。

    • 设置 DEB_BUILD_OPTIONS=nostrip,noopt 来建立 Debian 包。

    更多信息请参阅: Policy 10.1


    13.7.2.2 检查库函数关联关系

    使用ldd可查看程序与库函数的关联关系:

         $ ldd /bin/ls
    librt.so.1 => /lib/librt.so.1 (0x4001e000)
    libc.so.6 => /lib/libc.so.6 (0x40030000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x40153000)
    /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

    可在 chrooted 环境下使用 ls 检查上述库函数在你的 chroot 环境中是否可见。

    下面的命令也很有用:

    • strace: 跟踪系统调用和消息

    • ltrace: 跟踪库函数调用


    13.7.2.3 使用内存查漏工具进行调试

    Debian中有几个内存查漏工具。

    • njamd

    • valgrind

    • dmalloc

    • electric-fence

    • memprof

    • memwatch (没有软件包,从 memwatch 获取。)

    • mpatrol

    • leaktracer

    • libgc6

    • 来自 ParasoftInsure++(非自由软件,商业付费)

    亦可查阅Debugging Tools for Dynamic Storage Allocation and Memory Management.


    13.7.3 Flex – 更好的 Lex

    flex 是一个快速的词法分析机生成器。

    flex 参考资源:

    • info flex (教程)

    • flex(1)

    需要提供你自己的 main()yywrap(),或者你的 program.l 象这样不带library编译(yywrap 是一个宏;%option main 隐含地打开了 %option noyywrap):

         %option main
    %%
    .|\n ECHO ;
    %%

    另外,还可以在 cc 命令行末尾加上 -lfl 链接选项进行编译(象 AT&T-Lex 使用 -ll 一样),此时就不需要 %option 了。


    13.7.4 Bison – 更好的 Yacc

    Debian 中有几个软件包提供了与 Yacc 兼容的 LALR 词法生成器:

    • bison: GNU LALR parser generator

    • byacc: The Berkeley LALR parser generator

    • btyacc: Backtracking parser generator based on byacc

    bison 参考资源:

    • info bison (教程)

    • bison(1)

    需要提供自己的 main()yyerror()main() 调用 yyparse(),而 yyparse() 调用 yylex(),通常由 FleX 创建。

         %%

    %%

    13.7.5 Autoconf

    autoconf 一个 shell 脚本生成工具,由它生成的脚本能自动配置软件源码包,以适用于各种使用全套 GNU build 系统的类 UNIX 系统。

    autoconf 会生成配置脚本 configureconfigure 使用 Makefile.in 模版自动创建自定义 Makefile


    13.7.5.1 编译并安装程序

    Debian 不会改动 /usr/local/ 下的文件(参阅多 样性支持, 第 2.5 节)。所以如果是从源码编译程序,并将其安装到 /usr/local/ 下,是不会影响到 Debian 的。

         $ cd src
    $ ./configure --prefix=/usr/local
    $ make
    $ make install # this puts the files in the system

    13.7.5.2 卸载程序

    如果仍保存有源码,对其使用了 autoconf/automake,并且记得是如何进行配置的:

         $ ./configure all-of-the-options-you-gave-it
    # make uninstall

    另一种方法是,如果可以确定安装过程将文件都放在了 /usr/local/,并且该目录下没有什么别的重要文件,可用下面的命令将其全部删除:

         # find /usr/local -type f -print0 | xargs -0 rm -f

    如果不能确定文件安装到什么位置,最好使用 checkinstall,该命令可提供明确的卸载路径。


    13.8 Web

    通过下面的方法来制作一个基本的交互动态网页:

    • 使用 HTML 表单在浏览器里显示查询。

    • 填写和点击表单提交,将从浏览器传送一个将参数 [64] 编码的 URL 到服务器。例如:

      • http://www.foo.dom/cgi-bin/program.pl?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3

      • http://www.foo.dom/cgi-bin/program.py?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3

      • http://www.foo.dom/program.php?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3

    • 在 web 服务器上的 CGI 程序(任何一个 program.* 程序) 将接受编码的 "VAR1=VAL1 VAR2=VAL2 VAR3=VAL3" 参数作为环境变量 “QUERY_STRING” 的内容,并执行该环境变量。

    • CGI 程序的标准输出 将作为一个交互动态网页输出到 web 浏览器。

    出于安全的考虑,最好不要手工写新的程序来分析 CGI 参数。 在 Perl (参阅 Perl, 第 13.4 节)、Python (参阅 Python, 第 13.5 节) 和 PHP 中,有即定的模块具备这些功能。 当需要在客户端存储数据的时候,使用 cookies。 当需要在客户端进行数据处理的时候,经常使用 javascript。

    更多信息,请参阅 The Common Gateway InterfaceThe Apache Software FoundationJavaScript

    在浏览器地址栏里面直接输入编码的 URL http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial, 可以在 Google 搜索 “CGI tutorial”。 这也是一个查看 CGI 脚本在 Google 服务器上执行的好方法。


    13.9 准备文档


    13.9.1 roff 排版

    传统上,roff 是主要的 Unix 文字处理系统。

    参阅 roff(7)groff(7)groff(1)grotty(1)troff(1)groff_mdoc(7)groff_man(7)groff_ms(7)groff_me(7)groff_mm(7) 以及 info groff

    -me 宏提供了一个不错了说明文档。如果使用的是 groff(1.18或更新的版本),找到 file:///usr/share/doc/groff/meintro.me.gz 并执行下面的命令:

         $ zcat file:///usr/share/doc/groff/meintro.me.gz | \
    groff -Tascii -me - | less -R

    下面的命令将生成一个完整的纯文本文件:

         $ zcat file:///usr/share/doc/groff/meintro.me.gz | \
    GROFF_NO_SGR=1 groff -Tascii -me - | col -b -x > meintro.txt

    如果想打印出来,可使用 PostScript 输出:

         $ groff -Tps meintro.txt | lpr
    $ groff -Tps meintro.txt | mpage -2 | lpr

    13.9.2 SGML

    准备工作:

         # apt-get install debiandoc-sgml debiandoc-sgml-doc

    debiandoc-sgml 参考资源:

    • file:///usr/share/doc/debiandoc-sgml-doc

    • debiandoc-sgml(1)

    • DocBook: The Definitive Guide,作者 Walsh 和 Muellner,(O'Reilly 出版社) (docbook-defguide 软件包)

    SGML 能管理多种格式的文档。更简单的 SGML 系统是 Debiandoc,本文档就使用到它完成的。只需对原始的文本文件的下列字符进行少许转换:

    • "<" --> &lt;

    • ">" --> &gt;

    • " " --> &nbsp; (非中断空格)

    • "&" --> &amp;

    • "%" --> &percnt;

    • "(c)" --> &copy;

    • "–" --> &ndash;

    • "—" --> &mdash;

    设置章节为非打印注释,输入:

         <!-- State issue here ... -->

    设置章节为可控注释,输入:

         <![ %FIXME; [ State issue here ... ]]>

    在 SGML 中,仅条目的首次声明(first definition)有效。例如:

         <!entity % qref "INCLUDE">
    <![ %qref; [ <!entity param "Data 1"> ]]>
    <!entity param "Data 2">
    &param;

    最终结果是“Data 1”。如果第一行使用“IGNORE”而非“INCLUDE”,则最终结果为“Data 2”(第二行是一个候选声明)。同样,重复出现的短语可分别提前在文档中定义。

         <!entity whoisthis "my">
    Hello &whoisthis; friend.
    This is &whoisthis; book.

    该定义的结果如下:

         Hello my friend.
    This is my book.

    可参阅 examples 目录中简短的 SGML 样例文件sample.sgml

    当 SGML 文档逐渐变大时,作为后端文本处理器使用的 TeX 偶尔会错误。 参阅 TeX/LaTeX, 第 13.9.3 节


    13.9.3 TeX/LaTeX

    准备:

         # tasksel # select Miscellaneous  --> TeX/LaTeX environment

    LaTeX 参考:

    • The teTeX HOWTO: The Linux-teTeX Local Guide

    • tex(1)

    • latex(1)

    • The TeXbook, by Donald E. Knuth, (Addison-Wesley) [65]

    • LaTeX - A Document Preparation System, by Leslie Lamport, (Addison-Wesley)

    • The LaTeX Companion, by Goossens, Mittelbach, Samarin, (Addison-Wesley)

    这是一个很强大的排字环境。许多 SGML 处理器使用 LaTeX 作为他们的后端文本处理器。 由 lyxlyx-xformslyx-qt 提供的 Lyx,以及由 texmacs 提供的 GNU TeXmacs 为 LaTeX 提供了一个好的“所见及所得”的编辑环境,然而,许多人选择使用 Emacs 和 Vim 作为源代码编辑器。

    有许多在线资源存在:

    当 SGML 文档不断增大后,TeX 偶尔会出错。可通过修改 /etc/texmf/texmf.cnf,增加缓冲池的容量来解决这个问题(更好的方法是编辑 /etc/texmf/texmf.d/95NonPath 然后运 行update-texmf)。


    13.9.4 文学编程

    有文学的程序员书写包含代码的文档来代替包含文档的代码。 这种方法确保程序有一个好的文档。

    关于文学编程的更多信息,参阅 Literate Programming


    13.9.4.1 Noweb

    准备:

         # apt-get install nowebm

    Noweb 参考:

    这是一个类 WEB 的文学编程工具,独立于编程语言。由于提供了扩展而更简单。 [66] 当 noweb 被调用的时候,它将程序的源代码输出到在 noweb 中提到的文件中,它还将创建一个用于文档排版的 TeX 文件。

    Debian ifupdown 软件包是一个很好的例子。

         $ apt-get source ifupdown
    $ cd ifupdown*
    $ make ifupdown.pdf ifupdown.ps

    13.9.4.2 Doxygen

    准备:

         # apt-get install doxygen doxygen-doc doxygen-gui

    Doxygen 参考(由 doxygen 创建):

    它能够为 C++、C、 Java、 IDL 和某些范围的 PHP 和 C# 程序产生 HTML、 RTF、 Unix 手册页、 PostScript 和 PDF(使用 LaTeX)文档。 Doxygen 与 JavaDoc (1.1)、 Qt-Doc 和 KDOC 兼容,它有特定的设计用来与用 Troll Tech 的 Qt 工具包制作的项目兼容。 他甚至可以为没有文档的程序创建从属图、协作图和图形化的类分层图。输出类似于 Qt 的文档。


    13.10 打包

    准备工作:

         # apt-get install debian-policy developers-reference \
    maint-guide dh-make debhelper
    # apt-get install packaging-manual # if Potato

    有关打包的参考资源:

    • Debian 软件包管理系统, 第 2.2 节 (basics)

    • Debian New Maintainers' Guide (tutorial)

    • dh-make(1)

    • Debian Developer's Reference (best practice)

    • Debian Policy Manual (authoritative)

    • Packaging Manual (Potato)


    13.10.1 单个二进制文件打包

    Joey Hess 的快速和粗糙的打包法:生成一个单独的二进制包

         # mkdir -p mypkg/usr/bin mypkg/DEBIAN
    # cp binary mypkg/usr/bin
    # cat > mypkg/DEBIAN/control
    Package: mypackage
    Version: 1
    Architecture: i386
    Maintainer: Joey Hess <joeyh@debian.org>
    Description: my little package
    Don't expect much.
    ^D
    # dpkg-deb -b mypkg

    13.10.2 使用工具打包

    使用 dh_make 软件包中的 dh-make 工具创建一个基线包,接着按照 dh-make(1) 中描述的方法打包。会用到 debian/rules 中的 debhelper

    一个较老的方法是使用 debmake 软件包中的 deb-make。不需要 debhelper 脚本,仅需要 shell 环境。请不要再使用这种方法。

    有关多种源码包的例子,参阅“mc”(dpkg-source -x mc_4.5.54.dsc),其中用到 Adam Heath(doogie@debian.org)的“sys- build.mk”以及“glibc”(dpkg-source -x glibc_2.2.4-1.dsc)它由后来的 Joel Klecker(espy@debian.org)所写的另一个系统打包。


    [ 上一页 ] [ 目 录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ 14 ] [ 15 ] [ A ] [ 下 一页 ]


    Debian Reference (version 1)

    This translation is based on old version of Debian Reference (English, version 1.x), well before Sat, 26 Jan 2008.

    Osamu Aoki osamu#at#debian.org
    译者:
    Hao "Lyoo" Liu iamlyoo#at#163.net
    Ming Hua minghua#at#rice.edu
    肖盛文 atzlinux#at#163.com
    Haifeng Chen optical.dlz#at#gmail.com
    解彦博 xieyanbo#at#gmail.com
    easthero easthero#at#gmail.com
    作 者, 第 A.1 节


  • 相关阅读:
    Java项目中读取properties文件,以及六种获取路径的方法
    在eclipse中使用JUnit4,以及使用JUnit4进行单元测试的技巧
    [Evernote]印象笔记使用经验技巧
    使用Word2010发布博客文章
    Win7/8 绿色软件开机启动
    常见笔试题
    排序
    数据库知识归纳(索引)
    数据库知识归纳(事务)
    Redis
  • 原文地址:https://www.cnblogs.com/Donal/p/1700558.html
Copyright © 2011-2022 走看看