目录
這裡我給出一些 Debian 系統中的資訊,幫助學習程式設計的人找出打包的原始碼。下面是值得關注的軟體包和與之對應的文件。
表 12.1. 幫助程式設計的軟體包清單
軟件包 | 流行度 | 大小 | 包 |
---|---|---|---|
autoconf
|
V:38, I:269 | 1868 |
由 autoconf-doc 包提供的“info autoconf ”
|
automake
|
V:37, I:265 | 1784 |
由 automake1.10-doc 包提供的“info automake ”
|
bash
|
V:826, I:999 | 6462 |
由 bash-doc 包提供的“info bash ”
|
bison
|
V:11, I:109 | 2253 |
由 bison-doc 包提供的“info bison ”
|
cpp
|
V:389, I:790 | 42 |
由 cpp-doc 包提供的“info cpp ”
|
ddd
|
V:0, I:12 | 3929 |
由 ddd-doc 包提供的“info ddd ”
|
exuberant-ctags
|
V:7, I:42 | 333 | exuberant-ctags(1) |
flex
|
V:10, I:98 | 1225 |
由 flex-doc 包提供的“info flex ”
|
gawk
|
V:443, I:535 | 2412 |
由 gawk-doc 包提供的“info gawk ”
|
gcc
|
V:173, I:598 | 45 |
由 gcc-doc 包提供的“info gcc ”
|
gdb
|
V:17, I:124 | 8989 |
由 gdb-doc 包提供的“info gdb ”
|
gettext
|
V:52, I:345 | 6594 |
由 gettext-doc 包提供的“info gettext ”
|
gfortran
|
V:8, I:79 | 16 |
由 gfortran-doc 包提供的“info
gfortran ”(Fortran 95)
|
fpc
|
I:4 | 120 | fpc(1)
和由 fp-docs 包提供的 html 文檔(Pascal)
|
glade
|
V:1, I:9 | 2306 | 通過 UI Builder 菜單提供的文檔 |
libc6
|
V:937, I:999 | 12333 |
通過 glibc-doc 和 glibc-doc-reference
提供的“info libc ”
|
make
|
V:169, I:604 | 1296 |
通過 make-doc 包提供的“info make ”
|
xutils-dev
|
V:1, I:14 | 1466 | imake(1),xmkmf(1) 等。 |
mawk
|
V:342, I:998 | 183 | mawk(1) |
perl
|
V:618, I:994 | 575 | perl(1)
以及通過 perl-doc 和 perl-doc-html 提供的 html
文檔
|
python
|
V:578, I:986 | 68 | python(1)
以及通過 python-doc 包提供的 html 文檔 |
tcl
|
V:30, I:442 | 22 | tcl(3)
以及通過 tcl-doc 包提供的更詳細的手冊頁文件 |
tk
|
V:31, I:433 | 22 | tk(3)
以及通過 tk-doc 包提供的更詳細的手冊頁文件 |
ruby
|
V:173, I:341 | 37 | ruby(1)
以及通過 ri 包提供的交互式參考手冊 |
vim
|
V:119, I:395 | 2799 |
通過 vim-doc 包提供的幫助(F1)菜單
|
susv2
|
I:0 | 16 | 通過“單一UNIX規範(版本2)”獲取(英語文檔) |
susv3
|
I:0 | 16 | 通過“單一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
或更新的版本
避免編寫具有 bashisms(bash 化)或者 zshisms(zsh 化)語法的 shell 指令碼,確保指令碼在所有 POSIX shell 之間具有可移植性。你可以使用 checkbashisms(1) 對其進行檢查。
表 12.2. 典型 bashism 語法列表
好的: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 和外部命令的不同,它的實現也有差別。
避免使用除“-n
”以外的任何命令列選項。
避免在字串中使用轉義序列,因為根據 shell 不同,計算後的結果也不一樣。
![]() |
注意 |
---|---|
儘管“ |
![]() |
提示 |
---|---|
如果你想要在輸出字串中嵌入轉義序列,用 " |
特殊的 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 |
如下所示是需要記憶的基本的引數展開。
表 12.4. shell 引數展開列表
引數表示式形式 |
如果 var 變數已設定那麼值為
|
如果 var 變數沒有被設定那麼值為
|
---|---|---|
${var:-string}
|
"$var "
|
"string "
|
${var:+string}
|
"string "
|
"null "
|
${var:=string}
|
"$var "
|
"string " (並執行 "var=string ")
|
${var:?string}
|
"$var "
|
在 stderr 中顯示 "string "
(出錯退出)
|
以上這些操作中 ":
" 實際上都是可選的。
有 ":
" 等於測試的 var
值是存在且非空
沒有 ":
" 等於測試的 var
值只是存在的,可以為空
表 12.5. 重要的 shell 引數替換列表
引數替換形式 | 結果 |
---|---|
${var%suffix}
|
刪除位於 var 結尾的 suffix 最小匹配模式 |
${var%%suffix}
|
刪除位於 var 結尾的 suffix 最大匹配模式 |
${var#prefix}
|
刪除位於 var 開頭的 prefix 最小匹配模式 |
${var##prefix}
|
刪除位於 var 開頭的 prefix 最大匹配模式 |
每個命令都會返回 退出狀態,這可以被條件語句使用。
成功:0 ("True")
失敗:非0 ("False")
![]() |
注意 |
---|---|
"0" 在 shell 條件語句中的意思是 "True",然而 "0" 在 C 條件語句中的含義為 "False"。 |
![]() |
注意 |
---|---|
" |
如下所示是需要記憶的基礎 條件語法。
"<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
”選項而被呼叫時不會在該行意外地退出。
表 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 對該行各部分進行分組作為
一個標識(one token) (譯註:one token 是指 shell
識別的一個結構單元).
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:888, I:999 | 15719 | GNU 核心工具 |
debianutils
|
V:941, I:999 | 226 | 用於 Debian 的各種工具 |
bsdmainutils
|
V:861, I:999 | 587 | 來自 FreeBSD 更多的工具集合 |
bsdutils
|
V:866, I:999 | 293 | 來自 4.4BSD-Lite 的基礎工具 |
moreutils
|
V:5, I:24 | 237 | 額外的 Unix 工具 |
![]() |
提示 |
---|---|
儘管 |
一個簡單的 shell 程式的使用者介面中,echo
和 read
命令的互動性較為一般,你可以使用對話程式等來提升互動性。
表 12.9. 使用者介面程式列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
x11-utils
|
V:375, I:635 | 631 | xmessage(1):在一個視窗中顯示一條訊息或疑問(X) |
whiptail
|
V:434, I:996 | 70 | 從 shell 指令碼中顯示使用者友好的對話方塊(newt) |
dialog
|
V:17, I:125 | 1168 | 從 shell 指令碼中顯示使用者友好的對話方塊(ncurses) |
zenity
|
V:229, I:395 | 369 | 從 shell 指令碼中顯示圖形對話方塊(gtk2.0) |
ssft
|
V:0, I:0 | 75 | Shell 指令碼前端工具 (zenity, kdialog, and 帶有 gettext 的 dialog 封裝) |
gettext
|
V:52, I:345 | 6594 |
“/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 # 禁止回顯
這裡面的 "[TAB]
" 是一個 TAB 程式碼。每一行在進行變數替換以後會被 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 程式語言所使用的標頭檔案和庫例程。
參考資訊如下。
“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 個字元。
使用沒有邊界檢查的指標記憶體操作函式,比如 sprintf(3) 和 strcpy(3), 是不建議使用,是為防止快取溢位洩露而導致上面的溢位問題。請使用 snprintf(3) 和 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 一樣都能工作。 |
因為在 Debian 系統上預設所有已安裝的二進位制程式都是精簡的,絕大多數的除錯符號已經從常規的軟體包中移除了。為了能用
gdb(1)
除錯 Debian 軟體包,相對應的 *-dbg
軟體包或 *-dbgsym
軟體包需要被安裝 (例如 libc6
需要安裝
libc6-dbg
,coreutils
需要安裝
coreutils-dbgsym
)。
老式的軟體包將提供相應的 *-dbg
軟體包。它將和原始軟體包一起,直接放在 Debian main
檔案庫。對於新的軟體包,當它們編譯時,將會自動產生 *-dbgsym
軟體包,那些除錯軟體包將被獨立放在
debian-debug 檔案庫. 更多資訊請參閱 Debian Wiki 文件 .
如果一個需要被除錯的軟體包沒有提供其 *-dbg
軟體包或 *-dbgsym
軟體包,你需要按如下所示的從原始碼中重構並且安裝它。
$ mkdir /path/new ; cd /path/new $ sudo apt-get update $ sudo apt-get dist-upgrade $ sudo apt-get install fakeroot devscripts build-essential $ apt-get source package_name $ cd package_name* $ sudo apt-get build-dep ./
按需修改 bug。
軟體包除錯版本跟它的官方 Debian 版本不衝突,例如當重新編譯已存在的軟體包版本產生的 "+debug1
"
字尾,如下所示是編譯未發行的軟體包版本產生的 "~pre1
" 字尾。
$ dch -i
如下所示編譯並安裝帶有除錯符號的軟體包。
$ export DEB_BUILD_OPTIONS=nostrip noopt $ debuild $ cd .. $ sudo debi package_name*.changes
你需要檢查軟體包的構建指令碼並確保編譯二進位制的時候使用了 "CFLAGS=-g -Wall
" 選項。
當你碰到程式崩潰的時候,報告 bug 時附上棧幀資訊是個不錯的注意。
如下所示的步驟就可以取得棧幀資訊。
在 gdb(1) 中執行程式。
重現崩潰。
它使得你重新回到 gdb
提示符。
在 gdb
提示符後輸入 "bt
"。
程式在終端中的 gdb
環境執行時,如果它沒反應,你可以按下
Ctrl-C
來中止程式來取得 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 錯誤,您應當看見一條下面這樣的資訊。
'preview1' 程式出現 X 桌面系統錯誤。
如果就是這種情況,你可以嘗試在執行程式的時候加上 "--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`ed 環境,以上的庫在 `chroot`ed 環境也必須是可用的。
Debian 上有一些可用的記憶體洩漏檢測工具。
表 12.13. 記憶體洩漏檢測工具的列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
libc6-dev
|
V:276, I:613 | 18939 | mtrace(1):除錯 glibc 中的 malloc |
valgrind
|
V:7, I:52 | 80468 | 記憶體偵錯程式和分析器 |
electric-fence
|
V:0, I:5 | 70 | malloc(e) 偵錯程式 |
leaktracer
|
V:0, I:3 | 56 | C++ 程式記憶體洩露跟蹤器 |
libdmalloc5
|
V:0, I:3 | 393 | 記憶體分配庫除錯 |
表 12.14. 靜態程式碼分析工具的列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
splint
|
V:0, I:4 | 2239 | 靜態檢查 C 程式 bug 的工具 |
flawfinder
|
V:0, I:0 | 175 | 檢查 C/C++ 原始碼和查詢安全漏洞的工具 |
perl
|
V:618, I:994 | 575 | 帶有內部靜態程式碼檢測的直譯器:B::Lint(3perl) |
pylint
|
V:6, I:18 | 2668 | Python 程式碼靜態檢查器 |
weblint-perl
|
V:0, I:1 | 32 | 用於 HTML 的小巧的語法檢查器 |
linklint
|
V:0, I:0 | 343 | 快速的網站維護工具及連結檢查器 |
libxml2-utils
|
V:22, I:289 | 173 | 使用 xmllint(1) 來檢查 XML 檔案 |
可以使用 “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 解析器生成器列表
軟件包 | 流行度 | 大小 | 說明 |
---|---|---|---|
bison
|
V:11, I:109 | 2253 | GNU LALR 解析器生成器 |
byacc
|
V:0, I:6 | 160 | 伯克利(Berkeley)LALR 解析器生成器 |
btyacc
|
V:0, I:0 | 207 |
基於 byacc 的回溯解析生成器
|
可以使用 “info bison
” 檢視
bison(1)
的教程。
你需要提供你自己的的 "main()
" 和
"yyerror()
".通常,Flex 建立的 "main()
" 呼叫
"yyparse()
",它又呼叫了 "yylex()
".
%% %%
autoconf 是一種用於自動生成軟體原始碼包配置 shell 指令碼的工具,以適應使用完整 GNU 構建系統的各種類 Unix 系統。
autoconf(1)
生成配置指令碼 “configure
”。“configure
” 使用
“Makefile.in
” 模板自動生成一個自定義的 “Makefile
”。
![]() |
警告 |
---|---|
當你安裝編譯好的程式的時候,注意不要覆蓋系統檔案。 |
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
如果你不確定檔案被安裝到了哪裡,你可以考慮使用 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
" 是使用一個 16 進位制字元的 nn
值代替。
環境變數設定為: "QUERY_STRING="VAR1=VAL1 VAR2=VAL2 VAR3=VAL3"
".
Web伺服器上的CGI程式 (任何一個
"program.*
")在執行時,都會使用"$QUERY_STRING
"環境變數.
CGI 程式的 stdout
傳送到瀏覽器,作為互動式的動態 web 頁面展示。
出於安全考慮,最好不要自己從頭編寫解析CGI引數的手藝. 在Perl和Python中有現有的模組可以使用. PHP 中包含這些功能. 當需要客戶端資料儲存時, 可使用HTTP cookies . 當需要處理客戶端資料時, 通常使用Javascript.
更多資訊,參見 通用閘道器介面, Apache 軟體基金會, 和 JavaScript.
直接在瀏覽器地址中輸入 http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial 就可以在 Google 上搜索 “CGI tutorial”。這是在 Google 伺服器上檢視 CGI 指令碼執行的好方法。
如果你想製作一個 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
等軟體包,對軟體包打包過程,也有幫助。