第五节: 关於程式设计
5.1. 编写叙述程式 (Scripts): .BAT 档的聚合体
你或许使用过 .BAT 来当做一长串命令的缩写 (我常做这种事). 这件事可以藉由在
profile 或 .profile 中设定 alias 来达成. 但是, 一旦 .BAT 档太过复杂, 那麽你
会喜欢由 shell 提供的叙述语言 (Scripting language) : 它几乎和 Qbasic 一样强
大而且易用. 它可以使用变数, 可以拥有像是 while , for, case if.. then .. else,
的语法结构; 它还有其它的优点 -- 例如, 它可以当成是程式语言的替代品.
要撰写一个 script - 就像在 DOS 下写 .BAT 档一样 - 只要编写一个 ASCII 的档案,
内含你想要的指令, 然後储存, 再使用下面这个命令让它可以被执行:
$ chgmod u+x <scriptfile>
当要执行时, 只要键入它的档名就可以了.
这里有个小小的警告: 系统内定的编辑器叫作 vi, 它有一点难以使用, 我想你应该也
会这样认为它有些烦人. 我不会在这篇文章中讨论它 -- 我自己也还尚未找到使用的窍
门 :p 请参考 Matt Welsh 的 "Linux installation... ", 109 页. 但你也可以使用其
它的编辑器, 如 joe 或是 X 下的 emacs. 这里只稍为说明一点你必需知道的 vi 知识
(至少让你可以 quit :p )
- - 加入一段文字可以用在文章中按下 'i';
- - 离开 vi 但不储存文章 : 请按 ESC 再打 :q!
- - 离开且存存 : 按 ESC, 再打 :wq
在 Linux 中编写 shell script 是一门大学问 -- 它几乎要一本书才能讲得详细.
本文不会再更深入的讨论这个问题; 但是, 以下提供了几个有用(希望是)的范例, 希望
能够使你对 shell script 有个初步的了解.
EXAMPLE 1: first_script
#!/bin/sh
# I am a comment
# don't change the first line - it's got to be there
echo "Today is `date`"
echo "My name is "$0
echo "You gave me the following "$#" parameters: "$*
echo "First parameter is "$1
echo "Have you grasped the trick?"
EXAMPLE 2: 2exe
#!/bin/sh
echo "making "$1" executable... "
chmod u+x $1
EXAMPLE 3: backup
#!/bin/sh
echo "Copying files in ~/bak... "
for name in $*
do
cp ${name} ~/bak
done
EXAMPLE 4: fmta
#!/bin/sh
echo "I remind you that only root can format disks"
fdformat /dev/fd0H1440
mkfs -t ext2 -c /dev/fd0H1440
echo "disk formatted."
EXAMPLE 5: mnta
#!/bin/sh
echo "I remind you that only root can mount disks"
mount -t msdos /dev/fd0 /mnt
echo "don't forget to umount when you've done."
5.2. 自己写个 C 程式
你应该不会期待在 Linux 有 GW/Qbasic 吧?? 在 Un*x 中, 系统内定的语言是 C,
不管你是喜欢还是讨厌它. 当然还有其它的语言可以用 (FORTRAN, Pascal, Lisp,
Bacic
.. 但没有 Turbo Pascal ^Q^ ).
假设你懂得 C.. 如果你曾经被 Turbo C++ 或是它在 DOS 下的兄弟们宠爱过, 那这里
有两句话恐怕不啻晴天霹雳: Linux 下的 C 编译器叫作 gcc, 但, 它没有 IDE 环境,
没有线上求助系统, 没有整合式除错器,..等等. 只有一个命令列的编译器, 但强大
且有效率. 以下这个命令可以编译你已写好的 hello.c :
$ gcc hello.c
这样会产生一个 a.out 的执行档. 如果你想让 gcc 造出其它档名的执行档, 键入
$ gcc -o hola hello.c
要联结一个程式库, 你要在 gcc 後加上一个 -l<arg> 的选项. 比如说要联结 math
library
$ gcc -o mathprog mathprog.c -lm
( -l<arg> 会迫使 gcc 联结 /usr/lib/lib<arg>.a; 因此, -lm 会联结
/usr/lib/libm.a)
对小程式来说, 这是一个好方法. 但是若程式是由数个 source files 组成, 我们可能
会需要 make 这个程式. 假设我们已经写好一个语法分析程式 parser.c, 它 #include
了两个 .h : parser.h , xy.h. 现在, 有个 calc.c 需要使用到 parser.c 中的功能.
这样该怎麽办??
我们可以写一个叫作 makefile 的档案, 告诉编译器所有 source 和 object files
间的关系, 在这个例子里,
# This is makefile, used to compile calc.c
# Press the <TAB> key at appropriate positions!
calc: calc.o parser.o
<TAB>gcc -o calc calc.o parser.o -lm
# calc depends on two object files: calc.o and parser.o
calc.o: calc.c parser.h
<TAB>gcc -c calc.c
# calc.o depends on two source files
parser.o: parser.c parser.h xy.h
<TAB>gcc -c parser.c
# parser.o depends on three source files
# end of makefile.
储存, 然後键入
$ make
以便编译程式. 或者, 这个档案被存在 calc.mak 里, 那麽就必需
$ make -f calc.mak
当然, 请参阅 Man pages 以得到更多的资讯.
此外, 某些函数的用法在 man pages 可以找得到, 例如
$ man printf
5.1. 编写叙述程式 (Scripts): .BAT 档的聚合体
你或许使用过 .BAT 来当做一长串命令的缩写 (我常做这种事). 这件事可以藉由在
profile 或 .profile 中设定 alias 来达成. 但是, 一旦 .BAT 档太过复杂, 那麽你
会喜欢由 shell 提供的叙述语言 (Scripting language) : 它几乎和 Qbasic 一样强
大而且易用. 它可以使用变数, 可以拥有像是 while , for, case if.. then .. else,
的语法结构; 它还有其它的优点 -- 例如, 它可以当成是程式语言的替代品.
要撰写一个 script - 就像在 DOS 下写 .BAT 档一样 - 只要编写一个 ASCII 的档案,
内含你想要的指令, 然後储存, 再使用下面这个命令让它可以被执行:
$ chgmod u+x <scriptfile>
当要执行时, 只要键入它的档名就可以了.
这里有个小小的警告: 系统内定的编辑器叫作 vi, 它有一点难以使用, 我想你应该也
会这样认为它有些烦人. 我不会在这篇文章中讨论它 -- 我自己也还尚未找到使用的窍
门 :p 请参考 Matt Welsh 的 "Linux installation... ", 109 页. 但你也可以使用其
它的编辑器, 如 joe 或是 X 下的 emacs. 这里只稍为说明一点你必需知道的 vi 知识
(至少让你可以 quit :p )
- - 加入一段文字可以用在文章中按下 'i';
- - 离开 vi 但不储存文章 : 请按 ESC 再打 :q!
- - 离开且存存 : 按 ESC, 再打 :wq
在 Linux 中编写 shell script 是一门大学问 -- 它几乎要一本书才能讲得详细.
本文不会再更深入的讨论这个问题; 但是, 以下提供了几个有用(希望是)的范例, 希望
能够使你对 shell script 有个初步的了解.
EXAMPLE 1: first_script
#!/bin/sh
# I am a comment
# don't change the first line - it's got to be there
echo "Today is `date`"
echo "My name is "$0
echo "You gave me the following "$#" parameters: "$*
echo "First parameter is "$1
echo "Have you grasped the trick?"
EXAMPLE 2: 2exe
#!/bin/sh
echo "making "$1" executable... "
chmod u+x $1
EXAMPLE 3: backup
#!/bin/sh
echo "Copying files in ~/bak... "
for name in $*
do
cp ${name} ~/bak
done
EXAMPLE 4: fmta
#!/bin/sh
echo "I remind you that only root can format disks"
fdformat /dev/fd0H1440
mkfs -t ext2 -c /dev/fd0H1440
echo "disk formatted."
EXAMPLE 5: mnta
#!/bin/sh
echo "I remind you that only root can mount disks"
mount -t msdos /dev/fd0 /mnt
echo "don't forget to umount when you've done."
5.2. 自己写个 C 程式
你应该不会期待在 Linux 有 GW/Qbasic 吧?? 在 Un*x 中, 系统内定的语言是 C,
不管你是喜欢还是讨厌它. 当然还有其它的语言可以用 (FORTRAN, Pascal, Lisp,
Bacic
.. 但没有 Turbo Pascal ^Q^ ).
假设你懂得 C.. 如果你曾经被 Turbo C++ 或是它在 DOS 下的兄弟们宠爱过, 那这里
有两句话恐怕不啻晴天霹雳: Linux 下的 C 编译器叫作 gcc, 但, 它没有 IDE 环境,
没有线上求助系统, 没有整合式除错器,..等等. 只有一个命令列的编译器, 但强大
且有效率. 以下这个命令可以编译你已写好的 hello.c :
$ gcc hello.c
这样会产生一个 a.out 的执行档. 如果你想让 gcc 造出其它档名的执行档, 键入
$ gcc -o hola hello.c
要联结一个程式库, 你要在 gcc 後加上一个 -l<arg> 的选项. 比如说要联结 math
library
$ gcc -o mathprog mathprog.c -lm
( -l<arg> 会迫使 gcc 联结 /usr/lib/lib<arg>.a; 因此, -lm 会联结
/usr/lib/libm.a)
对小程式来说, 这是一个好方法. 但是若程式是由数个 source files 组成, 我们可能
会需要 make 这个程式. 假设我们已经写好一个语法分析程式 parser.c, 它 #include
了两个 .h : parser.h , xy.h. 现在, 有个 calc.c 需要使用到 parser.c 中的功能.
这样该怎麽办??
我们可以写一个叫作 makefile 的档案, 告诉编译器所有 source 和 object files
间的关系, 在这个例子里,
# This is makefile, used to compile calc.c
# Press the <TAB> key at appropriate positions!
calc: calc.o parser.o
<TAB>gcc -o calc calc.o parser.o -lm
# calc depends on two object files: calc.o and parser.o
calc.o: calc.c parser.h
<TAB>gcc -c calc.c
# calc.o depends on two source files
parser.o: parser.c parser.h xy.h
<TAB>gcc -c parser.c
# parser.o depends on three source files
# end of makefile.
储存, 然後键入
$ make
以便编译程式. 或者, 这个档案被存在 calc.mak 里, 那麽就必需
$ make -f calc.mak
当然, 请参阅 Man pages 以得到更多的资讯.
此外, 某些函数的用法在 man pages 可以找得到, 例如
$ man printf