目录
我为人们学习在 Debian 系统上进行程序设计提供了一些指导,足以追踪打包的源代码。以下是值得注意的软件包和相应的程序设计文档软件包。
表 12.1. 帮助程序设计的软件包列表
通过安装 manpages
和 manpages-dev
软件包后,输入 “man name
” 可以获得在线参考。通过安装相关的文档软件包后,输入 “info program_name
” 可以获得 GNU 工具的在线参考。 您可能需要在 main
存档之外,还包括 contrib
和 non-free
存档,因为一些 GFDL 文档不被认为是 DFSG 兼容的。
![]() |
警告 |
---|---|
不要使用 “ |
![]() |
注意 |
---|---|
您应该将直接从源代码编译的软件程序安装到 “ |
![]() |
提示 |
---|---|
创建 “啤酒之歌 99 瓶” 的代码示例 应该能让您很好地了解几乎所有程序设计语言。 |
Shell 脚本 是一个设置了执行位的文本文件,包含以下格式的命令。
#!/bin/sh ... command lines
第一行指定了读取和执行此文件内容的 shell 解释器。
阅读 shell 脚本是理解类 Unix 系统如何工作的最佳方式。在这里,我给出一些 shell 程序设计的提示和提醒。请参阅 “Shell 错误” (http://www.greenend.org.uk/rjk/2001/04/shell.html) 以从错误中学习。
与 shell 交互模式(请参阅 第 1.5 节,“简单的 Shell 命令” 和 第 1.6 节,“类 Unix 文本处理”)不同,shell 脚本经常使用参数、条件语句和循环。
许多系统脚本可以由任何 POSIX shell 解释(请参阅 表 1.13,“Shell 程序列表”)。系统的默认 shell 是 “/bin/sh
”,它是一个指向实际程序的符号链接。
bash(1) 用于 lenny
或更旧版本
dash(1) 用于 squeeze
或更新版本
避免编写带有 bashisms 或 zshisms 的 shell 脚本,以使其在所有 POSIX shell 之间可移植。您可以使用 checkbashisms(1) 进行检查。
表 12.2. 典型的 bashisms 列表
良好:POSIX | 避免:bashism |
---|---|
if [ "$foo" = "$bar" ] ; then …
|
if [ "$foo" == "$bar" ] ; then …
|
diff -u file.c.orig file.c
|
diff -u file.c{.orig,}
|
mkdir /foobar /foobaz
|
mkdir /foo{bar,baz}
|
funcname() { … }
|
function funcname() { … }
|
八进制格式: “\377 ” |
十六进制格式: “\xff ” |
必须谨慎使用 “echo
” 命令,因为其实现因 shell 内置命令和外部命令而异。
避免使用命令选项 “-e
” 和 “-E
”。
除了 “-n
” 之外,避免使用任何命令选项。
避免在字符串中使用转义序列,因为它们的处理方式各不相同。
![]() |
注意 |
---|---|
虽然 “ |
![]() |
提示 |
---|---|
如果需要在输出字符串中嵌入转义序列,请使用 “ |
shell 脚本中经常使用特殊的 shell 参数。
表 12.3. Shell 参数列表
shell 参数 | 值 |
---|---|
$0
|
shell 或 shell 脚本的名称 |
$1
|
第一个 (1) shell 参数 |
$9
|
第九个 (9) shell 参数 |
$#
|
位置参数的数量 |
"$*"
|
“$1 $2 $3 $4 …”
|
"$@"
|
“$1” “$2” “$3” “$4” …
|
$?
|
最近命令的退出状态 |
$$
|
此 shell 脚本的 PID |
$!
|
最近启动的后台作业的 PID |
需要记住的基本参数扩展如下。
表 12.4. Shell 参数扩展列表
参数表达式形式 | 如果 var 已设置的值 |
如果 var 未设置的值 |
---|---|---|
${var:-string}
|
“$var ” |
“string ” |
${var:+string}
|
“string ” |
“null ” |
${var:=string}
|
“$var ” |
“string ”(并运行 “var=string ”) |
${var:?string}
|
“$var ” |
向stderr 输出 “string ”(并以错误退出) |
这里,所有这些运算符中的冒号 “:
” 实际上是可选的。
带 “:
” = 运算符测试存在且非空
不带 “:
” = 运算符仅测试存在
表 12.5. 关键 shell 参数替换列表
参数替换形式 | 结果 |
---|---|
${var%suffix}
|
删除最短后缀模式 |
${var%%suffix}
|
删除最长后缀模式 |
${var#prefix}
|
删除最短前缀模式 |
${var##prefix}
|
删除最长前缀模式 |
每个命令都返回一个退出状态,可用于条件表达式。
成功:0 (“真”)
错误:非 0 (“假”)
![]() |
注意 |
---|---|
shell 条件上下文中的 “0” 表示 “真”,而 C 条件上下文中的 “0” 表示 “假”。 |
![]() |
注意 |
---|---|
“ |
需要记住的基本条件惯用法如下。
“<command> && <if_success_run_this_command_too> || true
”
“<command> || <if_not_success_run_this_command_too> || true
”
如下所示的多行脚本片段
if [ <conditional_expression> ]; then <if_success_run_this_command> else <if_not_success_run_this_command> fi
这里需要尾部的 “|| true
” 以确保当 shell 使用 “-e
” 标志调用时,此 shell 脚本不会在此行意外退出。
表 12.6. 条件表达式中的文件比较运算符列表
等式 | 返回逻辑真的条件 |
---|---|
-e <file>
|
<file> 存在 |
-d <file>
|
<file> 存在且是一个目录 |
-f <file>
|
<file> 存在且是一个常规文件 |
-w <file>
|
<file> 存在且可写 |
-x <file>
|
<file> 存在且可执行 |
<file1> -nt <file2>
|
<file1> 比 <file2> 新 (修改时间) |
<file1> -ot <file2>
|
<file1> 比 <file2> 旧 (修改时间) |
<file1> -ef <file2>
|
<file1> 和 <file2> 在同一设备上且具有相同的 inode 号 |
表 12.7. 条件表达式中的字符串比较运算符列表
等式 | 返回逻辑真的条件 |
---|---|
-z <str>
|
<str> 的长度为零 |
-n <str>
|
<str> 的长度为非零 |
<str1> = <str2>
|
<str1> 和 <str2> 相等 |
<str1> != <str2>
|
<str1> 和 <str2> 不相等 |
<str1> < <str2>
|
<str1> 排序在 <str2> 之前 (取决于区域设置) |
<str1> > <str2>
|
<str1> 排序在 <str2> 之后 (取决于区域设置) |
条件表达式中的算术整数比较运算符为 “-eq
”、“-ne
”、“-lt
”、“-le
”、“-gt
” 和 “-ge
”。
POSIX shell 中有几种循环惯用法可以使用。
“for x in foo1 foo2 … ; do command ; done
” 通过将列表 “foo1 foo2 …
” 中的项目分配给变量 “x
” 并执行 “command
” 来循环。
“while condition ; do command ; done
” 在 “condition
” 为真时重复 “command
”。
“until condition ; do command ; done
” 在 “condition
” 不为真时重复 “command
”。
“break
” 允许退出循环。
“continue
” 允许恢复循环的下一次迭代。
![]() |
提示 |
---|---|
类 C 语言的数字迭代可以通过使用 seq(1) 作为 “ |
![]() |
提示 |
---|---|
shell 大致按以下顺序处理脚本。
shell 读取一行。
如果在一行的一部分位于 “…”
或 ‘…’
内,则 shell 将其分组为一个标记。
shell 通过以下方式将行的其他部分拆分为标记。
空白字符:<空格> <制表符> <换行符>
元字符:< > | ; & ( )
如果不在 “…”
或 ‘…’
内,则 shell 检查每个标记的保留字以调整其行为。
保留字:if then elif else fi for in while unless do done case esac
如果不在 “…”
或 ‘…’
内,则 shell 扩展别名。
如果不在 “…”
或 ‘…’
内,则 shell 扩展波浪号。
“~
” → 当前用户的家目录
“~<user>
” → <user>
的家目录
如果不在 ‘…’
内,则 shell 将参数扩展为其值。
参数:“$PARAMETER
” 或 “${PARAMETER}
”
如果不在 ‘…’
内,则 shell 扩展命令替换。
“$( command )
” → “command
” 的输出
“` command `
” → “command
” 的输出
如果不在 “…”
或 ‘…’
内,则 shell 将路径名通配符扩展为匹配的文件名。
*
→ 任意字符
?
→ 一个字符
[…]
→ “…
” 中的任意一个字符
shell 从以下位置查找命令并执行它。
函数定义
内置命令
“$PATH
” 中的可执行文件
shell 转到下一行,并从该序列的顶部再次重复此过程。
双引号内的单引号无效。
在 shell 中执行 “set -x
” 或使用 “-x
” 选项调用 shell 会使 shell 打印所有执行的命令。 这对于调试非常方便。
为了使您的 shell 程序在 Debian 系统中尽可能地可移植,最好将实用工具程序限制为 essential 软件包提供的程序。
“aptitude search ~E
” 列出 essential 软件包。
“dpkg -L <package_name> |grep '/man/man.*/'
” 列出 <package_name>
软件包提供的命令的手册页。
表 12.8. 包含用于 shell 脚本的小型实用工具程序的软件包列表
软件包 | popcon | 大小 | 描述 |
---|---|---|---|
coreutils
|
http://qa.debian.org/popcon.php?package=coreutils | 14088 | GNU 核心实用程序 |
debianutils
|
http://qa.debian.org/popcon.php?package=debianutils | 222 | Debian 特有的各种实用程序 |
bsdmainutils
|
http://qa.debian.org/popcon.php?package=bsdmainutils | 558 | 来自 FreeBSD 的更多实用程序的集合 |
bsdutils
|
http://qa.debian.org/popcon.php?package=bsdutils | 187 | 来自 4.4BSD-Lite 的基本实用程序 |
moreutils
|
http://qa.debian.org/popcon.php?package=moreutils | 147 | 额外的 Unix 实用程序 |
![]() |
提示 |
---|---|
虽然 |
可以通过使用所谓的对话框程序等,将简单 shell 程序的用户界面从通过 echo
和 read
命令进行的枯燥交互改进为更具交互性的界面。
表 12.9. 用户界面程序列表
软件包 | popcon | 大小 | 描述 |
---|---|---|---|
x11-utils
|
http://qa.debian.org/popcon.php?package=x11-utils | 554 | xmessage(1):在窗口中显示消息或查询 (X) |
whiptail
|
http://qa.debian.org/popcon.php?package=whiptail | 87 | 从 shell 脚本显示用户友好的对话框 (newt) |
dialog
|
http://qa.debian.org/popcon.php?package=dialog | 1230 | 从 shell 脚本显示用户友好的对话框 (ncurses) |
zenity
|
http://qa.debian.org/popcon.php?package=zenity | 324 | 从 shell 脚本显示图形对话框 (gtk2.0) |
ssft
|
http://qa.debian.org/popcon.php?package=ssft | 152 | Shell 脚本前端工具(zenity、kdialog 和 dialog 的包装器,带有 gettext) |
gettext
|
http://qa.debian.org/popcon.php?package=gettext | 6355 | “/usr/bin/gettext.sh ”:翻译消息 |
这是一个简单的脚本,它使用 RS02 数据创建 ISO 镜像,并由 dvdisaster(1) 补充。
#!/bin/sh -e # gmkrs02 : Copyright (C) 2007 Osamu Aoki <osamu@debian.org>, Public Domain #set -x error_exit() { echo "$1" >&2 exit 1 } # Initialize variables DATA_ISO="$HOME/Desktop/iso-$$.img" LABEL=$(date +%Y%m%d-%H%M%S-%Z) if [ $# != 0 ] && [ -d "$1" ]; then DATA_SRC="$1" else # Select directory for creating ISO image from folder on desktop DATA_SRC=$(zenity --file-selection --directory \ --title="Select the directory tree root to create ISO image") \ || error_exit "Exit on directory selection" fi # Check size of archive xterm -T "Check size $DATA_SRC" -e du -s $DATA_SRC/* SIZE=$(($(du -s $DATA_SRC | awk '{print $1}')/1024)) if [ $SIZE -le 520 ] ; then zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="The data size is good for CD backup:\\n $SIZE MB" elif [ $SIZE -le 3500 ]; then zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="The data size is good for DVD backup :\\n $SIZE MB" else zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="The data size is too big to backup : $SIZE MB" error_exit "The data size is too big to backup :\\n $SIZE MB" fi # only xterm is sure to have working -e option # Create raw ISO image rm -f "$DATA_ISO" || true xterm -T "genisoimage $DATA_ISO" \ -e genisoimage -r -J -V "$LABEL" -o "$DATA_ISO" "$DATA_SRC" # Create RS02 supplemental redundancy xterm -T "dvdisaster $DATA_ISO" -e dvdisaster -i "$DATA_ISO" -mRS02 -c zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="ISO/RS02 data ($SIZE MB) \\n created at: $DATA_ISO" # EOF
您可能希望在桌面上创建一个启动器,命令设置为类似 “/usr/local/bin/gmkrs02 %d
”。
Make 是一个用于维护程序组的实用工具。 执行 make(1) 后,make
读取规则文件 “Makefile
”,如果目标依赖的先决条件文件自上次修改目标以来已被修改,或者如果目标不存在,则更新目标。 这些更新的执行可能会并发发生。
规则文件语法如下。
target: [ prerequisites ... ] [TAB] command1 [TAB] -command2 # ignore errors [TAB] @command3 # suppress echoing
这里 “ [TAB]
” 是一个 TAB 代码。 每行在 make 变量替换后由 shell 解释。 在行尾使用 “\
” 以继续脚本。 使用 “$$
” 为 shell 脚本输入 “$
” 的环境变量值。
可以编写目标和先决条件的隐式规则,例如,通过以下方式。
%.o: %.c header.h
这里,目标包含字符 “%
”(恰好一个)。 “%
” 可以匹配实际目标文件名中的任何非空子字符串。 先决条件也类似地使用 “%
” 来显示其名称与实际目标名称的关系。
运行 “make -p -f/dev/null
” 以查看自动内部规则。
您可以通过以下方式设置适当的环境来编译用 C 程序设计语言 编写的程序。
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
libc6-dev
软件包,即 GNU C 库,提供了 C 标准库,它是 C 程序设计语言使用的一组头文件和库例程。
有关 C 的参考资料如下。
“info libc
” (C 库函数参考)
gcc(1) 和 “info gcc
”
每个 C 库函数名称(3)
Kernighan & Ritchie, “The C Programming Language”, 第 2 版 (Prentice Hall)
可以通过以下方式将一个简单的示例 “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
这里,需要 “-lm
” 来链接来自 libc6
软件包的库 “/usr/lib/libm.so
”,用于 sqrt(3)。 实际库位于 “/lib/
” 中,文件名为 “libm.so.6
”,它是指向 “libm-2.7.so
” 的符号链接。
查看输出文本中的最后一个参数。 即使指定了 “%10s
”,也有超过 10 个字符。
不建议使用不带边界检查的指针内存操作函数,例如 sprintf(3) 和 strcpy(3),以防止利用上述溢出效应的缓冲区溢出漏洞。 请改用 snprintf(3) 和 strncpy(3)。
调试是程序设计活动的重要组成部分。 了解如何调试程序使您成为一个优秀的 Debian 用户,可以生成有意义的错误报告。
Debian 上的主要 调试器 是 gdb(1),它使您可以在程序执行时检查程序。
让我们通过以下方式安装 gdb
和相关程序。
# apt-get install gdb gdb-doc build-essential devscripts
“info gdb
” 提供了 gdb
的良好教程,或者在 网络上的其他地方 也可以找到。 以下是在使用 “-g
” 选项编译的 “program
” 上使用 gdb(1) 以生成调试信息的简单示例。
$ gdb program (gdb) b 1 # set break point at line 1 (gdb) run args # run program with args (gdb) next # next line ... (gdb) step # step forward ... (gdb) p parm # print parm ... (gdb) p parm=12 # set value to 12 ... (gdb) quit
![]() |
提示 |
---|---|
许多 gdb(1) 命令可以缩写。 Tab 扩展的工作方式与 shell 中相同。 |
由于默认情况下所有已安装的二进制文件都应该在 Debian 系统上被剥离,因此大多数调试符号都在普通软件包中被删除。 为了使用 gdb(1) 调试 Debian 软件包,需要安装相应的 *-dbg
软件包(例如,libc6
的情况下的 libc6-dbg
)。
如果要调试的软件包未提供其 *-dbg
软件包,则需要在通过以下方式重建后安装它。
$ mkdir /path/new ; cd /path/new $ sudo apt-get update $ sudo apt-get dist-upgrade $ sudo apt-get install fakeroot devscripts build-essential $ sudo apt-get build-dep source_package_name $ apt-get source package_name $ cd package_name*
如果需要,修复错误。
将软件包版本提升为与官方 Debian 版本不冲突的版本,例如,当重新编译现有软件包版本时,附加 “+debug1
”,或者当编译未发布的软件包版本时,附加 “~pre1
”,如下所示。
$ dch -i
通过以下方式编译和安装带有调试符号的软件包。
$ export DEB_BUILD_OPTIONS=nostrip,noopt $ debuild $ cd .. $ sudo debi package_name*.changes
您需要检查软件包的构建脚本,并确保使用 “CFLAGS=-g -Wall
” 来编译二进制文件。
当您遇到程序崩溃时,提交带有剪切粘贴的回溯信息的错误报告是一个好主意。
可以通过以下步骤获得回溯。
在 gdb(1) 下运行程序。
重现崩溃。
这会导致您返回到 gdb
提示符。
在 gdb
提示符下键入 “bt
”。
如果程序冻结,您可以按 Ctrl-C
在运行 gdb
的终端中崩溃程序,以获取 gdb
提示符。
![]() |
提示 |
---|---|
通常,您会看到一个回溯,其中顶部的一行或多行位于 “ |
$ MALLOC_CHECK_=2 gdb hello
表 12.12. 高级 gdb 命令列表
命令 | 命令目标的描述 |
---|---|
(gdb) thread apply all bt
|
获取多线程程序的所有线程的回溯 |
(gdb) bt full
|
获取函数调用堆栈上的参数 |
(gdb) thread apply all bt full
|
获取回溯和参数,作为前面选项的组合 |
(gdb) thread apply all bt full 10
|
获取回溯和参数,用于顶部 10 个调用以截断不相关的输出 |
(gdb) set logging on
|
将 gdb 输出的日志写入文件(默认文件为 “gdb.txt ”) |
如果 GNOME 程序 preview1
收到 X 错误,您应该会看到如下消息。
The program 'preview1' received an X Window System error.
如果是这种情况,您可以尝试使用 “--sync
” 运行程序,并在 “gdk_x_error
” 函数处中断,以便获取回溯。
使用 ldd(1) 找出程序对库的依赖关系,如下所示。
$ 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)
为了使 ls(1) 在 `chroot` 环境中工作,上述库必须在您的 `chroot` 环境中可用。
请参阅 第 9.5.6 节,“追踪程序活动”。
Debian 中有几种内存泄漏检测工具可用。
表 12.13. 内存泄漏检测工具列表
软件包 | popcon | 大小 | 描述 |
---|---|---|---|
libc6-dev
|
http://qa.debian.org/popcon.php?package=libc6-dev | 10555 | mtrace(1):glibc 中的 malloc 调试功能 |
valgrind
|
http://qa.debian.org/popcon.php?package=valgrind | 94878 | 内存调试器和性能分析器 |
kmtrace
|
http://qa.debian.org/popcon.php?package=kmtrace | 264 | 使用 glibc 的 mtrace(1) 的 KDE 内存泄漏跟踪器 |
alleyoop
|
http://qa.debian.org/popcon.php?package=alleyoop | 948 | Valgrind 内存检查器的 GNOME 前端 |
electric-fence
|
http://qa.debian.org/popcon.php?package=electric-fence | 46 | malloc(3) 调试器 |
leaktracer
|
http://qa.debian.org/popcon.php?package=leaktracer | 116 | C++ 程序的内存泄漏跟踪器 |
libdmalloc5
|
http://qa.debian.org/popcon.php?package=libdmalloc5 | 325 | 调试内存分配库 |
表 12.14. 静态代码分析工具列表
软件包 | popcon | 大小 | 描述 |
---|---|---|---|
splint
|
http://qa.debian.org/popcon.php?package=splint | 1836 | 用于静态检查 C 程序中错误的工具 |
rats
|
http://qa.debian.org/popcon.php?package=rats | 876 | 用于安全性的粗略审计工具 (C, C++, PHP, Perl 和 Python 代码) |
flawfinder
|
http://qa.debian.org/popcon.php?package=flawfinder | 188 | 用于检查 C/C++ 源代码并查找安全漏洞的工具 |
perl
|
http://qa.debian.org/popcon.php?package=perl | 17077 | 带有内部静态代码检查器的解释器:B::Lint(3perl) |
pylint
|
http://qa.debian.org/popcon.php?package=pylint | 416 | Python 代码静态检查器 |
jlint
|
http://qa.debian.org/popcon.php?package=jlint | 156 | Java 程序检查器 |
weblint-perl
|
http://qa.debian.org/popcon.php?package=weblint-perl | 57 | HTML 的语法和最小样式检查器 |
linklint
|
http://qa.debian.org/popcon.php?package=linklint | 432 | 快速链接检查器和网站维护工具 |
libxml2-utils
|
http://qa.debian.org/popcon.php?package=libxml2-utils | 139 | 带有 xmllint(1) 的实用程序,用于验证 XML 文件 |
Flex 是一个与 Lex 兼容的快速 词法分析器 生成器。
可以在 “info flex
” 中找到 flex(1) 的教程。
您需要提供自己的 “main()
” 和 “yywrap()
”。 否则,您的 flex 程序应如下所示进行编译,而无需库。 这是因为 “yywrap
” 是一个宏,并且 “%option main
” 隐式地打开了 “%option noyywrap
”。
%option main %% .|\n ECHO ; %%
或者,您可以在 cc(1) 命令行末尾使用 “-lfl
” 链接器选项进行编译(如带有 “-ll
” 的 AT&T-Lex)。 在这种情况下,不需要 “%option
”。
一些软件包在 Debian 中提供了与 Yacc 兼容的前瞻 LR 解析器 或 LALR 解析器 生成器。
表 12.15. Yacc 兼容 LALR 解析器生成器列表
软件包 | popcon | 大小 | 描述 |
---|---|---|---|
bison
|
http://qa.debian.org/popcon.php?package=bison | 1518 | GNU LALR 解析器生成器 |
byacc
|
http://qa.debian.org/popcon.php?package=byacc | 143 | Berkeley LALR 解析器生成器 |
btyacc
|
http://qa.debian.org/popcon.php?package=btyacc | 248 | 基于 byacc 的回溯解析器生成器 |
bison(1) 的教程可以在 "info bison
" 中找到。
你需要提供你自己的 "main()
" 和 "yyerror()
"。 "main()
" 调用 "yyparse()
",后者调用 "yylex()
",通常用 Flex 创建。
%% %%
Autoconf 是一个用于生成 shell 脚本的工具,这些脚本可以自动配置软件包的源代码,以适应许多类 Unix 系统,它使用了完整的 GNU 构建系统。
autoconf(1) 生成配置文件脚本 "configure
"。 "configure
" 使用 "Makefile.in
" 模板自动创建自定义的 "Makefile
"。
![]() |
警告 |
---|---|
安装编译后的程序时,不要覆盖系统文件。 |
Debian 不会触及 "/usr/local/
" 或 "/opt
" 中的文件。 因此,如果你从源代码编译程序,请将其安装到 "/usr/local/
" 中,这样它就不会干扰 Debian。
$ cd src $ ./configure --prefix=/usr/local $ make $ make install # this puts the files in the system
如果你有原始源代码,并且它使用了 autoconf(1)/automake(1),并且你还记得你是如何配置它的,请按如下方式执行以卸载程序。
$ ./configure "all-of-the-options-you-gave-it" # make uninstall
或者,如果你绝对确定安装过程仅将文件放在 "/usr/local/
" 下,并且那里没有任何重要的东西,你可以通过以下方式删除其所有内容。
# find /usr/local -type f -print0 | xargs -0 rm -f
如果你不确定文件安装在哪里,你应该考虑使用 checkinstall
包中的 checkinstall(8),它为卸载提供了干净的路径。 它现在支持使用 "-D
" 选项创建 Debian 软件包。
虽然任何 AWK 脚本都可以使用 a2p(1) 自动重写为 Perl,但单行 AWK 脚本最好手动转换为单行 Perl 脚本。
让我们考虑以下 AWK 脚本代码片段。
awk '($2=="1957") { print $3 }' |
这等同于以下任何一行。
perl -ne '@f=split; if ($f[1] eq "1957") { print "$f[2]\n"}' |
perl -ne 'if ((@f=split)[1] eq "1957") { print "$f[2]\n"}' |
perl -ne '@f=split; print $f[2] if ( $f[1]==1957 )' |
perl -lane 'print $F[2] if $F[1] eq "1957"' |
perl -lane 'print$F[2]if$F[1]eq+1957' |
最后一个是一个谜题。 它利用了以下 Perl 特性。
空格是可选的。
存在从数字到字符串的自动转换。
有关命令行选项,请参阅 perlrun(1)。 有关更多疯狂的 Perl 脚本,Perl Golf 可能会很有趣。
基本交互式动态网页可以按如下方式制作。
使用 HTML 表单向浏览器用户呈现查询。
填写并单击表单条目会从浏览器向 Web 服务器发送以下 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
"
URL 中的 "%nn
" 将被替换为十六进制值为 nn
的字符。
环境变量设置为: "QUERY_STRING="VAR1=VAL1 VAR2=VAL2 VAR3=VAL3"
"。
Web 服务器上的 CGI 程序("program.*
" 中的任何一个)使用环境变量 "$QUERY_STRING
" 执行自身。
CGI 程序的 stdout
被发送到 Web 浏览器,并呈现为交互式动态网页。
出于安全原因,最好不要手工制作新的 hack 来解析 CGI 参数。 在 Perl 和 Python 中有成熟的模块用于处理它们。 PHP 自带这些功能。 当需要客户端数据存储时,使用 HTTP cookies。 当需要客户端数据处理时,经常使用 Javascript。
更多信息,请参阅 Common Gateway Interface、The Apache Software Foundation 和 JavaScript。
在 Google 上搜索 "CGI tutorial",直接在浏览器地址中输入编码的 URL http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial,是查看 CGI 脚本在 Google 服务器上运行情况的好方法。
有一些程序可以转换源代码。
表 12.16. 源代码转换工具列表
软件包 | popcon | 大小 | 关键词 | 描述 |
---|---|---|---|---|
perl
|
http://qa.debian.org/popcon.php?package=perl | 17077 | AWK→PERL | 将源代码从 AWK 转换为 PERL: a2p(1) |
f2c
|
http://qa.debian.org/popcon.php?package=f2c | 424 | FORTRAN→C | 将源代码从 FORTRAN 77 转换为 C/C++: f2c(1) |
protoize
|
http://qa.debian.org/popcon.php?package=protoize | 125 | ANSI C | 从 C 代码创建/删除 ANSI 原型 |
intel2gas
|
http://qa.debian.org/popcon.php?package=intel2gas | 72 | intel→gas | 从 NASM (Intel 格式) 到 GNU 汇编器 (GAS) 的转换器 |
如果你想制作 Debian 软件包,请阅读以下内容。
第 2 章,Debian 软件包管理 以了解基本的软件包系统
第 2.7.13 节,“将软件包移植到稳定系统” 以了解基本的移植过程
第 9.8.4 节,“Chroot 系统” 以了解基本的 chroot 技术
debuild(1), pbuilder(1) 和 pdebuild(1)
第 12.4.2 节,“调试 Debian 软件包”,了解为调试而重新编译
Debian 新维护者指南,作为教程 ( maint-guide
软件包)
Debian 开发者参考 ( developers-reference
软件包)
Debian 策略手册 ( debian-policy
软件包)
有一些软件包可以帮助打包,例如 dh-make
, dh-make-perl
等。