目录
這裏我給出一些 Debian 系統中的信息,幫助學習編程的人找出打包的源代碼。下面是值得關注的軟件包和與之對應的文檔。
表 12.1. 幫助編程的軟件包清單
軟件包 | 流行度 | 大小 | 包 |
---|---|---|---|
autoconf
|
V:29, I:226 | 1868 |
由 autoconf-doc 包提供的“info autoconf ”
|
automake
|
V:27, I:220 | 1707 |
由 automake1.10-doc 包提供的“info automake ”
|
bash
|
V:853, I:999 | 5799 |
由 bash-doc 包提供的“info bash ”
|
bison
|
V:10, I:113 | 2061 |
由 bison-doc 包提供的“info bison ”
|
cpp
|
V:394, I:806 | 41 |
由 cpp-doc 包提供的“info cpp ”
|
ddd
|
V:1, I:13 | 3965 |
由 ddd-doc 包提供的“info ddd ”
|
exuberant-ctags
|
V:7, I:38 | 333 | exuberant-ctags(1) |
flex
|
V:10, I:101 | 1174 |
由 flex-doc 包提供的“info flex ”
|
gawk
|
V:355, I:478 | 2199 |
由 gawk-doc 包提供的“info gawk ”
|
gcc
|
V:148, I:606 | 43 |
由 gcc-doc 包提供的“info gcc ”
|
gdb
|
V:21, I:140 | 7983 |
由 gdb-doc 包提供的“info gdb ”
|
gettext
|
V:53, I:367 | 7076 |
由 gettext-doc 包提供的“info gettext ”
|
gfortran
|
V:20, I:63 | 16 |
由 gfortran-doc 包提供的“info
gfortran ”(Fortran 95)
|
fpc
|
I:4 | 113 | fpc(1)
和由 fp-docs 包提供的 html 文檔(Pascal)
|
glade
|
V:1, I:12 | 2209 | 通過 UI Builder 菜單提供的文檔 |
libc6
|
V:933, I:999 | 10679 |
通過 glibc-doc 和 glibc-doc-reference
提供的“info libc ”
|
make
|
V:154, I:622 | 1211 |
通過 make-doc 包提供的“info make ”
|
xutils-dev
|
V:2, I:18 | 1466 | imake(1),xmkmf(1) 等。 |
mawk
|
V:371, I:997 | 183 | mawk(1) |
perl
|
V:610, I:996 | 651 | perl(1)
以及通過 perl-doc 和 perl-doc-html 提供的 html
文檔
|
python
|
V:683, I:988 | 648 | python(1)
以及通過 python-doc 包提供的 html 文檔 |
tcl8.4
|
V:3, I:50 | NOT_FOUND | tcl(3)
以及通過 tcl8.4-doc 包提供的更詳細的手冊頁文檔 |
tk8.4
|
V:1, I:31 | NOT_FOUND | tk(3)
以及通過 tk8.4-doc 包提供的更詳細的手冊頁文檔 |
ruby
|
V:103, I:321 | 38 | ruby(1)
以及通過 ri 包提供的交互式參考手冊 |
vim
|
V:118, I:393 | 2374 |
通過 vim-doc 包提供的幫助(F1)菜單
|
susv2
|
I:0 | 15 | 通過“單一UNIX規範(版本2)”獲取(英語文檔) |
susv3
|
I:0 | 15 | 通過“單一UNIX規範(版本3)”獲取(英語文檔) |
安裝 manpages
和 manpages-dev
包之後,可以通過運行“man 名稱
”查看手冊頁中的參考信息。安裝了 GNU
工具的相關文檔包之後,可以通過運行“info 程序名稱
”查看參考文檔。某些 GFDL 協議的文檔與 DFSG
並不兼容,所以你可能需要在 main
倉庫中包含 contrib
和
non-free
才能下載並安裝它們。
![]() |
警告 |
---|---|
不要用“ |
![]() |
小心 |
---|---|
你可以把從源代碼編譯得到的程序直接放到“ |
![]() |
提示 |
---|---|
“歌曲:99瓶啤酒”的代碼示例可以給你提供實踐各種語言的好範本。 |
Shell 腳本 是指包含有下面格式的可執行的文本文件。
#!/bin/sh …… 命令
第一行指明瞭讀取並執行這個文件的 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
”,它是某個實際 shell 程序的鏈接。
對 lenny
或更老的系統來說,它是
bash(1)
dash(1)
供 squeeze
或更新的版本
Avoid writing a shell script with bashisms or zshisms to make it portable among all POSIX shells. You can check it using checkbashisms(1).
表 12.2. List of typical bashisms
Good: POSIX | Avoid: 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() { … }
|
octal format: "\377 "
|
hexadecimal format: "\xff "
|
The "echo
" command must be used with following cares
since its implementation differs among shell builtin and external commands.
Avoid using any command options except "-n
".
Avoid using escape sequences in the string since their handling varies.
![]() |
注意 |
---|---|
Although " |
![]() |
提示 |
---|---|
Use the " |
特殊的 shell 引數經常在 shell 腳本里面被用到。
表 12.3. shell 引數列表
shell 引數 | 值 |
---|---|
$0
|
shell 或 shell 指令碼的名稱 |
$1
|
第一個 shell 引數 |
$9
|
第 9 個 shell 引數 |
$#
|
位置引數數量 |
"$*"
|
"$1 $2 $3 $4 … "
|
"$@"
|
"$1" "$2" "$3" "$4" …
|
$?
|
最近一次命令的退出狀態碼 |
$$
|
這個 shell 指令碼的 PID |
$!
|
最近開始的後臺任務 PID |
Basic parameter expansions to remember are as follows.
表 12.4. List of shell parameter expansions
parameter expression form |
value if var is set
|
value if var is not set
|
---|---|---|
${var:-string}
|
"$var "
|
"string "
|
${var:+string}
|
"string "
|
"null "
|
${var:=string}
|
"$var "
|
"string " (and run "var=string ")
|
${var:?string}
|
"$var "
|
echo "string " to stderr (and exit with error)
|
Here, the colon ":
" in all of these operators is actually
optional.
with ":
" = operator
test for exist and not null
without ":
" = operator
test for exist only
表 12.5. List of key shell parameter substitutions
parameter substitution form | result |
---|---|
${var%suffix}
|
remove smallest suffix pattern |
${var%%suffix}
|
remove largest suffix pattern |
${var#prefix}
|
remove smallest prefix pattern |
${var##prefix}
|
remove largest prefix pattern |
Each command returns an exit status which can be used for conditional expressions.
Success: 0 ("True")
Error: non 0 ("False")
![]() |
注意 |
---|---|
"0" in the shell conditional context means "True", while "0" in the C conditional context means "False". |
![]() |
注意 |
---|---|
" |
Basic conditional idioms to remember are the following.
"<command> && <if_success_run_this_command_too>
|| true
"
"<command> || <if_not_success_run_this_command_too> ||
true
"
A multi-line script snippet as the following
if [ <conditional_expression> ]; then <if_success_run_this_command> else <if_not_success_run_this_command> fi
Here trailing "|| true
" was needed to ensure this shell
script does not exit at this line accidentally when shell is invoked with
"-e
" flag.
表 12.6. 在條件表示式中進行檔案比較
表示式 | 返回邏輯真所需的條件 |
---|---|
-e <file>
|
<file> 存在 |
-d <file>
|
<file> 存在並且是一個目錄 |
-f <file>
|
<file> 存在並且是一個普通檔案 |
-w <file>
|
<file> 存在並且可寫 |
-x <file>
|
<file> 存在並且可執行 |
<file1> -nt <file2>
|
<file1> is newer than <file2> (modification) |
<file1> -ot <file2>
|
<file1> is older than <file2> (modification) |
<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
" 可以用來重新開始下一次迴圈。
![]() |
提示 |
---|---|
The C-language like numeric iteration can be
realized by using
seq(1)
as the " |
![]() |
提示 |
---|---|
shell 大致以下列的順序來處理一個指令碼。
shell 讀取一行。
The shell groups a part of the line as one
token if it is within "…"
or
'…'
.
shell 通過下列方式將行中的其它部分分隔進 tokens。
空白字元:<空格> <tab> <換行符>
元字元:< > | ; & ( )
shell 會檢查每一個不位於 "…"
或 '...'
的 token 中的
關鍵字 來調整它的行為。
關鍵字: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 將不位於 "…"
或 '...'
中的 glob 路徑 展開為匹配的檔名。
*
→ 任何字元
?
→ 一個字元
[…]
→ 任何位於 "…
" 中的字元
shell 從下列幾方面查詢 命令 並執行。
函式 定義
內建命令
“$PATH
” 中的可執行檔案
shell 前往下一行,並按照這個順序從頭再次進行處理。
雙引號中的單引號是沒有效果的。
在 shell 中執行 “set -x
” 或使用 “-x
” 選項啟動
shell 可以讓 shell 顯示出所有執行的命令。這對除錯來說是非常方便的。
為了使你的 shell 程式在 Debian 系統上儘可能地具有可移植性,你應該只使用 必要的 軟體包所提供的應用程式。
"aptitude search ~E
",列出 必要的 軟體包。
"dpkg -L <package_name> |grep '/man/man.*/'
",列出
<package_name>
軟體包所提供的 man 手冊。
表 12.8. 包含用於 shell 指令碼的小型應用程式的軟體包
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
coreutils
|
V:881, I:999 | 15103 | GNU 核心工具 |
debianutils
|
V:934, I:999 | 213 | 用於 Debian 的各種工具 |
bsdmainutils
|
V:866, I:998 | 566 | 來自 FreeBSD 更多的工具集合 |
bsdutils
|
V:851, I:999 | 238 | 來自 4.4BSD-Lite 的基礎工具 |
moreutils
|
V:4, I:19 | 201 | 額外的 Unix 工具 |
![]() |
提示 |
---|---|
儘管 |
一個簡單的 shell 程式的使用者介面中,echo
和 read
命令的互動性較為一般,你可以使用對話程式等來提升互動性。
表 12.9. 使用者介面程式列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
x11-utils
|
V:305, I:635 | 637 | xmessage(1):在一個視窗中顯示一條訊息或疑問(X) |
whiptail
|
V:415, I:995 | 68 | 從 shell 指令碼中顯示使用者友好的對話方塊(newt) |
dialog
|
V:29, I:151 | 1111 | 從 shell 指令碼中顯示使用者友好的對話方塊(ncurses) |
zenity
|
V:112, I:425 | 362 | 從 shell 指令碼中顯示圖形對話方塊(gtk2.0) |
ssft
|
V:0, I:0 | 129 | Shell Scripts Frontend Tool (wrapper for zenity, kdialog, and dialog with gettext) |
gettext
|
V:53, I:367 | 7076 |
“/usr/bin/gettext.sh ”:翻譯資訊
|
下面是一個簡單的指令碼,它通過 dvdisaster(1) 建立了帶有 RS02 補充資料的 ISO 映像。
#!/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
,自從上次目標檔案被修改後,如果目標檔案依賴的相關檔案發生了改變,那麼就會更新目標檔案,或者目標檔案不存在,那麼這些檔案更新可能會同時發生。
規則檔案的語法如下所示。
目標:[相關檔案 ...] [TAB] 命令1 [TAB] -命令2 # 忽略錯誤 [TAB] @命令3 # 禁止回顯
Here "[TAB]
" is a TAB code. Each line is interpreted by
the shell after make variable substitution. Use "\
" at
the end of a line to continue the script. Use "$$
" to
enter "$
" for environment values for a shell script.
目標跟相關檔案也可以通過隱式規則給出,例如,如下所示。
%.o: %.c header.h
在這裡,目標包含了 "%
" 字元 (只是它們中確切的某一個)。"%
"
字元能夠匹配實際的目標檔案中任意一個非空的子串。相關檔案同樣使用 "%
" 來表明它們是怎樣與目標檔案建立聯絡的。
表 12.10. 自動變數的列表
自動變數 | 值 |
---|---|
$@
|
當前目標 |
$<
|
首個相關檔案 |
$?
|
所有較新的相關檔案 |
$^
|
所有相關檔案 |
$*
|
"% " matched stem in the target pattern
|
執行 "make -p -f/dev/null
" 命令來檢視內部自動化的規則。
你可以通過下列方法設定適當的環境來編譯使用 C 程式語言編寫的程式。
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
libc6-dev
軟體包,即 GNU C 庫,提供了 C 標準庫,它包含了 C 程式語言所使用的標頭檔案和庫例程。
參考資訊如下。
“info libc
”(C 庫函式參考)
gcc(1)
和 “info gcc
”
each_C_library_function_name(3)
Kernighan & Ritchie,“C 程式設計語言”,第二版(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
為了使用
sqrt(3),必須使用
“-lm
” 連結來自 libc6
軟體包的庫
“/usr/lib/libm.so
”。實際的庫檔案位於
“/lib/
”,檔名為 “libm.so.6
”,它是指向
“libm-2.7.so
” 的一個連結。
請看一下輸出文字的最後一段。即使指定了 “%10s
”,它依舊超出了 10 個字元。
The use of pointer memory operation functions without boundary checks, such as sprintf(3) and strcpy(3), is deprecated to prevent buffer overflow exploits that leverage the above overrun effects. Instead, use snprintf(3) and strncpy(3).
除錯是程式中很重要的一部分。知道怎樣去除錯程式使得作為 Debian 使用者的你, 能夠做出有意義的錯誤報告。
Debian 上原始的偵錯程式是 gdb(1), 它能讓你在程式執行的時候檢查程式。
讓我們通過如下所示的命令來安裝 gdb
及其相關程式。
# apt-get install gdb gdb-doc build-essential devscripts
gdb
的好的教程由 "info gdb
" 提供或者可以在網上的其他地方找到。如下是用
gdb(1)
在"程式
"帶有 "-g
" 選項編譯的時候來產生除錯資訊。
$ gdb program (gdb) b 1 # 在第一行設定斷點 (gdb) run args # 帶引數執行程式 (gdb) next # 執行下一步 ... (gdb) step # 單步進入 ... (gdb) p parm # 列印 parm 的值 ... (gdb) p parm=12 # 把值設為 12 ... (gdb) quit
![]() |
提示 |
---|---|
許多 gdb(1) 命令都能被縮寫。Tab 擴充套件跟在 shell 一樣都能工作。 |
Since all installed binaries should be stripped on the Debian system by
default, most debugging symbols are removed in the normal package. In order
to debug Debian packages with
gdb(1),
corresponding *-dbg
packages need to be installed
(e.g. libc6-dbg
in the case of libc6
).
If a package to be debugged does not provide its *-dbg
package, you need to install it after rebuilding it by the following.
$ 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*
Fix bugs if needed.
Bump package version to one which does not collide with official Debian
versions, e.g. one appended with "+debug1
" when
recompiling existing package version, or one appended with
"~pre1
" when compiling unreleased package version by the
following.
$ dch -i
Compile and install packages with debug symbols by the following.
$ export DEB_BUILD_OPTIONS=nostrip,noopt $ debuild $ cd .. $ sudo debi package_name*.changes
You need to check build scripts of the package and ensure to use
"CFLAGS=-g -Wall
" for compiling binaries.
When you encounter program crash, reporting bug report with cut-and-pasted backtrace information is a good idea.
The backtrace can be obtained by the following steps.
Run the program under gdb(1).
Reproduce crash.
It causes you to be dropped back to the gdb
prompt.
Type "bt
" at the gdb
prompt.
In case of program freeze, you can crash the program by pressing
Ctrl-C
in the terminal running gdb
to
obtain gdb
prompt.
![]() |
提示 |
---|---|
Often, you see a backtrace where one or more of the top lines are in
" |
$ MALLOC_CHECK_=2 gdb hello
表 12.12. 高階 gdb 命令列表
命令 | 命令用途的描述 |
---|---|
(gdb) thread apply all bt
|
get a backtrace for all threads for multi-threaded program |
(gdb) bt full
|
get parameters came on the stack of function calls |
(gdb) thread apply all bt full
|
get a backtrace and parameters as the combination of the preceding options |
(gdb) thread apply all bt full 10
|
get a backtrace and parameters for top 10 calls to cut off irrelevant output |
(gdb) set logging on
|
write log of gdb output to a file (the default is
"gdb.txt ")
|
If a GNOME program preview1
has received an X error, you
should see a message as follows.
The program 'preview1' received an X Window System error.
If this is the case, you can try running the program with
"--sync
", and break on the
"gdk_x_error
" function in order to obtain a backtrace.
Use ldd(1) to find out a program's dependency on libraries by the followings.
$ 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)
For ls(1) to work in a `chroot`ed environment, the above libraries must be available in your `chroot`ed environment.
See 第 9.3.6 节 “跟蹤程式活動”.
Debian 上有一些可用的記憶體洩漏檢測工具。
表 12.13. 記憶體洩漏檢測工具的列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
libc6-dev
|
V:269, I:615 | 15628 | mtrace(1): malloc debugging functionality in glibc |
valgrind
|
V:8, I:56 | 70463 | memory debugger and profiler |
kmtrace
|
V:1, I:18 | 351 | KDE memory leak tracer using glibc's mtrace(1) |
alleyoop
|
V:0, I:1 | 655 | GNOME front-end to the Valgrind memory checker |
electric-fence
|
V:0, I:6 | 70 | malloc(3) debugger |
leaktracer
|
V:0, I:2 | 56 | C++ 程式記憶體洩露跟蹤器 |
libdmalloc5
|
V:0, I:3 | 360 | 記憶體分配庫除錯 |
There are lint like tools for static code analysis.
表 12.14. 靜態程式碼分析工具的列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
splint
|
V:0, I:5 | 1889 | tool for statically checking C programs for bugs |
flawfinder
|
V:0, I:1 | 175 | tool to examine C/C++ source code and looks for security weaknesses |
perl
|
V:610, I:996 | 651 | interpreter with internal static code checker: B::Lint(3perl) |
pylint
|
V:6, I:15 | 945 | Python code static checker |
weblint-perl
|
V:0, I:2 | 34 | syntax and minimal style checker for HTML |
linklint
|
V:0, I:1 | 343 | fast link checker and web site maintenance tool |
libxml2-utils
|
V:24, I:318 | 177 | utilities with xmllint(1) to validate XML files |
Flex is a Lex-compatible fast lexical analyzer generator.
Tutorial for
flex(1)
can be found in "info flex
".
You need to provide your own "main()
" and
"yywrap()
". Otherwise, your flex program should look
like this to compile without a library. This is because that
"yywrap
" is a macro and "%option main
"
turns on "%option noyywrap
" implicitly.
%option main %% .|\n ECHO ; %%
Alternatively, you may compile with the "-lfl
" linker
option at the end of your
cc(1)
command line (like AT&T-Lex with "-ll
"). No
"%option
" is needed in this case.
Several packages provide a Yacc-compatible lookahead LR parser or LALR parser generator in Debian.
表 12.15. List of Yacc-compatible LALR parser generators
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
bison
|
V:10, I:113 | 2061 | GNU LALR parser generator |
byacc
|
V:0, I:7 | 160 | Berkeley LALR parser generator |
btyacc
|
V:0, I:0 | 207 |
backtracking parser generator based on byacc
|
Tutorial for
bison(1)
can be found in "info bison
".
You need to provide your own "main()
" and
"yyerror()
". "main()
" calls
"yyparse()
" which calls "yylex()
",
usually created with Flex.
%% %%
Autoconf is a tool for producing shell scripts that automatically configure software source code packages to adapt to many kinds of Unix-like systems using the entire GNU build system.
autoconf(1)
produces the configuration script
"configure
". "configure
" automatically
creates a customized "Makefile
" using the
"Makefile.in
" template.
![]() |
警告 |
---|---|
當你安裝編譯好的程式的時候,注意不要覆蓋系統檔案。 |
Debian 不會在 "/usr/local
" 或 "/opt
"
目錄下建立檔案。如果你想要原始碼編譯程式,把它安裝到 "/usr/local/
" 目錄下,因為這並不會影響到
Debian。
$ cd src $ ./configure --prefix=/usr/local $ make $ make install # 這一步是把檔案安裝到系統上
如果你有原始碼並且它使用 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
If you are not sure where files are installed, you should consider using
checkinstall(8)
from the checkinstall
package, which provides a clean
path for the uninstall. It now supports to create a Debian package with
"-D
" option.
Although any AWK scripts can be automatically rewritten in Perl using a2p(1), one-liner AWK scripts are best converted to one-liner Perl scripts manually.
Let's think following AWK script snippet.
awk '($2=="1957") { print $3 }' |
This is equivalent to any one of the following lines.
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' |
The last one is a riddle. It took advantage of following Perl features.
The whitespace is optional.
The automatic conversion exists from number to the string.
See perlrun(1) for the command-line options. For more crazy Perl scripts, Perl Golf may be interesting.
Basic interactive dynamic web pages can be made as follows.
Queries are presented to the browser user using HTML forms.
Filling and clicking on the form entries sends one of the following URL string with encoded parameters from the browser to the web server.
"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
" 是使用一個 16 進位制字元的 nn
值代替。
環境變數設定為: "QUERY_STRING="VAR1=VAL1 VAR2=VAL2 VAR3=VAL3"
".
CGI program (any one of
"program.*
") on the web server executes itself with the
environment variable "$QUERY_STRING
".
CGI 程式的 stdout
傳送到瀏覽器,作為互動式的動態 web 頁面展示。
For security reasons it is better not to hand craft new hacks for parsing CGI parameters. There are established modules for them in Perl and Python. PHP comes with these functionalities. When client data storage is needed, HTTP cookies are used. When client side data processing is needed, Javascript is frequently used.
更多資訊,參見 通用閘道器介面, Apache 軟體基金會, 和 JavaScript.
Searching "CGI tutorial" on Google by typing encoded URL http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial directly to the browser address is a good way to see the CGI script in action on the Google server.
如果你想製作一個 Debian 包,閱讀下面內容。
第 2 章 Debian 軟體包管理 理解基本的包管理系統
第 2.7.13 节 “移植一個軟體包到 stable 系統” 理解基本的移植過程
第 9.10.4 节 “Chroot 系統” 理解基本的 chroot 技術
debuild(1), pbuilder(1) 和 pdebuild(1)
Debian 新維護者指引
作為一個教程(maint-guide
包)
Debian 開發者參考手冊
(developers-reference
包)
Debian 策略手冊
(debian-policy
包)
Debian 維護者指引
(debmake-doc
包)
debmake
, dh-make
,
dh-make-perl
等軟體包,對軟體包打包過程,也有幫助。