1 / 49

Linux 程序设计基础

Linux 程序设计基础. 西安交通大学 李思 2004 年 8 月 25 日. 主要内容. Java 程序开发环境 C/C++ 程序设计基础 使用 gcc 编译程序 LinuxC 编程与 WindowsC 编程的主要区别 使用 gdb 调试程序 Make 和 Makefile 其它工具: Indent 和 CVS Shell 编程快速入门 Bash 脚本 正则表达式, Sed 和 awk. 1. Java 程序开发环境. JDK 的安装.

avye-gentry
Download Presentation

Linux 程序设计基础

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux程序设计基础 西安交通大学 李思 2004年8月25日

  2. 主要内容 • Java程序开发环境 • C/C++程序设计基础 • 使用gcc编译程序 • LinuxC编程与WindowsC编程的主要区别 • 使用gdb调试程序 • Make和Makefile • 其它工具:Indent和CVS • Shell编程快速入门 • Bash脚本 • 正则表达式,Sed和awk

  3. 1. Java程序开发环境

  4. JDK的安装 • 到sun.java.com下载jdk的安装文件:j2sdk-1_4_2_05-linux-i586.bin并把文件存放到/usr/local下 • #chmod +x j2sdk-xxxxxx.bin • #/usr/local/j2sdk-xxxxxx.bin • ln -s j2sdk1.4.2_04 java • 编辑/etc/profile,增加如下三行: • export JAVA_HOME=/usr/local/java/ • export CLASSPATH=.:/usr/local/java/lib/dt.jar:/usr/local/ java/lib/tools/jar • export PATH=/usr/local/java/bin:$PATH • 注意:上面命令中不能随意添加空格 • 退出,重新登陆

  5. Hello World • #vi HelloWorld.java • public class HelloWorld • { • public static final void main( String args[] ) • { • System.out.println("Hello World"); • } • } • #javac HelloWorld.java • #java HelloWorld

  6. 其它开发工具 • Linux下常用的Java集成化开发环境有 • JBuilder(最新版为X) • Eclipse(最新版为3.0) • Eclipse安装提示 • 有motif和gtk两个版本,建议选gtk版 • 安装Eclipse之前必须先安装JDK或者JRE • 用unzip命令解开压缩包 • 运行方法:eclipse -vm /usr/local/java/bin/java -vmargs -Xmx256M

  7. 2. C/C++程序设计基础

  8. 开发工具与开发环境 • 基本工具 • vi, emacs, gcc, g++, gdb • 图形界面调试工具DDD • 集成化开发环境 • Kylix、Kdevelop、Eclipse+CDT • 工程管理 • 版本控制:CVS • 条件编译:make

  9. gcc/g++ • 用法: gcc[<options>] <input files> • 常用的选项: • -g:产生调试信息 (用于gdb调试) • -Wall:输出所有警告信息 • -D<sym>:在所有源代码中定义<sym> • -o <name>:指定输出文件名 • -c: 只编译成目标文件,不连接 • -I <dir_name>: 指定include的路径 • -l<lib_name>: 指定需要连接的库 • -S: 输出汇编语言文件 • -O: 对编译的结果进行优化 • Example: gcc -g –Wall –o hello hello.cpp

  10. 头文件 • 系统默认的头文件路径为: • /usr/include • 当头文件既不在源代码目录下,也不在默认目录下时,有两种办法指定其目录 • 在源文件中指定,例如:#include </usr/local/mysql/include> • 编译时通过-I参数指定,例如:gcc –o foo foo.c –I /usr/local/mysql/include • 一般在编写内核模块驱动程序时需要指定头文件路径

  11. 静态库文件的连接 • 静态库文件位于/usr/lib目录下,文件名为libname.a • 当使用到库函数时,应该把库函数连接到程序中去 • 例如:gcc -o foo.c -lm • 注意:-l的参数不是库文件名,而是库名 • 如果库不在/usr/lib下,应该采用-L参数指定其路径 • 例如: gcc -o foo foo.c -L /root –lmylib • 常用的静态库包括:数学库m,线程库pthread,动态加载库dl等

  12. 共享库(1) • 共享库的生成 • 使用-fPIC参数生成位置无关代码 • 使用-shared参数生成共享目标库 • 例如: gcc -fPIC -shared -o libfoo.so foo.c • 共享库的调用 • 使用dlopen函数打开共享库文件 • 使用dlsym取得共享函数的指针 • 使用共享函数指针调用共享函数 • 使用dlclose关闭共享库文件 • 编译方法:gcc -o foo foo.c -ldl

  13. 共享库(2) • 如果在dlopen函数中没有指定共享库文件的绝对路径,则按照一下顺序搜索 • 用户的LD_LIBRARY_PATH环境变量 • /etc/ld.so.cache中列出的路径 • /lib和/usr/lib • 注意:不要直接修改/etc/ld.so.cache • 应该修改/etc/ld.so.conf • 然后运行ldconfig以更新/etc/ld.so.cache • 使用ldd命令可以列出一个程序所依赖的共享库 • 例如: ldd /bin/ls

  14. Linux IPC概述 • 进程间通信IPC是Linux编程与Windows编程最大的区别之一 • Linux下的进程间通信分为以下几类: • 信号:用于进程间的事件通知,如定时器等 • 管道:父子进程之间单向的通信机制 • 信号量:用于实现进程间的同步 • 消息队列:用于实现异步共享通信 • 共享内存:用于进程间共享数据 • UnixSocket:与BSD Socket类似,但效率高于后者

  15. Make与Makefile • 当一个程序包含多个C语言源代码文件时,手工编译程序将会十分麻烦 • make实际上是工程(项目)管理程序,它可以根据makefile中定义的规则自动编译、安装程序 • makefile可以自己编写,但更多时候是由开发工具自动生成(autoscan, aclocal, autoconf, automake) • Make命令的格式 • make [-f <makefilename>] [<target>] • 如果不指定makefilename,默认为当前目录下的makefile或者Makefile • Target是Makefile中定义的目标,默认为第一个目标

  16. Makefile的写法 • Makefile内部可分为两部分 • 变量定义: • <variable>=<string value> • 所有变量的默认值都源自于Shell变量 • 规则定义: • <目标>: <依赖><命令> • <目标>是指本条规则要生成的文件或达到的效果 • <依赖>是指执行本条规则所需要的文件或者条件,它可以是文件,也可以是其它目标 • <命令>是指本条规则的动作,Makefile中的第一个目标是默认的目标

  17. Makefile实例 # Example Makefile CC=g++ CCOPTS=-g –Wall -DDEBUG foobar: foo.o bar.o $(CC) $(CCOPTS) –o foobar foo.o bar.o foo.o: foo.cpp foo.h $(CC) $(CCOPTS) –c foo.cpp bar.o: bar.cpp bar.h $(CC) $(CCOPTS) –c bar.cpp clean: rm foo.o bar.o foobar

  18. Makefile的常用缩写 • $@ 代表该目标的全名 • $* 代表已经删除了后缀的目标名 • $< 代表该目标的第一个相关目标名 • 例如: prog: prog1.o prog2.o gcc prog1.o prog2.o -o $@ prog1.o: prog1.c lib.h gcc -c -I. -o $@ $< prog2.o: prog2.c gcc -c $*.c

  19. GDB • GDB=GNU DeBugger • 它是一个文字界面下的程序调试工具 • 常见用法:gdb [<programfile> [<pid>]] • <programfile>:可执行程序的文件名 • <pid>:正在执行的程序的进程号 • 例如 • gdb ./hello • gdb bash 6174 • 要求: • 使用gcc/g++编译程序时,应该添加-g参数,才能实现源代码级的调试

  20. gdb的命令(1) • 基本命令: file[<file>]打开文件<file>进行调试 run [<args>]用<args>参数来运行当前的程序 attach<pid>调试进程号为<pid>的进程 kill杀死当前调试的进程 quit退出gdb help [<topic>]显示帮助 • 单步与继续: c[ontinue]继续执行 s[tep]运行一行源代码,跟踪进入函数内部 n[ext]运行一行源代码,不进入函数内部 finish运行到函数结束并显示返回值

  21. gdb的命令(2) • 断点 b[reak] [<where>] 设置断点, <where>可以是地址、 函数名、行号等。还可以是<文件名>:<行号>的格式 [r]watch <expr>设置观察点。每当<expr>被写(或 被读)的时候,显示该变量 catch <event>当<event>事件发生的时候程序暂 停,可用于捕获一系列的事件,包 括C++的异常 info break[points]显示出所有断点的列表 clear [<where>]清除<where>处的断点 d[elete] [<nums>]删除第<nums>个断点

  22. gdb的命令(3) • 用于获取信息的命令: list [<where>]打印<where>处的源代码 search <regexp>在源代码中查找<regexp>表达式 backtrace [<n>]打印<n>级回溯 info [<what>]显示有关<what>的信息(如局部 变量,函数参数等) p[rint] [<expr>]显示表达式<expr>的值 • 数据修改与路径控制命令: set <name> <expr>设置变量或者参数 return [<expr>]从当前函数返回<expr>的值 jump <where>跳到<where>处执行

  23. indent • 源代码格式美化工具 • 其功能是在源代码中插入与删除空格 • GNU风格:indent -gnu foo.c • KR风格:indent -kr foo.c • Linux内核源代码所用的风格是kr风格,且行缩进为8个空格 • indent -kr –i8 xxx.c

  24. CVS服务器配置 • CVS=Concurrent Version System,是一种源代码版本管理系统,有助于实现团队协作 • CVS服务器的配置 • 在/etc/xinet.d/中添加cvspserver配置文件 • useradd cvs; chmod 770 /home/cvs -R • 在/etc/profile中添加export CVSROOT=/home/cvs • cvs -d /home/cvs init • 进入需要使用CVS的工程目录 • cvs import ProjName v_tag r_tag

  25. CVS客户端的使用 • 在/etc/profile里添加export CVSROOT=:pserver:cvs@202.117.21.150:/home/cvs • cvs login:登陆 • cvs logout:退出 • cvs checkout ProjName: 下载某项工程到本地 • cvs update: 检查文件更新状况 • cvs commit: 提交文件 • cvs log: 检查文件的修改日志 • cvs add: 添加一个文件 • cvs remove: 删除一个文件

  26. 3. Shell编程快速入门

  27. 概述 • Shell程序比Windows批处理功能更强 • Shell的种类:Bourne Shell(bsh)、Bourne Again Shell(bash)、C Shell(csh)等等 • 文件第一行#!/bin/sh指明shell解释器 • 其它各行从#开始到行末的字符均为注释 • chmod +x filename使文件可执行 • shell的两种执行方式 • ./filename • /bin/sh filename

  28. bash变量赋值 • 变量的赋值: str=“Hello, world!” • 注意等号两边不可有空格 • 接受用户输入: read str1 str2 • 特殊变量 • $0 这个程序的执行名字 • $n 这个程序的第n个参数值,n=1..9 • $* 这个程序的所有参数 • $# 这个程序的参数个数 • $$ 这个程序的PID • $! 执行上一个背景指令的PID • $? 执行上一个指令的返回值

  29. bash表达式与变量的使用 • 变量的引用: echo $str • 变量名产生歧义时应该加{} • num=2 • echo “This is ${num}nd” • 计算表达式 • 例: expr 2 + 3 • 程序执行结果的引用: 使用一对`符号 • 例: echo "The cureent directory is "`pwd` • 例: number=`expr$number+1`

  30. bash变量和通配符的展开 • 未加任何引号的变量和通配符会被展开 • “”可以禁止通配符的展开 • ‘’可以禁止任何展开 • \ 可用作转义字符,在expr中使用*、(、)时,必须使用\防止产生歧义 • echo *.txt 将列出当前目录所有txt文件 • echo “*.txt” *号将无法展开 • echo “this is $abc”变量abc将被展开 • echo ‘this is $abc’变量abc将无法展开 • expr 2\*\(1+3\)

  31. bash逻辑表达式(1) int1 -eq int2 如果int1 = int2则为真 int1 -ge int2 如果int1 >= int2则为真 int1 -gt int2 如果int1 > int2则为真 int1 -le int2 如果int1 <= int2则为真 int1 -lt int2 如果int1 < int2则为真 int1 -ne int2 如果int1 != int2则为真 str1 = str2 如果str1和str2相同则为真 str1 != str2 如果str1和str2不相同则为真 str 如果str不为空则为真 -n str 如果str的长度大于零则为真 -z str 如果str的长度等于零则为真

  32. bash逻辑表达式(2) • -d file 如果file为目录则为真 • -f file 如果file为文件则为真 • -r file 如果file为只读则为真 • -s file 如果file长度大于零则为真 • -w file 如果file可写则为真 • -x file 如果file可执行则为真 • !expr 对expr的逻辑值取反 • expr1 -a expr2 expr1和expr2相与 • expr1 -o expr2 expr1和expr2相或

  33. Bash的If语句 if [.…]; then .... elif [.…]; then .... else .... fi 注意if和fi应成对出现

  34. Bash的&&和|| • 以下两个语句是等价的,请注意&& • [ -f "/etc/shadow" ] && echo "This com\ puter uses shadow passwors"  • if [ -f "/etc/shadow" ]; then echo "This computer uses shadow passwors" fi • 与&&相反,||在逻辑表达式为假时执行后面的语句

  35. Bash的Case语句 case string1 in str 1) commands;; str 2) commands;; *) commands;; esac

  36. Bash的循环语句 • For循环 for var in list; do …… done • While循环 while [……]; do …… done

  37. Bash的函数 • 函数必须先定义后使用 • 定义函数的方法 • function foo(){……} • ()和function二者可以省略其一 • 利用$1, $2……可以取得函数的参数 • 利用local可以定义局部变量 • return只能返回0~255之间的整数 • 用$?可以取得return返回的值 • 一般通过全局变量返回函数结果

  38. Bash函数实例 #!/bin/bash function add { local temp; temp=`expr $1 + $2` sum=`expr $temp + $3` return $sum } add 1 2 3 echo $? echo $sum

  39. Shell脚本的自动执行(1) • 开机时自动执行 • 在/etc/rc.local中调用脚本 • 或把shell脚本直接写到/etc/rc.local中 • 用户登陆时自动执行 • /etc/profile • ~/.bash_profile • ~/.bashrc • /etc/bashrc

  40. Shell脚本的自动执行(2) • 定时执行:atd系统服务 • at –f file HH:MM MMDDYY • atq: 显示定时任务队列 • atrm: 删除某项定时任务 • 执行的结果用email发回 • 周期性执行:crond系统服务 • crontab –e:编辑周期执行列表格式:分 时 日 月 星期 命令 • crontab –l:显示周期执行列表 • crontab –r:删除周期执行列表 • 执行的结果用email发回

  41. 正则表达式(1) • 正则表达式是用于实现字符匹配的表达式 • 基本字符 • / 转义字符,表示其后的是特殊字符 • . 匹配一个任意字符 • [] 匹配方括号内列出的任何一个字符 • [^]不匹配方括号内出现的任何一个字符 • 多字符匹配 • ?匹配0或者多个字符 • * 匹配其前面的字符0次或多次 • + 匹配其前面的字符至少一次

  42. 正则表达式(2) • 多字符匹配 • {n} 匹配其前面的字符n次 • {n,}匹配其前面的字符n次以上 • {n,N}匹配其前面的字符n~N次 • 位置匹配 • ^匹配行首 • $ 匹配行尾

  43. 正则表达式举例 • 列出当前目录下的所有子目录 • ls -al|grep "^d“ • 列出以数字作为文件名的所有文件 • ls|grep "^[0-9]*$“ • 列出文件file中包含的所有URL行 • cat file|egrep "^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*([(/~?)\.-]\w*)*$" • 列出文件file中包含的所有Email地址行 • cat file|egrep "^\w(-?.?\w*)*@(\w+(-\w+)*)(\.(\w+(-\w+)*))*"

  44. sed概述 • Sed=Stream Editor, 非交互式的流编辑器 • 用法: sed [-n] [-e 'script'] [-f script_file] file • -n:不显示输出结果 • -e:在命令行中使用脚本 • -f: 指定脚本文件名 • file:输入文件名 • Sed的脚本的基本格式如下: • [address1 [,address2] ] command [argument] • address: 行号或者行条件 • command: 是要执行的命令 • argument: 是命令的参数

  45. sed的简单应用 • 字符串替换:将文件file中的所有ok替换成OK • sed -e 's/ok/OK/' file • 字符替换:将?结尾的行中的字母H和W换成小写 • sed -e '/?$/y/HW/hw/' file • 行前插入:在含有you的行前插入aaa • sed -e '/you/iaaa' file • 行后插入:在含有you的行后插入bbb • sed -e '/you/abbb' file • 行删除:以?结尾的行 • sed -e '/?$/d' file

  46. awk概述 • Awk名称出自三个创建者姓氏的首字母 • 用于匹配特定的模式并执行指定的动作 • 每个awk语句总是由两部分组成 • 模式: 要匹配的字符或字符串 • 动作: 匹配成功时执行的操作 • 命令格式: awk ‘pettern { operation }’ • 当pettern为空时,operation总是被执行 • pettern可以使用正则表达式或者逻辑表达式表示 • 正则表达式应该使用//括起来 • 默认的operation为print $0,即原样输出字符串

  47. awk的简单应用 • 显示出进程号小于100的进程的信息 • ps aux| awk '$2<100 {print $0}' • 显示出进程号大于100且用户为root的进程号和进程名称 • ps aux| awk '$1=="root" && $2>100 {print $2, $11}' • 显示出以r打头的用户id和用户名 • cat /etc/passwd| awk --field-separator=: '/^r/ {print $3, $1}' • 杀死所有名为abc的进程 • ps aux| awk '$11=="abc" {system("kill "$2)}'

  48. 练习题 • 编写、编译、运行一个简单的Java程序 • 编写一个C程序,要求程序至少具有两个C语言源文件,编写其Makefile,要求能够实现编译、安装与反安装。 • 练习CVS的基本操作 • 编写一个shell脚本,要求能够输出1~100之间的偶数 • 用awk读取/etc/passwd文件,输出其中的用户名和uid

  49. Thank You!

More Related