Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
Linux 的发音 A : ['linju:ks]  B : ['linэks] C : ['linΛks] D : ['liniks] 正确发音  GO “ hello,this is linus torvalds and i pronounce linux as linux”
Linux  入门 历史、背景、版本、安装 Linux 系统管理 基本操作、各类服务的架设 Linux 程序设计 Vi 、 SHELL 、 C 、可视化程序 课程介绍
什么是 UNIX UNIX 是有 OPEN GROUP 管理的一个商标,它指的是一个遵循特定规范的计算机操作系统 这个规范称为单一 UNIX 规范( The Single UNIX Specification ) UNIX 的源代码属于 SCO 公司
类 UNIX 系统 多数为商用,如 SCO 的 Unixware 、 IBM 的 AIX 、 HP 的 HP-UX 和 Sun 的 Soloris 免费的有 FreeBSD 和 Linux
认识 Linux 什么 是 Free Software ? Shareware/Freeware 不提供 Source Code 无法让 使用者自由更改或散播
认识 Linux 什 么 是  自由软件 Opensource? Freedom( 自由 )/Open( 开 放 ) Source Code 必须公开 任何人都可以自由 传播 、 下载 、使用或 改写
什么是 Linux 是一个类 UNIX 内核的可以自由发布的实现版本,是一个操作系统的底层核心 可以获得内核源代码,编译并安装,然后获得并安装许多其他自由发布的软件,从而创建一个完整的 Linux ,通常称为 Linux 系统 Linux 发行版
发行版简介 Linux 操作系统( kernel+ultiliteies ):专家才会用 Linux 发行版( Distribution ):整合更多配套软件,普通用户也能用
LINUX 源起 1991  年  8  月 芬兰 的一 个学 生在 comp.os.minix  新闻组贴 上了以下 这 段 话 : 「 你好,所有使用  minix  的人  - 我正在 为 386 ( 486 ) AT  做一個 免费 的操作系統  (  只是 为 了 爱 好  ) ,不 会 像  GNU  那 样 很大很 专业 。 」
1990 年秋, Linus 修读 Unix 课程,基于 minix 编写仿真程序 1991 年 10 月发布 linux0.02 版本 1993 年发布 linux0.99 版本 1994 年 3 月发布 linux1.0 版本 1994 年加入 GNU 组织
GNU 计划 1983  年  Richard Stallman( 自由 软件业 的精神教父 )  创办   GNU(GNU’s not Unix) 计划 开始于 1984 年,旨在 发展 一個 类 -Unix  且 为  自由 软件  的完整 操作 系統 http://www.gnu.org/
自由 软件基金会 GNU 计划 的 赞助单位 FSF(Free Software Fundation) 提倡 免费软件 FSF 自由使用 权 的三個 意义 : 可自由 复制 GNU 的 软件 可自由修改 源代码 可自由 散布 修改 过 的 源代码 ,但不得收取任何 版权费用
GNU Gen era l Public License 大 众 公有 版权 / 通用公共 版权 官方 翻译 :自由文件 许可 Copy left (是 copyright 的反话,就是防止有人给自由软件的使用加上限制) http://www.linux.org.tw/CLDP/GNU/licences/fdl.zh.html http://www.gnu.org/copyleft/gpl.html
在 GPL 条款下发布的主要 GNU 项目软件 GCC G++ GDB GNU make Bash GNU Emacs
GNU 与 Linux GNU 仍自行 发展 Hurd Kernel 开发许多 以 GPL 发 行的 应 用程 序与 工具程 序 Linux ( Linus’s Unix ) 由 网络上热心 的朋友一起 发 展 Linux Kernel 采 用 GNU 发 展的 许多应 用程 序与 工具 应该称作 GNU/Linux
Linux 品牌 RedHat Linux SuSE Linux Mandrake Linux Caldera Linux Turbolinux Debian GNU/Linux Gentoo Linux Linpus Linux
内核版本号与发行版本号 内核版本号:由 Linus 等人制定和维护,全球统一 发行版本号:由各个发行公司或者组织自行制定,不同公司的发行版本号之间无可比性 内核版本号格式: x.y.zz-www , x 为主版本号, y 为次版本号, zz 为次次版本号, www 发行号
Linux Kernel 现状与认证 Kerenl  版本  http://www.kernel.org 主版本号、次版本号、次次版本号 稳 定版本- 2. 6 . 1 2 Linux 认证 RedHat RHCE  http://www.redhat.com/ LPI Level one/two/three  http://www.lpi.org
Linux 产业现状 国内 Linux 市场普及度越来越高 银行、证券、电信、邮政、税务、航空等对稳定性、安全性要求颇高的领域应用广(服务器端)  手机软件也用到了 Linux 嵌入式开发平台   桌面市场不成熟
Linux 人才现状 Linux 在中国前景光明,但缺少这方面的人才已成为其发展的瓶颈  国内熟练的 Linux 开发人员只有 3000 人左右,而且有很大一部分都是自由软件的爱好者,并没有经过专业的课程培训  根据 EvansData 发表的有关 Linux 开发状况的调查结果,目前 Linux 应用软件开发人员中,有 52% 是从 Windows 应用软件开发领域转行过来的,另外还有 30% 曾经从事过 UNIX 的应用开发
人才问题 其一,人才培养跟不上。企业能直接从学校或社会上招聘到的 Linux 人才少,一般只能招到公司后再慢慢培训; 其二,高层次的 Linux 技术人才少。很多人对 Linux 都是一知半解,只懂点皮毛,对内核级别有研究的更是凤毛麟角; 其三, Linux 企业以外的 Linux 人才少。
薪水如何? Linux 普通网络管理人员的月薪大约 5000 元左右 负责编程的 Linux 软件工程师月薪大约在 8000 - 12000 元之间 近年来特别红火的 Linux 嵌入式软件开发人员的月薪大约在 1.2 万元以上 项目经理的工资可能更高 在美国的一些大城市,经验丰富的 Linux 管理人员的薪金待遇普遍比 Unix 和 Windows 同行高出 20% ~ 30%
 
 
 
 
 
 
 
 
man  男人 ? 在线 查詢  man page # man ls # man 1 ls # info ls info 也可以
系統 关机 关机 shutdown –h now halt poweroff init 0 重新 启动 shutdown –r now reboot init 6
Linux 与 XP 双系统 参考资料: http://soft.yesky.com/os/lin/36/2300036_1.shtml 要点: 硬盘中有独立的分区留出来 先装 XP 后装 Linux ,否则 XP 会吃掉  linux 的引导 双系统是由 linux 的 GRUB 来引导启动
关于课本 《 linux 系统应用与开发教程》 机械工业出版社 刘海燕等编著 ftp dns dhcp telnet
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
Linux 终端使用基础  Linux 终端也称为虚拟控制台  . 一台计算机的输入输出设备就是一个物理的控制台  . 如果在一台计算机上用软件的方法实现了多个互不干扰独立工作的控制台界面,就是实现了多个虚拟控制台。  Linux 终端的工作方式是字符命令行方式,用户通过键盘输入命令进行操作,可以通过 Linux 终端对系统进行控制。
什么是 shell Shell 是一个作为用户与 linux 系统间接口的程序,它允许用户向操作系统输入需要执行的命令 在 linux 中可有多种 shell Linux 是高度模块化的 可用多个 shell 内核 csh bash xwindow 其他程序
shell 的基本形式  shell 的种类  : ash :是贝尔实验室开发的 shell , bsh 是对 ash 的符号链接。 bash :是 GNU 的 Bourne Again shell ,是 GNU 操作系统上默认的 shell 。 sh 以及 bash2 都是对它的符号链接。 tcsh :是 Berkeley UNIX C shell 。 csh 是对它的符号链接
shell 命令的基本格式是: 命令名  [ 选项 ]  < 参数 1> < 参数 2> …… 命令自动补齐与历史记录 shell 提示符  :# $
我们用的 shell GNU 工具中的 bash 作为 /bin/sh 被默认安装 大多数 linux 发行版中, shell 程序 /bin/sh 实际上是对程序 /bin/bash 的一个连接 /bin/sh -version
Linux 文件 链接数 所属组 所属用户 文件属性 文件大小 修改时间 文件名
文件与目录的基本概念  文件是 Linux 用来存储信息的基本结构,它是被命名的存储在某种介质上的一组信息的集合。 Linux 系统中有三种基本的文件类型 . 普通文件:又分为文本文件和二进制文件; 目录文件:目录文件存储了一组相关文件的位置、大小等与文件有关的信息; 设备文件: Linux 系统把每一个 I/O 设备都看成一个文件,与普通文件一样处理,这样可以使文件与设备的操作尽可能统一 ;
文件系统概念 文件系统是磁盘上有特定格式的一片区域,操作系统通过文件系统可以方便地查询和访问其中所包含的磁盘块 文件:文件系统中存储数据的一个命名对象 目录:文件系统中的每个文件都登记在一个或多个目录中
文件结构 文件的成分:无论文件是一个程序、一个文档、一个数据库、一个目录,都有以下同样的结构 索引节点,又称 I 节点,存放文件的状态信息 数据
Linux  文件种类 正规文件 ( regular file ) 第一个属性为   [ - ] 纯文字文件 (ascii) 二进制文件 (binary)    目录   (directory) : 第一个属性为   [ d ] 链接文件   (link) : 第一个属性为   [ l ] 设备文件   (device) : 区块   (block)  设备文件 , 第一个属性为   [ b ] ;  字 符   (character)  设备文件 , 第一个属性为   [ c ] 。
Linux 程序 Linux 中的应用程序有两种类型 可执行文件(相当于 windows 中的 .exe 文件) 脚本文件(相当于 windows 中的 .bat .cmd 文件) Linux 并不要求应用程序具有特殊的文件名或扩展名
Linux  文件属性 可读  可写  可执行  无此属性 文件类型  拥有者属性  组属性  其他人对该文件属性
目录 Linux 系统以目录的方式来组织和管理系统中的所有文件  Linux 系统通过目录将系统中所有的文件分级、分层组织在一起,形成了 Linux 文件系统的树型层次结构。以根目录“ /” 为起点,所有其他的目录都由根目录派生而来。 特殊目录 :“.” 代表该目录自己, “ ..” 代表该目录的父目录,对于根目录,“ .” 和“ ..” 都代表其自己。
观察目录文件的信息 目录文件也包含数据,它与普通文件的差别是:内核对这些数据进行结构化处理,它是由成对的“ I 节点号 / 文件名”构成的列表 当把文件添加到一个目录中时,该目录的尺寸会增大,以便容纳新文件名。当删除文件时,目录的尺寸并不减小,而是内核对该目录项做上特殊标记,以便下次添加一个文件时重新使用它。
Linux  目录结构 /bin :常用系統 程序目录 /boot : 开机设定目录 ,也是 摆放 核心  vmlinuz  的地方 /dev : 摆放系统设备装置文件的目录 /etc : 系统配置文件 ,尤其  passwd, shadow /etc/rc.d/init.d :系統 开机 的時候 载入服务 的  scripts  的 摆放地点 /home :系統使用者的目 录
Linux  目录结构 /lib : Linux  执行 或 编译程序函数库目录 /mnt : 软驱与光驱接入挂载 的地方 /proc :系 统 核心 与执 行程序的一些 信息 /root :系 统 管理 员 的目 录   /usr/bin, /bin : 一般执行文件摆放 的地方 /usr/sbin, /sbin : 系统管理员 常用 指令 集 /var : 摆放系统日志文件 的地方  /lost+fount : 摆放系统 不正常 产 生 错误时遗 失的片段
 
工作目录:用户登录到 Linux 系统后,每时每刻都处在某个目录之中,此目录被称为“工作目录” 或“当前目录” 用户主目录( Home Directory ):是系统管理员在增加用户时为该用户建立起来的目录,每个用户都有自己的主目录。 使用符号 ~ 表示。
路径是指从树型目录结构中的某个目录到某个文件的一条道路。此路径的主要构成是目录名称,中间用“ /” 分开。 绝对路径是指从“根”开始的路径,也称为完全路径; 相对路径是指从用户工作目录开始的路径。 通配符  通配符 *  通配符?  字符组模式:通配符“ [” 、“ ]” 、“ -” 用于构成字符组模式。  转义字符 \
Linux 用正斜线( / )分隔文件名里的目录名 Windows 用反斜线( \ )分隔
目录和文件的基本操作  文件列表 ls [-a] [-l] [-i] 文件查看和连接命令 cat cat [ 选项 ] <file1> … 分屏显示命令 more more [ 选项 ]  <file>… 按页显示命令 less less [ 选项 ] <filename>
复制、删除和移动命令  复制命令 cp cp [ 选项 ] <source> <dest> 或者  cp [ 选项 ] <source>... <directory> 删除命令 rm rm [ 选项 ] <name>... 移动或重命名命令 mv mv [ 选项 ] <source> <dest> 或者  mv [ 选项 ] <source>... <directory>
创建和删除目录命令  创建目录命令 mkdir mkdir [-p] <dirName>… 删除空目录命令 rmdir rmdir [-p] <dirName>
切换工作目录和显示目录命令  切换工作目录命令 cd cd <dirName> 显示当前路径命令 pwd pwd 查看目录命令 ls ls [ 选项 ] [<name>...]
查找与定位命令  查找文件或者目录命令 find find [path…] [expression] 文件定位命令 locate/slocate locate [ 选项 ] <search string>
链接 ln ln [ 选项 ] <source> <dest> 硬链接 hard link 软链接 symbolic link 改变文件或目录时间的命令 touch  touch [ 选项 ] <file1> [file2 ...]
压缩解压缩命令 命令格式为: tar < 主选项 > [ 辅选项 ] < 文件或者目录 > 压缩和解压命令 gzip  gzip [ 选项 ] < 文件名 > 解压命令 unzip unzip [ 选项 ] < 压缩文件名 >
常用命令 显示文字命令 echo  echo [ -n ] < 字符串 > 显示日历命令 cal  cal [ 选项 ] [[ 月 ]  年 ] 日期时间命令 date  显示日期和时间的命令格式为: date [ 选项 ] [+FormatString] 设置日期和时间的命令格式为: date  <SetString> 清除屏幕命令 clear
软件包管理命令 rpm  安装软件  rpm -i (  或者  --install) [ 安装选项 ] <file1.rpm> ... <fileN.rpm>  删除  rpm -e ( 或者 --erase) [ 删除选项 ] pkg1 ... pkgN   升级  rpm -U (  或者 --upgrade) [ 升级选项 ] file1.rpm ... fileN.rpm   查询  rpm -q (  或者  --query) [ 查询选项 ] pkg1 ... pkgN 校验已安装的软件包 rpm -V (  或者  --verify) [ 校验选项 ] pkg1 ... pkgN
公共邮箱 [email_address] 密码: 123456 课件、资料
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
更改  Linux  文件属性命令 u g o a +( 加入 ) -( 除去 )  =( 设定 ) r  w  x 文件或目录 chmod r=4,w=2,x=1 # chmod 770 test owner  = rwx  = 4+2+1 = 7 group  = rwx  = 4+2+1 = 7 others = ---  = 0+0+0 = 0
练习 系统中有用户 user1 和 user2 ,同属于 users 组。在 user1 用户目录下有一文件 file1 ,它拥有 644 的权限,如果 user2 用户想修改 user1 用户目录下的 file1 文件,应拥有    权限。   A   744   B   664   C   646   D  746
Linux 上的 X Window 系统  整个 X Window 由三个部分组成: X Server :是控制输出及输入设备并维护相关资源的程序,它接收输入设备的信息,并将其传给 X Client ,而将 X Client 传来的信息输出到屏幕上( 在屏幕上构造方块(窗口),然后画出里面的元素   )。 X Client :是应用程序的核心部分,它与硬件无关,每个应用程序就是一个 X Client 。 X Client 可以是终端仿真器( Xterm )或图形界面程序,它不直接对显示器绘制或者操作图形,而是与 X Server 通信,由 X Server 控制显示。 X protocol : X Client 与 X Server 之间的通信协议。
X 服务程序响应 X 客户程序的请求,直接与图形设备通信,负责打开和关闭窗口,控制字体和颜色等底层的具体操作。每一个显示设备只有一个惟一的 X 服务程序。
X 客户程序是使用系统窗口功能的一些应用程序,无法直接影响窗口或显示,它们只能请求 X 服务程序,并通过 X 服务程序提供的服务在指定的窗口中完成特定的操作  X 协议是一个抽象的应用服务协议,包括了终端的输入请求和对 X 服务程序发出的屏幕输出命令,不包括对底层硬件的访问和控制。 X 协议是 X 服务程序和 X 客户程序进行通信的途径
X Window 的特点  良好的网络支持: X Window 采用了 C/S 网络结构, X Client 和 X Server 可以通过网络来通信,而且有良好的网络透明性。 个性化的窗口界面: X Window 并未对窗口界面作统一的规范,程序员可以根据需求自行设计,其中最有名的就是后面将要介绍的 GNOME 与 KDE 。 不内嵌于操作系统: X Window 只定义了一个标准,而不属于某个操作系统,因此可在不同的操作系统上运行相同的 X Window 软件
在 Mac OS 和 Windows ,构件图形界面的功能都做在了操作系统里面,你只能使用那些。这个方法很简单,但是却不灵活。 Unix 和类 Unix 的操作系统没有内建这个功能,要使用 GUI 你就不得不使用窗口系统( X Window )。
GNOME : GNOME 项目有两个目标:提供一个完整的、易学易用的桌面环境 -GNOME 桌面环境,为程序设计人员提供强大的应用程序开发环境- GNOME 开发平台,用于建立桌面上的应用。  KDE :其目的是在 X Window 上建立一个与 MacOS 或者微软的 Windows 类似的完整易用的桌面环境,从而使 UNIX 更接近广大普通用户。 KDE 不仅提供了一个方便易用的超级桌面环境,而且还提供了一套免费的计算开发平台。
总结几个概念 DE ( Destop Environment ):桌面环境 GNOME 、 KDE (必须在 X Winodw 上运行) 窗口管理器(必须在 X Winodw 上运行) GNOME 的 Enlightenment KDE 的 KVM TWM : Tab Window Manager for the X Window System
注意 X Winodw 里的 X Server 只负责显示窗口画面 窗口管理器负责选择在哪里放置窗口、移动、改变大小、最大化、最小化等
窗口管理器  窗口  主题  工作区菜单  终端窗口
GNOME  桌面环境  GNOME 是 GNU 网络对象模型环境( GNU Network Object Model Environment )的缩写,它是 GNU 项目的一部分  GNOME 操作界面由 GNOME 面板( Panel )和桌面组成
GNOME 面板的组成 主菜单:主菜单是系统中所有应用程序的起点。 程序启动器:是 Linux 应用程序的启动链接,如同 Windows 中的快捷方式。 工作区切换器: 可以将 GNOME 的桌面分为相互独立的工作区,每个工作区是桌面的一部分 . 窗口列表:窗口列表显示了当前工作区上运行着的应用程序的名称。 通知区域: Red Hat 网络更新通知工具是通知区域的一部分。它提供了一种简捷的系统更新方式,确保系统时刻使用 Red Hat 的最新勘误和错误修正来更新。 插件小程序( Applets ):插件小程序是完成特定任务的小程序。 GNOME 有很多十分有用并且非常有趣的插件小程序,例如,电子邮件检查器、时钟日历、 CPU 和内存情况查看器等。
组合面板的内容元素  主菜单、程序启动器、工作区切换器、窗口列表、通知区域、插件小程序都可以看成是 GNOME 面板上的内容元素,它们可以自由组合和排列  ; 组合主菜单  组合程序启动器  使用抽屉组合
组合面板的属性元素  GNOME 有边缘面板、角落面板、浮动面板、滑动面板和菜单面板 5 种不同属性的面板 设置边缘面板、角落面板、浮动面板、滑动面板和菜单面板的属性 .
GNOME 桌面  初始桌面  : 初始桌面包括 “ < 用户名 > 的主目录”、“从这里开始”和“回收站”。  root 用户桌面上所保存的所有项目都保存在目录 /root/.gnome-desktop/ 下,其它用户的桌面上所保存的所有项目都位于该用户主目录下的 .gnome-desktop 目录中 . 该目录是个点文件,一般隐藏显示。
GNOME 桌面  将程序启动器拖放到桌面上 把项目从文件管理器窗口拖放到桌面上  建立链接 : 两种方法 桌面菜单  桌面属性的设置  : 背景、屏幕保护程序 . 工作区切换器属性设置
GNOME 的窗口管理器  调整窗口大小、移动窗口、最大化、最小化、关闭窗口等操作与 Windows 的对应操作几乎一样 与 Windows 下的窗口不同的操作有:  卷起:窗口卷起后只剩下窗口标题栏可见, GNOME 默认将鼠标在窗口标题栏上双击作为窗口的卷起操作,也可以右单击窗口标题栏,选择【卷起】命令。对于卷起以后的窗口,鼠标双击标题栏或者右单击窗口标题栏,选择【展开】命令可使窗口恢复原样。 移动到别的工作区:右单击窗口标题栏,选择“移动到工作区  < 工作区名 >” ,可将该窗口移动到指定的工作区,同时该窗口从原来的工作区消失。 复制到别的工作区:右单击窗口标题栏,选择“放在所有工作区上”命令,将该窗口在各个工作区生成一个备份。
GNOME 的文件管理器  Nautilus 文件管理器主要由菜单栏、工具栏、位置栏、状态栏、侧栏和浏览窗格等组成 。
 
文件管理器的基本操作  选择文件  打开文件  更改文件名  移动和复制文件 给文件建立链接  删除文件 :文件被删除后都暂时存放到回收站中,回收站的内容存放在用户主目录下的 .Trash 目录下中 定位  改变文件查看方式  排列和布局文件
文件管理器的个性化设置  改变鼠标动作的关联
文件管理器的个性化设置  改变鼠标动作的关联 给文件增加徽标
文件管理器的个性化设置  改变鼠标动作的关联 给文件增加徽标 改变侧栏和浏览窗格的背景或者颜色
KDE 桌面环境  KDE 从外表上看同 GNOME 几乎相同,也是由面板和桌面组成 KDE 是遵守 GNU 的自由软件。在 LGPL 下所有 KDE 库都允许开发 KDE 桌面的程序,所  有 KDE 应用程序得到 GPL 许可, KDE 使用  Qt C++  跨平台工具包 , 有各自的授权。  Qt 的授权允许你免费使用 Qt 来开发  X Windows 下的软件,只要你的原始代码也自由地  被使用。
KDE 桌面环境 如果你希望你的原始代码不允许修改,你必须获得 Qt 的商业授权  Qt 是建造使用者接口的 C++ 基类库。它提供大多数 widgets 、菜单、按钮、 sliders 等  等。 Qt 是一个跨平台库,写的代码可在 Unix 编译,也可在  Windows 编译。
KDE 面板的组成
KDE 面板 组合 KDE 面板内容元素:可以将 KDE 面板上的内容分为小程序、应用程序按钮、特殊程序按钮和扩展 4 大类。用户可以对这 4 类元素自由组合。 设置 KDE 属性 : KDE 面板设置控制模块  改变 KDE 面板的布局和大小 隐藏 KDE 面板和添加隐藏按钮  淡化小程序面板把手
KDE 主菜单  菜单编辑器 菜单的编辑  为程序定义快捷键  菜单的其它属性设置
KDE 桌面  初始桌面图: 包括起点目录、 floppy 、从这里开始和回收站 。 Floppy 图标用来对软驱进行操作。  拖放操作 :拖放操作的来源分为菜单、面板和文件夹。  桌面快捷菜单  桌面属性的设置 :外观、桌面行为、背景
KDE 的文件管理器 Konqueror
文件导航系统 1 )目录树导航   2 )多视图导航 3 )标签导航 4) 书签导航
Konqueror  的其它功能 Konqueror 和终端的紧密结合  Konqueror 的网络功能
桌面切换  在字符终端下切换桌面: 命令: switchdesk KDE|GNOME 在 X Window 下切换桌面: 在桌面环境中完成切换选择   “ 主菜单 / 系统工具 / 更多系统工具 /Desktop Switching tool ” 在登录界面实现选择 Ctrl+alt+backspace ,重新进入登录界面  主题的切换与安装 http://www.gnome-look.org http://art.gnome.org
vi 文本编辑器   vi 管理 员 至少一定要 会 一 种编辑器 vi  的使用: 一般模式: 移动 、 复制 、 删除 、 黏贴 编辑 模式:插入 与 取代文件 命令 模式: 查询 、自 动 取代、 保存 等
vi help h,j,k,l  移动 yy  复制 dd  刪除 p  黏贴 o,i,a  插入 R,r  取代 u  回复 /  查询 :%s/x/y/g  自 动 取代 :w  保存 :q  退出 :wq!  保存 強制 退出
账号  Linux 系统的账号分为用户账号和组账号两类: 用户账号:通常一个操作者拥有一个用户账号,每个用户账号有唯一的识别号 UID ( User ID )和自己所属组的识别号 GID ( Group ID )。 Linux 系统中可以有两类用户账号: root 用户和普通用户。 组账号:是一组用户账号的集合。通过使用组账号,可以设置使一组用户对文件具有相同的权限。
用户和组的配置信息保存在以下三个文件中:  /etc/passwd  对所有用户都可读  /etc/shadow /etc/group
/etc/passwd 文件 每一行存储一个用户的账号信息,每一行可以包含如下域,各域之间以冒号分隔: 登录名:即用户账号 口令:通常是一个“ x” ,表示口令已被加密,加密后的口令存储在 /etc/shadow 文件中。如果是“ *” ,则表示该账号已被停用。 UID :每个用户账号都有一个不同的 ID ,它是一个整数。 GID :用户所属的组的 ID ,每个组也都具有不同的 ID 。 用户信息:这是账号附加的信息,如用户名、电话、住址等,可以使用命令 finger 和 chfn 查询和修改这些信息。 主目录:在默认状态下,每个用户都有一个主目录, root 用户的主目录是 /root ,管理员新建立的用户的主目录默认为 /home/< 用户名 > 。 登录 shell :设置用户在登录时使用的 shell ,系统默认使用 /bin/bash 。 例如: root : x : 0 : 0 : root : /root : /bin/bash
伪  用  户  含  义 bin  拥有可执行的用户命令文件 sys  拥有系统文件 adm  拥有帐户文件 uucp  UUCP 使用 lp  lp 或 lpd 子系统使用 nobody  NFS 使用
/etc/shadow etc/shadow 中的记录行与 /etc/passwd 中的一一对应,它由 pwconv 命令根据 /etc/passwd 中的数据自动产生 登录名 : 加密口令 : 最后一次修改时间 : 最小时间间隔 : 最大时间间隔 : 警告时间 : 不活动时间 : 失效时间 : 标志
/etc/shadow 是根据 /etc/passwd 文件产生的,一行存储一个用户的信息,各域之间以冒号分隔: 用户账号 加密的口令密文 最后一次修改时间 , 从 1970 年 1  月 1 日到上次口令修改日期的天数。 最小间隔时间,口令上次修改后,要过多少天才能再修改。若为 0 表示没有时间限制。 最大间隔时间 警告时间,如果口令有期限限制,要过期前多少天向用户示警。一般系统默认为 7 天。
/etc/group 存储所有组账号的数据,一行表示一个组的信息,各域之间以冒号分隔,包括: 组名 x 表示加密的组口令,口令的相关信息存储在 /etc/gshadow 文件中,其形式与 /etc/shadow 相似。 组 ID ( GID ),系统生成的组 ID 小于 500 ,管理员新建的第一个组 ID 为 500 ,以后依次递增。 该组包含的用户账号列表,以逗号分隔。 例如: bin : x : 1 : root , bin , daemon
用户管理 / 命令   增加用户:  adduser [ 选项 ] <newusername>  -d <dirName> :指定用户主目录,默认情况下,将会在 /home 目录下新建一个与用户名相同的用户主目录。  -s <shellName> :指定用户登录时使用的 shell ,默认的 shell 为 /bin/bash 。  -g <gName> :指定用户归属的组名。 默认地,每当创建一个新用户的时候,一个与用户名相同的组就会被创建,而这个用户就是该组的成员。( UPG 方案)   -G < 组列表 > :在 Linux 系统中,一个用户可以属于一个组,也可以属于多个组,其中用户在初始化时属于的组称为主组。如果要让用户属于其它的组,应该使用选项 -G< 组列表 > 。 -u <uid> :指定新用户的 UID 。
设置和修改口令 : passwd  [ 用户名 ] 只有超级用户可以使用“ passwd  用户名”修改其他用户的口令,普通用户只能用不带参数的 passwd 命令修改自己的口令
演示 添加一用户,用户名为 user2008 修改某密码
删除用户的命令为 userdel ,该命令的格式为: userdel < 用户名 > 如果系统不要保存这些文件,可以使用带选项的命令: userdel -r < 用户名 >
修改用户属性 usermod –g< 主组名 > -G < 组名 > -d < 用户主目录 > -s < 用户 shell> 增加用户组 groupadd < 新组名 > 删除用户组 groupdel < 组名 > 修改组成员:直接编辑 /etc/group 文件,将用户名写到对应的组名的后面。
图形界面的用户管理
账号管理和查看命令   whoami 命令的功能在于显示用户自身的用户名。  who [ 选项 ] :该命令主要用于查看当前在线的用户情况  w 命令 :用于显示登录到系统的用户情况 finger 命令可用于查找和显示用户信息,并且在查找后显示指定账号的相关信息 chfn 命令能够改变系统存储的用户信息 切换用户身份: su - [ 用户名 ]
更改  Linux  文件拥有者命令 语 法:  chown [ -R ]  帐号名称   文件或目录   chown [ -R ]  帐号名称 : 组名   文件 或 目录   示例 :  [root@test root]# chown games test  [root@test root]# ls -l test  drw-r--r--    1 games     root        0 Jun 20 14:36 test [root@test root]# chown –R root:root tmp
更改  Linux  文件 所 属 群 组 语法 :  chgrp  群 组 名  文件 或 目录   示例 : [root@test root]# chgrp users test  [root@test root]# ls -l  drw-r--r--    1 root     users        1 Jun 20 14:36 test
系统安全设置 / 系统管理  BIOS 安全设置 安全分区  系统文件的权限  限制用户资源  系统升级
系统安全设置 / 用户安全管理  账号安全管理  suid 程序  口令安全管理  自动注销账号
suid 程序就是在运行的时候可以拥有比自己用户高的权限的用户的权限。 假设你有一个程序是属于 nobody 这个用户的,这个程序的功能是要修改一个文件,而这个文件的属性是只有 root 才能修改。所以如果这个程序在以写方式打开该文件的时候肯定出错,提示没有权限。 因此使用 chmod u+s  命令给程序授权,这样程序在运行后就会得到 root 的权限,从而就可以修改那个文件了。 最常用的就是 ping 这个命令,就是 suid 程序。 任何用户都可以使用这个命令,但是 ping 里面实际上是使用了 raw_socket ,而 raw_socket 只有 root 用户才可以创建。 所以 ping 命令大都放在 /bin 下,而不是 /usr/bin 下 而且使用 ls -l  察看 ping 的权限,是 -r-sr-xr-x
系统安全设置 / 网络服务安全管理 关闭不必要的服务 禁止响应 ping 命令  屏蔽系统信息
上机实验 实验内容:书本 219 页实验 1 上机地点:院楼 801 , 803 用户名: root 密码: xxxyjsjx
实验参考 一、修改配置文件的方法 ( 一 ) 、修改系统级的 PATH 环境变量 1, 编辑  /etc/profile, 文件,添加下面一行 export PATH=$PATH:/path1:/path2:/pahtN 2, 运行该文件 source  /etc/profile ( 二 ) 、修改用户级别的 PATH 环境变量 先进入用户目录: #cd /home/aaa #vi .bash_profile 添加同样一行 存盘退出 # souce .bash_profile 以上一个是全局的 PROFILE 一个是单独用户的 profile   二、命令行状态下直接修改环境变量 修改环境变量,在 bash 下用 export, 在 csh 下用 setenv 。比如:        export   PATH=$PATH:/usr/local/bin 
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
用户管理 / 命令   增加用户:  adduser [ 选项 ] <newusername>  -d <dirName> :指定用户主目录,默认情况下,将会在 /home 目录下新建一个与用户名相同的用户主目录。  -s <shellName> :指定用户登录时使用的 shell ,默认的 shell 为 /bin/bash 。  -g <gName> :指定用户归属的组名。 默认地,每当创建一个新用户的时候,一个与用户名相同的组就会被创建,而这个用户就是该组的成员。( UPG 方案)   -G < 组列表 > :在 Linux 系统中,一个用户可以属于一个组,也可以属于多个组,其中用户在初始化时属于的组称为主组。如果要让用户属于其它的组,应该使用选项 -G< 组列表 > 。 -u <uid> :指定新用户的 UID 。
设置和修改口令 : passwd  [ 用户名 ] 只有超级用户可以使用“ passwd  用户名”修改其他用户的口令,普通用户只能用不带参数的 passwd 命令修改自己的口令
演示 添加一用户,用户名为 user2008 修改某密码
删除用户的命令为 userdel ,该命令的格式为: userdel < 用户名 > 如果系统不要保存这些文件,可以使用带选项的命令: userdel -r < 用户名 >
修改用户属性 usermod –g< 主组名 > -G < 组名 > -d < 用户主目录 > -s < 用户 shell> 增加用户组 groupadd < 新组名 > 删除用户组 groupdel < 组名 > 修改组成员:直接编辑 /etc/group 文件,将用户名写到对应的组名的后面。
图形界面的用户管理
更改  Linux  文件拥有者命令 语 法:  chown [ -R ]  帐号名称   文件或目录   chown [ -R ]  帐号名称 : 组名   文件 或 目录   示例 :  [root@test root]# chown games test  [root@test root]# ls -l test  drw-r--r--    1 games     root        0 Jun 20 14:36 test [root@test root]# chown –R root:root tmp
更改  Linux  文件 所 属 群 组 语法 :  chgrp  群 组 名  文件 或 目录   示例 : [root@test root]# chgrp users test  [root@test root]# ls -l  drw-r--r--    1 root     users        1 Jun 20 14:36 test
账号管理和查看命令   whoami 命令的功能在于显示用户自身的用户名。  who [ 选项 ] :该命令主要用于查看当前在线的用户情况  w 命令 :用于显示登录到系统的用户情况 finger 命令可用于查找和显示用户信息,并且在查找后显示指定账号的相关信息 chfn 命令能够改变系统存储的用户信息 切换用户身份: su [ 用户名 ]
用户的安全管理 限制用户使用资源 编辑 /etc/security/limits.conf 自动注销账号 编辑 /etc/profile ,设置 tmout 变量的数值 Suid 程序
suid 程序就是在运行的时候可以拥有比自己用户高的权限的用户的权限。 假设你有一个程序是属于 nobody 这个用户的,这个程序的功能是要修改一个文件,而这个文件的属性是只有 root 才能修改。所以如果这个程序在以写方式打开该文件的时候肯定出错,提示没有权限。 因此使用 chmod u+s  命令给程序授权,这样程序在运行后就会得到 root 的权限,从而就可以修改那个文件了。 最常用的就是 ping 这个命令,就是 suid 程序。 任何用户都可以使用这个命令,但是 ping 里面实际上是使用了 raw_socket ,而 raw_socket 只有 root 用户才可以创建。 所以 ping 命令大都放在 /bin 下,而不是 /usr/bin 下 而且使用 ls -l  察看 ping 的权限,是 -r-sr-xr-x
如何去掉程序的 suid 位 find / -perm -4000  查找 chmod –s filename  去掉文件的 suid 位
存储设备  计算机系统中,所有的存储设备都是以目录树的形式对文件进行管理的  . 在 Linux 系统中,所有的文件都是在以“ /” 目录为根的一棵“大”目录树中进行管理。 如果要使用 USB 存储设备、光盘或软盘等存储设备,必须将这些设备中的“小”目录树像嫁接一样挂载( mount )到 Linux 系统的“大”目录树中。
挂载的文件系统类型 ext 、 FAT 、 ext2 ( extended file system  )、 ext3 、 MINIX 、 MSDOS 、 SYSV  Linux 系统的第一个文件系统是 Minix (文件名不能超过 14 个字符,文件大小不能超过 64MB ) ext : 1992 年设计,是第一个专为 linux 设计的文件系统,文件大小可到 2GB ,文件名支持 255 字符,性能不佳 ext2 :  1993 年设计,提高性能 ext3 :采用日志式文件系统技术( Journalling Filesystem ),目前各个 linux 发行版使用
Linux 引进 ext 文件系统时有了一个重大的改进:真正的文件系统从操作系统和系统服务中分离出来,在它们之间使用了一个接口层—虚拟文件系统 VFS(Virtual File System)
VFS Linux 系统可以支持多种文件系统,为此,必须使用一种统一的接口,这就是虚拟文件系统 (VFS) 。通过 VFS 将不同文件系统的实现细节隐藏起来,因而从外部看上去,所有的文件系统都是一样的。
VFS 并不是一个实际的文件系统 只存在于内存,系统启动时建立,系统关闭时消亡 VFS 功能包括: 记录可用文件系统的类型 将设备同对应的文件系统联系起来 处理面向文件的通用操作 涉及到针对文件系统的操作时,把他们映射到相关的物理文件系统
确定挂载信息  挂载对象的文件系统类型; vfat  ext2  ext3  iso9660 挂载对象的设备名称; 在 Linux 系统中,设备名称通常都在 /dev 目录下,设备名称的命名是有规则的  ; /dev/hda1  /dev/sda2  /dev/fd0  /dev/cdrom 设备挂载到哪一目录,即挂载点。 Linux 系统中有一个 /mnt 目录,专门用作挂载点( mount Point )目录  在挂载设备时首先查看挂载点目录是否存在,如果不存在必须首先创建该目录,否则 mount 命令无法正常执行。
挂载命令 mount  mount [ 选项 ] < 挂载设备名称 >  < 挂载点 > 选项: -t  挂载的文件系统 例如: mount  –t  ext2  /dev/fd0  /mnt/floppy -o [ 参数 = 值 ]  ,对于挂载的不同类型的设备可以使用一组不同的参数。  mount  -o  iocharset=cp936 /dev/sda1  /mnt/usb
挂载设备的过程  查看设备 :使用命令“ fdisk –l” 可以查看系统的存储设备 挂载设备  :首先使用 mkdir 命令建立挂载点目录,然后再使用 mount 命令挂载相关设备 访问设备 卸载设备  :用户在使用完挂载设备后,不能直接将挂载设备从系统拔出,否则会出现问题,严重的会导致系统崩溃。用户必须先执行卸载命令然后再该设备拔出 umount [ 挂载点或设备名 ]
自动挂载  使用配置文件 /etc/fstab 来自动挂载存储设备。 文件 /etc/fstab 存放的是系统中的文件系统信息。每个文件系统在文件中都对应一个独立的行 。 fsck 、 mount 、 umoun t 的等命令都利用这个文件 。 fstab 每一行为一个分区记录,包含六个域: <fs_spec> <fs_file> <fs_type> <fs_options> <fs_dump> <fs_pass> 例如: /dev/hda1  /mnt/c  vfat  iocharset=cp936 0  0
mount 命令 利用 fstab 文件, mount 还有另外两种使用格式 : mount –a 该命令将文件 /etc/fstab 中提到的所有文件系统,凡没使用 noauto 选项的,一律按照指定的方式自动挂载。该命令一般在系统的启动脚本中执行。 mount < 挂载点 >  或者  mount < 挂载设备名称 > 当挂载 fstab 中提到的文件系统时,可以只指定挂载设备或者只指定挂载点即可完成挂载。
图形化挂载工具  执行【主菜单 / 系统工具 / 磁盘管理】
磁盘格式化  mkfs [ 选项 ][-t < 文件系统类型 >] [ 设备名称 ] [ 区块数 ] 说明:把指定的设备格式为指定的文件系统。 例如格式化硬盘时: mkfs –t ext3 /dev/hda4 格式化软盘时,需要指定设备名和区块数,每个区块大约 1000 个字节,一张 1.44MB 的软盘对应 1440 个区块。格式化指令为: mkfs –t ext3 /dev/fd0 1440 执行菜单【主菜单 / 系统工具 / 软盘格式化器】,打开“ floppy formatter” 窗口 。图形化的格式化界面。
声卡  用户可以从声卡的生产厂商获取相应的驱动程序,并按相应的要求进行安装。 如果用户无法获取正确的驱动程序,也可以使用两种通用的驱动程序 : OSS (开放声音系统),它是一个商业声卡驱动程序,需要花钱购买,否则每次启动后,只可以免费使用 240 分钟; ALSA (高级 Linux 声音架构),是自由软件,可以免费使用。
安装 OSS 声卡驱动程序  可以从 http:// www.opensound.com / 下载最新的 OSS 驱动程序 ,假设下载了 ossLinux393q-2217-UP.tar.gz  解压缩源文件: 运行安装文件:以 root 用户身份运行 oss-install 文件 声卡驱动命令:安装完毕后,在默认的安装目录 /usr/local/bin 里有一个 soundon 命令,它用来打开 oss 驱动,命令 soundoff 用于关闭 oss 驱动。
安装 ALSA 声卡驱动程序 ALSA 源程序文件需要如下 4 个软件包,用户可以到 http://www.heihei.com/ 下载: alsa-driver-0.5.9.tar.gz :驱动程序包,包括所支持的声卡的驱动程序。 alsa-conf-0.4.3b.tar.gz :配置工具包,能够自动配置软件包中的配置文件。 alsa-lib-0.5.9.tar.gz :专用库函数包。 alsa-utils-0.5.9.tar.gz :工具软件包,提供支持混音调制的工具软件。
安装声卡驱动程序库:对文件 alsa-driver-0.5.9.tar.gz  ,依次执行: 1 )解压缩 2 ) ./configure # 自动配置命令 3 ) make install # 安装声卡驱动库 4 ) ./snddevices  # 这是一个脚本程序,在 /dev 目录下自动创建相关的声卡设备。   配置声卡驱动程序 安装混音程序
鼠标 :在终端输入命令 /usr/sbin/mouseconfig ,可以打开鼠标配置界面  在 X Window 下,选择【主菜单 / 系统设置 / 鼠标】打开图形界面的鼠标配置窗口
显卡 首先找到显卡支持 Linux 的驱动程序,绝大多数的 3D 显卡都已有了支持 Linux 的驱动程序,用户可以从各显卡厂商的网站或 Linux 的相关站点上去寻找。 如果用户能够进入 X Window ,但是无法使用显卡的特殊功能,那么可以通过图形界面的配置工具配置显卡。  选择【主菜单 / 系统配置 / 显示】,弹出显示设置窗口 。
打印机  获取打印机驱动程序  阅读安装文档 安装驱动程序  配置打印机 ,向系统添加打印机 测试打印机
上机实验 开机、登录 重启 ls 查看目录,进入 tmp 目录,在 tmp 下创建 test 目录,进入 test 目录,用 touch 创建一个文件,以自己学号命名,用 ls 查看该文件属性 压缩以上文件 解压以上文件 删除以上文件,删除以上目录
上机实验 创建一个用户,以自己的学号为用户名,密码自由设定。 在 linux 中使用 U 盘 把任意一个文件 copy 进 U 盘
使用 usb 参考 P79
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
关于硬连接、软连接、复制 硬连接:给文件一个副本(别名),同时建立两者之间的连接关系,修改其中一个,与其连接的文件同时被修改,如果删除其中一个,其余的文件不受影响。磁盘上只有一份数据。 软连接:只是一个快捷方式,删除了原文件,这个连接文件就没用了 复制:磁盘上会多一份数据
网络接口配置  配置网络接口可以使用三种不同的工具来完成: 使用网络接口配置程序 netconfig 使用图形配置工具 使用终端命令 ifconfig
使用网络接口配置程序 netconfig  在终端中输入命令 netconfig
使用图形配置工具  【主菜单 / 系统工具 / 网络设备控制】
 
使用终端命令 ifconfig  ifconfig < 设备名 > <IP 地址 > netmask < 掩码 >  例如: ifconfig eth0 192.168.15.11 netmask 255.255.255.0 fconfig eth1 21.156.299.13 netmask 255.255.255.0 ifconfig eth0:0 192.168.17.21 netmask 255.255.255.0
网络接口的启动与禁用  在网络配置界面中,通过“激活”或者“解除”按钮可以启动或者禁用网络接口, 网络控制程序 network  /etc/rc.d/init.d/network  start|stop|restart  命令 ifconfig : ifconfig < 设备名 > [up|down] 命令 ifup/ifdown  ifup eth0 ifdown eth0
网络接口的启动与禁用 执行【主菜单 / 系统工具 / 网络设备控制】,打开 “网络设备控制”窗口
网络接口的查看  使用终端命令 ifconfig 方便地查看系统目前所有活跃的网络接口的详细信息  例如: ifconfig ifconfig eth0
常用网络命令  网络测试命令  : ping [ 选项 ] < 目的主机名或 IP 地址 > ping 大数据包 -c num  发送 num 个数据包后停止 -s bytes  默认值是 64 字节 显示数据包经过路由的命令 traceroute  traceroute  < 目的主机 IP 或域名 >
管理路由表命令 route 显示路由表内容 : 不加任何参数的 route 命令显示本机路由表的内容, 添加 / 删除路由记录 route add|del –net < 网络号 > netmask < 网络掩码 > dev < 设备名 > route add –net 200.1.1.0 netmask 255.255.255.0 dev eth0 添加或者删除默认网关: route add|del default gw < 网关名或网关 IP> 例如: route add default gw 200.1.1.254 route del default gw 200.1.1.254
远程登录命令  telnet  < 主机名 /IP>  rlogin  <B 主机名或 IP 地址 >
网络相关配置文件 设定主机的不同端口的网络服务 /etc/services 定义使用的网络互联协议及协议号 /etc/protocols 域名服务器设置文件 /etc/resolv.conf 域名或主机名与 IP 地址的映射文件 /etc/hosts 域名解析的控制文件 /etc/host.conf 此目录下的文件是系统启动时用来初始化网络的一些信息,例如:第一块以太网卡对应的文件为 ifcfg-eth0 /etc/sysconfig/network-scripts/* 最基本的网络信息,系统启动时读取该文件 /etc/sysconfig/network 功能 配置文件名
/etc/sysconfig/network 对本机的网络进行配置,常见的几个配置项如下: NETWORKING :值为 yes 或 no ,表示主机是否支持网络功能。 HOSTNAME :主机名(即域名)。 GATEWAY:  默认网关。 FORWARD_IPV4: 设置本机是否允许转发 IPV4 的数据包。 DOMAINNAME: 此台主机所属的网络域。 GATEWAYDEV: 连接网关的设备,例如 eth0 ,如果是拨号用户则设为 ppp0 。
/etc/sysconfig/network-scripts/  DEVICE=eth0  // 设备名称  ONBOOT=yes  // 起动时是否起动该设备,省略该行表示 yes BOOTPROTO=none  // 启动协议 ,none 表示使用用户设置的 ip 地址 ,dhcp 表示从 dhcp 获得 ip 地址。省略该行表示使用设置的 IP 地址。 IPADDR=192.168.14.11  //IP 地址 NETMASK=255.255.255.0 // 子网掩码 BROADCAST=192.168.14.255// 广播地址 , NETWORK=192.168.14.0 // 网络地址
域名解析配置文件  /etc/host.conf  order hosts,bind multi on nospoof on
主机名列表文件 /etc/hosts  IP 地址 主机名 别名 例如: 192.168.14.15 qq.yys.com qq
域名服务器设置文件  /etc/resolv.conf  nameserver  <DNS 服务器 IP> domain  < 域名 >  search  < 域名列表 >
协议定义文件 /etc/protocols  协议名称  协议号  别名 例如: tcp  6  TCP udp  17  UDP
网络服务列表文件  /etc/services 列出了系统支持的服务名称、服务使用的端口号和协议类型、服务的别名、功能注释等。 例如 http 80/tcp www www-http #WorldWideWeb HTTP
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
网络服务管理工具  /etc/services 文件列出了 Linux 系统支持的所有服务的名称  介绍三种不同的管理工具 网络进程服务程序 xinetd
图形界面的管理工具  在 X Window 下执行【主菜单 / 系统配置 / 服务器设置 / 服务】
文本界面的管理工具  在终端中 输入命令 ntsysv
命令行界面的管理工具  命令 chkconfig 用于检查和设置系统的各种服务  添加指定的新服务: chkconfig --add  服务名 删除指定服务: chkconfig --del  服务名 显示所有或指定服务,以及他们在每个运行级别是否启动等: chkconfig --list  或 chkconfig --list [ 服务名 ] 检查指定服务的状态 : chkconfig  服务名 改变服务的运行级别及启动信息: chkconfig [--level  运行级 ]  服务名  [ 状态 ]
终端命令 service 用于设置网络服务的当前状态: service  服务名  [start|stop|restart] 管理员可以通过查看当前的进程树命令 pstree 来获知系统正在运行哪些服务 : pstree
超级服务器 xinetd  支持对 TCP 、 UDP 、 RPC 服务的管理 可以实施基于时间段的访问控制 功能完备的 log 功能,可以记录连接成功、连接失败的行为 能够有效地防止拒绝服务( DoS )的攻击 能够限制同时运行的同一类型的服务器的数目 能够限制 log 文件大小 能够将某个服务绑定在特定的系统接口上,从而实现只能允许私有网络访问某项服务。 能够实现作为其它系统的代理。
守护进程原理 在 Cl ie nt/Server 模式下。服务器监听( Listen )在一个特定的端口上等待客户连接。连接成功后服务器和客户端通过端口进行数据通信。守护进程的工作就是打开一个端口,并且等待( Listen )进入连接。 如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听其他的服务请求。
独立的守护进程 独立运行的守护进程由 init 脚本负责管理,所有独立运行的守护进程的脚本在 /etc/rc.d/init.d/ 目录下。 系统服务都是独立运行的守护进程包括: syslogd 和 cron 等。 运行独立的守护进程工作方式称作: stand - alone 。它是 Unix 传统的 C/S 模式的访问模式。服务器监听( Listen )在一个特点的端口上等待客户端的联机。如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听。以保持多个子服务器池等待下一个客户端请求。
 
Web 服务器 Ap ache 和邮件服务器 Sendmail 、域名服务器 Bind 应用独立守护进程模式启动。 因为这些负载很大服务器上,预先创子服务器,可以通过客户的服务速度。
Xinetd 模式 从守护进程的概念可以看出,对于系统所要通过的每一种服务,都必须运行一个监听某个端口连接所发生的守护进程,这通常意味着资源浪费。 为了解决这个问题, Linux 引进了“网络守护进程服务程序”的概念。 Redhat Linux 9.0 使用的网络守护进程是 xinted ( eXtended InterNET daemon )。和 stand - alone 模式相比 xinted 模式也称  Internet Super - Server (超级服务器)。 xinetd 能够同时监听多个指定的端口,在接受用户请求时,他能够根据用户请求的端口不同,启动不同的网络服务进程来处理这些用户请求。 可以把 xinetd 看做一个管理启动服务的管理服务器,它决定把一个客户请求交给那个程序处理,然后启动相应的守护进程。
 
运行单个 xinetd 就可以同时监听所有服务端口,这样就降低了系统开销,保护系统资源。但是对于访问量大、经常出现并发访问时, xinetd 想要频繁启动对应的网络服务进程,反而会导致系统性能下降。
超级服务器 xinetd 需要配置文件: /etc/xinetd.conf :控制 xinetd 程序运行的配置文件。其中,提供了所有服务的缺省配置。 /etc/xinetd.d/* :该目录包括所有由 xinetd 程序启动的服务的配置文件,每个服务都有自己单独的配置文件,配置文件名与服务名一致。
系统默认的 /etc/xinetd.conf 文件内容如下: # Simple configuration file for xinetd # # Some defaults, and include /etc/xinetd.d/ defaults { Instances = 60 log_type = SYSLOG authpriv log_on_success = HOST PID log_on_failure = HOST cps = 25 30 }
/etc/xinetd.d 目录  service telnet { disable =no # 表示允许 xinetd 启动本项服务 flags =REUSE  # 表示当中断或重启 xinetd 时, TCP/IP Socket 可重用 socket_type =stream  # 表示使用 TCP 的 Socket 类型 wait =no # 表示该服务提供多线程功能 user =root # 设置进程的 UID ,由 root 用户操作 server  =/usr/sbin/in.telnetd # 设置服务程序文件 log_on_failure+=USERID # 表示当连接失败时,系统除记录 /etc/xinetd.conf 文件中设置的内容外,还需记录用户 ID 。 }
演示一 配置 telnet 服务 编辑 /etc/xinetd.d/telnet  service telnet { …… disable=yes  ( 这里要改为 no) … .. } 保存退出 重新启动服务  service xinetd restart
vsFTPd 服务器  FTP 是一种文件传输协议,它实现了服务器与客户机之间的文件传输和资源的共享。 vsFTPd ( very secure FTP daemon )是一个功能强大的 FTP 服务器,能运行在大部分 UNIX  类作系统上,支持很多其他的 FTP 服务器不支持的特征: 支持虚拟 IP 支持虚拟用户 可以独立操作或者由 xinetd 管理  可以对每个用户进行配置 带宽限制 支持 IPv6 支持通过 SSL 的加密 高速
安装  下载源代码文件,并将文件解压缩 编译源代码: make 为 vsftpd 的运行准备条件  mkdir /var/ftp/ useradd -d /var/ftp ftp chown root.root /var/ftp chmod og-w /var/ftp 将可执行文件安装到 Linux 的系统目录中
启动 vsFTPd  也可以工作在两种模式:一种是自己启动运行的独立工作模式,另一种是借助 xinetd 管理的工作模式。 独立工作模式 :在 vsFTPd 的配置文件 /etc/vsftpd/vsftpd.conf 中,设置选项“ listen=YES” ,使用服务管理工具操作 vsftpd 程序了。  借助 xinetd 管理的工作模式:将前面的选项设置为“ listen=NO” ,并配置 /etc/xinetd.d/vsftpd 文件(以前的模式)
vsFTPd 的配置文件有三个: /etc/vsftpd/vsftpd.conf : vsFTPd 的主配置文件 /etc/vsftpd.ftpusers :vsFTPd 的访问控制 /etc/vsftpd.user_list:
vsftpd.conf anonymous_enable=YES // 允许匿名登录 local_enable=YES // 允许本地用户登录 write_enable=YES // 开放本地用户的写权限 dirmessage_enable=YES // 当切换目录时,显示该目录的信息。 connect_from_port_20=YES // 使用 FTP 数据端口 20 的连接请求 userlist_enable=YES // 与前面介绍的 vsftpd.user_list 配置文件有关,后面介绍 listen=YES // 是否允许 vsFTPd 运行在独立启动模式;如果值为 NO ,则需要使用其它软件启动 vsFTPd 。 tcp_wrappers=YES
userlist_enable  用法: YES/NO  若是启动此功能,则会读取 /etc/vsftpd.user_list  当中的使用者名称。此项功能可以在询问密码前就出现失败讯息,而不需要检验密码的程序。默认值为关闭。  userlist_deny  用法: YES/NO  这个选项只有在 userlist_enable  启动时才会被检验。如果将这个选项设为 YES ,则在  /etc/vsftpd.user_list  中的使用者将无法登入﹔ 若设为 NO  , 则只有在 /etc/vsftpd.user_list  中的使用者才能登入。而且此项功能可以在询问密码前就出现错误讯息,而不需要检验密码的程序。
应用实例  匿名登录: anonymous_enable=YES 本地用户登录: 1 )允许登录 为使用 FTP 的用户在本地建立账号 在 vsftpd.conf 中设置配置项: local_enable=YES   2) 上传文件  : 在 vsftpd.conf 中设置配置项: write_enable=YES
演示二 配置 vsftp ,按照独立模式配置
使用 xinetd 模式配置 vsftp--- 第一步 修改 /etc/vsftpd/vsftpd.conf  将  listen=YES  改为  listen=NO
使用 xinetd 模式配置 vsftp--- 第二步 新增一个文件: /etc/xinetd.d/vsftpd  内容如下:  service vsftpd  {  disable = no  socket_type = stream  wait = no  user = root  server = /usr/sbin/vsftpd  port = 21  log_on_success += PID HOST DURATION  log_on_failure += HOST  }  重启 xinetd
3 )访问控制 限制指定的本地用户不能访问,而其它本地用户可以访问。 userlist_enable= YES userlist_deny= YES userlist_file= /etc/vsftpd.user_list 限制指定的本地用户可以访问,而其它本地用户不可以访问。 userlist_enable= YES userlist_deny= NO userlist_file= /etc/vsftpd.user_list 无论何时都禁止指定的本地用户访问服务器 在 /etc/vsftpd.ftpusers 配置文件中保存了一个用户列表,如果哪个用户名在这个列表中,它就不能通过网络进行 FTP 登录。
DNS DNS ( Domain Name System )是一个分布式数据库,本地负责控制整个分布式数据库的部分段,每一段中的数据通过客户 / 服务器模式在整个网络上均可存取,通过采用复制技术和缓存技术,在保证整个数据库可靠的同时,又拥有良好的性能。  DNS 的数据库的结构是一个倒立的树状结构,根的名字用空字符串“”来表示,但在文本中用“ .” 来书写。树的每一个节点都表示整个分布式数据库中的一个分区(域),每个域可再进一步划分成子分区(域),每个域都有一个标签( LABEL ),标明了它与父域的关系。在 DNS 中,完整域名是一个从该域到根之间路径上的标签序列,以“ .” 分隔这些标签。
域名解析的工作原理主要由以下几步实现: 客户机将域名查询请求发送到本地 DNS 服务器,服务器在本地数据库中查找客户机要求的映射。 如果不能在本地找到客户机查询的信息,将客户机请求发送到根域名服务器。根域名服务器负责解析客户机请求的根域部分,它将包含下一级域名信息的服务器的地址返回给客户机的 DNS 服务器。 客户机的 DNS 服务器利用根域名服务器解析的地址访问下一级 DNS 服务器,得到维护再下一级域名的 DNS 服务器的地址。 按照上述方法递归地逐级接近查找目标,最后在维护目标域名的 DNS 服务器上找到相应的 IP 地址信息。 客户机的本地 DNS 服务器将查询结果返回客户机。 客户机利用从本地 DNS 服务器查询得到的 IP 地址访问目标主机。
配置实例 myoffice.myschool.org  192.168.14.11 shao.myoffice.myschool.org 主机 192.168.14.15 jing.myoffice.myschool.org 主机 192.168.14.16 zhao.myoffice.myschool.org 主机 192.168.14.16 ftp.myoffice.myschool.org FTP 服务器 192.168.14.16 www.myoffice.myschool.org Web 服务器 192.168.14.16 mail.myoffice.myschool.org 邮件服务器 192.168.14.12 dns.myoffice.myschool.org 域名服务器 IP 地址 域名 功能
配置  将 IP 地址映射为主机名的区文件 /var/named/14.168.192.in-addr.arpa.zone 将主机名映射为 IP 地址的区文件 /var/named/myoffice.myschool.org.zone 用户配置的区文件 用于回环 IP 地址 (127.0.0.1 ) 到本机名的映射 /var/named/0.0.127.in-addr.arpa.zone 本地主机正向解析 /var/named/localhost.zone localhost 区文件(默认) 根域名服务器的配置信息 /var/named/named.ca 根域名服务器指向文件 设置一般的 named 参数,指定该服务器使用的域数据库的信息源 /etc/named.conf 主配置文件 说明 文件名
演示三 配置 dns 服务
实验内容 1 配置 telnet 服务 1 、为 linux 配置一 ip 地址,并与隔壁的机器协商配置同一段的 ip 地址,即两台机器采用同一段 ip 地址,然后互相 ping 通; 2 、在本机以自己学号创建用户,并给予密码; 3 、编辑 /etc/xinetd.d/telnet  service telnet { …… disable=yes  ( 这里要改为 no) … .. } 保存退出 4 、重新启动服务  service xinetd restart 5 、从另一台机器 telnet 到本机  6 、把第 3 步当中的 yes 改回 no ,保存并退出,并重启服务
实验内容 2—— 配置 vsftp 服务 根据实验内容 1 的网络情况,默认已经安装了 vsftp ,使用 service vsftpd restart 启动服务 使用实验内容 1 中自己创建的用户进行登录 如 创建的是 test 用户,本机或另外一台机器命令行输入 ftp X.X.X.X ,提示输入用户名和密码 尝试修改 vsftp 的三个配置文件,修改后必须重启服务 使用命令行上传下载文件
假设两台机器 ip 地址为 10.1.3.9 和 10.1.3.10 在 10.1.3.9 有 jack 用户,启动 ftp 服务后,在 10.1.3.10 机器终端输入命令 ftp 10.1.3.9 这时会提示输入用户名和密码,这里假设使用 jack 用户登录,登录 ftp 后当前目录为 /home/jack ,用 ls 看有何文件 lcd /tmp  ( 把客户机目录切换到 tmp 下 ) bin  (使用二进制模式传输文件) get  filename  或  put filename bye
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
主要内容 Shell 的作用 Shell 程序的编辑和运行 基于 Bash 的 Shell 程序设计 变量声明 表达式 条件判断 控制结构 参数访问
Shell 的作用 shell 是用户和系统内核之间的接口程序  shell 是命令解释器  在本章中, shell 指 linux 的终端 即解释用户命令和 shell 程序的文字终端 用户 硬件 shell 操作系统 图形界面 其它用户界面
linux 下的 shell 用户使用 shell 的设定 通过查看 /etc/passwd 文件可以查看用户使用的 shell 类型 例子:  /etc/passwd 部分节选 webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin gdm:x:42:42::/var/gdm:/sbin/nologin htt:x:100:101:IIIMF Htt:/usr/lib/im:/sbin/nologin tom:x:500:500:tom:/home/tom:/bin/bash # 可见, tom 用户使用的 shell 为 bash
linux 下的 shell linux 下的 shell 通过 cat /ect/shells 命令查看安装的 shell shell 及路径 查看 shell 的命令
shell 程序 Shell 程序的特点及用途: shell 程序可以认为是将 shell 命令按照控制结构组织到一个文本文件中,批量的交给 shell 去执行  不同的 shell 解释器使用不同的 shell 命令语法 shell 程序解释执行,不生成可以执行的二进制文件 可以帮助用户完成特定的任务,提高使用、维护系统的效率  了解 shell 程序可以更好的配置和使用 linux
Shell 使用解释型语言,不需重新编译 它适合于编写执行相对简单的任务的工具,因为它更强调易于配置、维护和可移植性 它不适合用来完成时间紧迫型和处理器忙碌型的任务
基于 bash 的 shell 程序 简单程序示例 greeting.sh  echo &quot;Programme Ends.&quot; 12 say_hello 11 echo &quot;Programme Starts Here.....&quot; 10 } 9 echo &quot;Hello $name&quot; 8 read name 7 echo &quot;Enter Your Name,Please.  :&quot; 6 { 5 function say_hello() 4 #a Function 3 #a Simple shell Script Example 2 #!/bin/bash 1 解释 输出提示,提示程序结束 调用函数 程序开始的第一条命令,输出提示信息 函数结束 输出 读入用户的输入到变量 name echo 命令输出字符串 函数开始 以  functin   开始,定义函数 同上 以  #  开始,其后为程序注释 以   #!  开始,其后为使用的 shell
如何执行 可以使用  /bin/sh filename 或给该文件属性添加执行权限,然后直接执行
基于 bash 的 shell 程序 程序编译和运行过程 一般步骤: 编辑文件 保存文件 将文件赋予可以执行的权限 运行及排错 常用到的命令: vi ,编辑、保存文件 ls -l  查看文件权限 chmod  改变程序执行权限 直接键入文件名运行文件
shell 程序的编辑和执行 查看权限 查看权限,初始状态无执行( x )权限 增加可执行( x )的权限 查看权限,已经具备执行( x )权限 运行程序 程序运行过程输出
shell 程序设计 一般结构 shell 类型 函数 主过程 #!/bin/bash function fun1(){ } ...... funciton funn(){ } ........... . . . . . . 函数定义 shell 类型 主过程
变量的声明和使用 变量的声明和使用 变量是弱类型的 声明变量不用声明类型 可以存储不同类型的内容 使用灵活 使用时要明确变量的类型 大小写区分 变量声明及赋值格式 格式: 变量=值 (注意:等号两侧不能有空格) 例如: a=”hello ” b=9
变量的声明和使用 变量的引用 格式 : $ 变量名,或者 ${ 变量名 } 变量名为一个字符用方式一,变量名多于一个字符建议用第 2 中方式 例子: a=1 abc=&quot;hello&quot; echo $a echo ${abc}
Linux 是一个大小写敏感的系统, shell 认为变量 foo 与 Foo 是不同的,与 FOO 也不同 当为变量赋值时,只需要使用变量名,该变量会被自动创建 要使用变量,必须在变量前加 $ 符号
演示 salutation=hello echo $salutation hello salutation=“yes dear” echo $salutation yes dear salutation=7+5 echo $salutation 7+5
注意: 如果字符串里包含空格,就必须用引号把它们括起来 还要注意在等号两边不能有空格
使用 read 将用户的输入赋值给变量 read salutation I’m jack. echo $salutation I’m jack
使用引号 如果在参数中包含一个或多个空白字符,必须给参数加双引号 如果把一个带有 $ 字符的变量放在双引号中,程序执行到该行时会把变量替换为它的值 如果你把它放在单引号中,不会发生替换现象 可用 \ 字符取消 $ 的特殊含义 字符串通常被放在双引号中
演示 #!/bin/sh myvar=“Hi there” echo $myvar echo “$myvar” echo ‘$myvar’ echo \$myvar echo Enter some text read myvar echo ‘$myvar’ now equals $myvar exit 0
环境变量 $HOME  当前用户的主目录 $PATH  以冒号分隔的用来搜索命令的目录列表 $PS1  命令提示符,通常是 $ 字符 $PS2  二级提示符 $IFS  输入域分隔符,当 shell 读取输入时,用来分隔单词的一组字符,它们通常是空格、制表符 $0  shell 脚本的名字 $#  传递给脚本的参数个数 $$  shell 脚本的进程号
提示符特殊字符代码 字符 含义 \!  显示该命令的历史记录编号。 \#  显示当前命令的命令编号。 \$  显示 $ 符作为提示符,如果用户是 root 的话,则显示 # 号。 \\  显示反斜杠。 \d  显示当前日期。 \h  显示主机名。 \n  打印新行。 \nnn  显示 nnn 的八进制值。 \s  显示当前运行的 shell 的名字。 \t  显示当前时间。 \u  显示当前用户的用户名。 \W  显示当前工作目录的名字。 \w  显示当前工作目录的路径。
参数变量 $1 $2 $3 …..  脚本程序的参数 $*  在一个变量中列出所有的参数,各个参数之间用环境变量 IFS 中的第一个字符分隔开 $@  它是 $* 的一种变体,它不使用 IFS 环境变量,所以当 IFS 为空时,参数的值不会结合在一起
演示 $ IFS=‘’ $ set foo bar bam $ echo “$@” foo bar bam $ echo “$*” foobarbam $ unset IFS $ echo “$*” foo bar bam
演示 #!bin/sh sa=&quot;Hello&quot; echo $sa echo &quot;the program $0 is now running&quot; echo &quot;the second parameter was $2&quot; echo &quot;the first parameter was $1&quot; echo &quot;the parameter list was $*&quot; echo &quot;the user's home directory is $HOME&quot; echo &quot;please enter a new word&quot; reas sa echo $sa echo &quot;the script is now complete&quot; exit 0
常用的运算符 整数的算术运算符  + 、-、 * 、 / 、 % ;  赋值运算符  +=、-=、 * =、 / =、%=  位运算符  << 、 >> 、 & 、 | 、 ~ 、 ^ ;  位运算赋值运算符  << =、 >> =、 & =、 | =、 ~ =、 ^ =; 逻辑运算符:  && , || , ! , > , > =, < , < =,!=,==
简单数学表达式 expr 命令计算一个表达式的值  格式  :expr arg 例子:计算( 2 + 3 ) ×4 的值 1 、分步计算,即先计算 2 + 3 ,再对其和乘 4 s=`expr 2 + 3` expr $s \* 4 2 、一步完成计算: expr  `expr 2 + 3 `  \* 4   说明: 运算符号和参数之间要有空格分开; 通配符号( * ) , 在作为乘法运算符时要用 \ 、“”、‘’符号修饰
简单数学表达式 let 命令  格式: let arg1 [arg2 ......] 例子:计算( 2 + 3 ) ×4 的值 let s=(2+3)*4 说明: 与 expr 命令相比, let 命令更简洁直观 当运算符中有 < 、 > 、 & 、 | 等符号时,同样需要用引号(单引号、双引号)或者斜杠来修饰运算符
条件判断 常见的条件: 变量属性; 文件属性; 命令执行结果; 多种条件的逻辑组合; 判断结果的一般定义: 真: 0 假: 1 格式: test condition [ condition ]
条件判断 测试文件属性 如果 fn 存在且 fn 为符号链接则返回真,否则返回假。 -L  fn 如果 fn 存在且被当前用户拥有则返回真,否则返回假。 -O  fn 如果 fn 存在且 fn 可执行则返回真,否则返回假。 -x  fn 如果 fn 存在且 fn 可写则返回真,否则返回假。 -w  fn 如果 fn 存在且 fn 可读则返回真,否则返回假。 -r  fn 如果 fn  存在且 fn 为目录则返回真,否则返回假。 -d  fn 如果 fn 存在则返回真,否则返回假。 -e  fn 如果 fn 存在且 fn 为块设备则返回真,否则返回假。 -b  fn 如果 fn 存在且 fn 为普通文件则返回真,否则返回假。 -f  fn 常用的文件属性条件判断
条件判断 字符串属性  同 -n string ,如果字符串 string 长度不为 0 返回真,否则返回假。 string 如果字符串 string 长度不为 0 则返回真,否则返回假; -n string 如果字符串 string 的长度为 0 则返回真,否则返回假; -z string 如果 string_1 和 string_2 两个字符串不相等则返回真,否则返回假; string_1 != string_2 如果 string_1 和 string_2 两个字符串相等则返回真,否则返回假; string_1 = string_2 常用字符串属性条件判断
整数关系 整数间关系判断 如果 num_1 大于等于 num_2 则返回真,否则返回假; mum_1 –ge num_2 如果 num_1 小于等于 num_2 则返回真,否则返回假; mum_1 –le num_2 如果 num_1 小于 num_2 则返回真,否则返回假; mum_1 –lt num_2 如果 num_1 大于 num_2 则返回真,否则返回假; mum_1 –gt num_2 如果 num_1 不等于 num_2 则返回真,否则返回假; mum_1 –ne num_2 如果 num_1 和 num_2 相等则返回真,否则返回假; mum_1 –eq num_2 常用的整数关系条件判断
管道和重定向 ls –l > lsoutput.txt 该命令把 ls –l 的结果输出到 lsoutput.txt 文件中 通过 > 把标准输出重定向到一个文件,如果该文件已经存在,会覆盖文件的内容 可以用 >> 追加文件内容,而不是覆盖
重定向 文件描述符 0 代表一个程序的标准输入 文件描述符 1 代表一个程序的标准输出 文件描述符 2 代表一个程序的标准错误输出
重定向 如果想对标准错误进行重定向,需要把准备重定向的文件描述符编号加在 > 操作符的前面,即 2> ,当需要丢弃错误信息并阻止它显示在屏幕,这个方法很有用 kill –HUP 1234 >killout.txt 2>killerr.txt kill –l  1234 >killouterr.txt 2>&1 (2>&1 意思是把标准输出重定向到文件 killouterr.txt ,然后将标准错误输出重定向到与标准输出相同的地方,顺序不可有误 ) Kill –l 1234 >/dev/null 2>&1 (可以用“回收站” /dev/null 来有效丢弃所有输出信息)
管道 管道符  | 用于连接进程 通过管道连接的进程可以同时运行 , 并且随着数据流在它们之间的传递可以自动地进行协调 ls –l | grep hello  ls –l | more ls –l | grep hello > lsoutput.txt
控制结构 控制结构: 根据某个条件的判断结果,改变程序执行的路径。可以简单的将控制结构分为分支和循环两种 。 常见分支结构: if case 常见循环结构: for while until
if 分支 格式: 说明: 中括号中的部分可省略; 当条件为真( 0 )时执行 then 后面的语句,否则执行 else 后面的语句; 以 fi 作为 if 结构的结束。 if  条件 1 then 命令 [elif  条件 2 then 命令 ] [else 命令 ] fi
#!/bin/sh echo –n “Is it morning? Please answer yes or no? read timeofday If [ $timeofday = “yes” ] then echo “Good morning” elif [ $timeofday = “no” ]; then echo “Good afternoon” else  echo “sorry,$timeofday not recognized. Enter yes or no” exit 1 fi exit 0
echo 语法 echo –n 命令去除换行符
case 分支 格式: 说明: “ 条件”可以是变量、表达式、 shell 命令等; “ 模式”为条件的值,并且一个“模式”可以匹配多种值,不同值之间用竖线( | )联结 ; 一个模式要用双分号(;;)作为结束 ; 以逆序的 case 命令( esac )表示 case 分支语句的结束  case  条件  in 模式 1) 命令 1 ;; [ 模式 2 ) 命令 2 ;; ............... 模式 n ) 命令 n ;; ] esac
? :仅与一个任意字符匹配 * :匹配任意字符 [...] :同方括号中的任意一个字符相匹配。这些字符可以用字符范围 ( 比如  1-9) 或者 离散值 或同时使用两者表示。例如: [a-zBE5-7]  同所有  a  到  z  之间的字符和  B 、 E 、 5 、 6 、 7  相匹配。 [!...] :与所有 不在 方括号中的某个字符匹配。例如  [!a-z]  同某个非小写字母相匹配 [ 5 ] ; {c1,c2} :同  c1  或者  c2  相匹配。其中  c1  和  c2  也是通配符。因此,您可以使用  {[0-9]*,[acr]} 。
以下是一些通配符模式及其说明: /etc/*conf : /etc  目录中所有以  conf  结尾的文件。它将同  /etc/inetd.conf 、 /etc/conf.linuxconf , 并且也会同  /etc/conf  相匹配。请注意, *  也匹配空字符串。 image/{cars,space[0-9]}/*.jpg : image/cars 、 image/space0 、 (...) 、 image/space9  目录中以  .jpg  结尾的文件。 /usr/share/doc/*/README :所有  /usr/share/doc  的直接子目录中的全部  README  文件。比如  /usr/share/doc/mandrake/README 。但是不包括  /usr/share/doc/myprog/doc/README 。 *[!a-z] :当前目录中 不以 小写字符结尾的全部文件。
#!/bin/sh echo &quot;Is it morning? Please answer yes or no?&quot; read timeofday case &quot;$timeofday&quot; in yes | y | Yes | YES ) echo &quot;good morning&quot; ;; [nN]* ) echo &quot;good afternoon&quot; ;; * ) echo &quot;error&quot; exit 1 ;; esac exit 0
for 循环 格式 说明: “ 列表”为存储了一系列值的列表,随着循环的进行,变量从列表中的第一个值依次取到最后一个值; do 和 done 之间的命令通常为根据变量进行处理的一系列命令,这些命令每次循环都执行一次; 如果中括号中的部分省略掉, Bash 则认为是“ in $@” ,即执行该程序时通过命令行传给程序的所有参数的列表。   for  变量  [in  列表 ] do 命令(通常用到循环变量) done
#!/bin/sh for var in v1 v2 v3 do  echo $var done exit 0
#!/bin/sh for file in $(ls f*.sh); do lpr $file done exit 0
while 循环与 until 循环 格式: 说明: while 循环中,只要条件为真,就执行 do 和 done 之间的循环命令;  until 循环中,只要条件不为真,就执行 do 和 done 之间的循环命令,或者说,在 until 循环中,一直执行 do 和 done 之间的循环命令,直到条件为真; 避免生成死循环。  while/until  条件 do 命令 done
#!/bin/sh foo=1 while [ &quot;$foo&quot; -le 20 ] do  echo &quot;$foo&quot; foo=$(($foo+1)) done exit 0
#!/bin/sh until who | grep &quot;$1&quot; > /dev/null do  sleep 30 done echo -e  echo &quot;$1 has just logged in&quot; exit 0
函数 格式: 定义: 引用: 说明: 中括号中的部分可以省略; 如果在函数内部需要使用传递给函数的参数,一般用 $0 、 $1 、 ...... 、 $n ,以及 $# 、 $* 、 $@ 这些特殊变量 : $0 为执行脚本的文件名; $1 是传递给函数的第 1 个参数 ; $# 为传递给函数的参数个数;  $* 和 $@ 为传递给函数的所有参数  [function]  函数名() { 命令 } 函数名  [  参数 1  参数 2 ... 参数 n ]
函数对变量的访问示例 即变为下一个变量 变量左移, $1 变为原来 $1 的右侧的变量 变量计数加 1 输出第一个变量 访问变量 $1, 即第一个变量 函数开始 ...... } done shift let count=$count+1 echo &quot;Parameters(\$$count) is:$1&quot; do while [ -n &quot;$1&quot; ] ...... { function demo_fun() 利用 shift 访问参数变量
实验任务一  设计一个菜单驱动程序。如下: Use one of the following options: P:  To display current directory S:  To display the name of running file D:  To display today’s date and present time L:  To see the listing of files in your present working directory W:  To see who is logged in Q:  To quit this program Enter your option and hit : 菜单程序将根据用户输入的选择项给出相应信息。要求对用户的输入忽略大小写,对于无效选项的输入给出相应提示。 要求使用 case 语句实现以上功能,输入响应的字母后应该执行响应的命令完成每项功能,如输入 P 或 p ,就执行 pwd 命令。
实验任务二  编写一段 bash shell 程序,完成:根据从键盘输入的学生成绩,显示相应的成绩等级,其中 60 分以下为“ Failed !”, 60-70 分为“ Passed !”, 70-80 分为“ Medium !”, 80-90 分为“ Good !”, 90-100 为“ Excellent !”。 如果输入超过 100 的分数,则显示错误分数提示。
注意事项:实验要求有良好格式,有正确的返回码指令,实验完成后所有人要提交实验报告,报告内容包括实验题目、程序流程图、程序代码、运行效果图。 学号尾数为 2 的同学检查任务一,学号尾数为 8 的同学检查任务二。检查时间为 11 月 12 日上机,报告提交时间为 11 月 12 日理论课中。
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
进程的概念 Linux 系统上所有运行的东西都可以称之为一个进程。每个用户任务、每个系统管理任务,都可以称之为进程。进程是一个程序的运行。  进程与程序是有区别的。程序只是一个静态的指令集合,不占系统的运行资源;而进程是一个随时都可能发生变化的、动态的、使用系统运行资源的程序。一个程序可以启动多个进程。
进程的概念 Linux 操作系统包括三种不同类型的进程,每种进程都有自己的特点和属性: 交互进程 : 由 shell 启动的进程。 批处理进程 : 这种进程和终端没有联系,是一个进程序列。 守护进程 : 在后台持续运行的进程。
启动进程 / 手工启动  前台启动 : 一般地,用户键入一个命令,就已经启动了一个前台的进程。 后台启动  : 对于非常耗时进程,可以让进程在后台运行。从后台启动进程其实就是在命令结尾加上一个“ &” 号
启动进程 / 调度启动  1 ) at 命令 在 shell 提示符下输入” at  时间”,然后按回车键。这时在下一行 shell 会等待用户继续输入要执行的命令。每一行输入一个命令,所有命令都输入完毕后按 Ctrl+d 键结束。 将各个命令写入 shell 脚本中,然后使用下面格式设置在指定时间执行 shell 脚本中的命令: at  时间 – f  脚本文件。  batch 命令
启动进程 / 调度启动  /cron 命令 cron 命令在系统启动时由一个 shell 脚本自动启动,进入后台。 cron 启动后搜索 /var/spool/cron 目录,寻找以 /etc/passwd 文件中的用户名命名的 crontab 文件,被找到的这种文件将载入内存。 如果没有 crontab 文件,就转入“休眠”状态,释放系统资源。 cron 每分钟“醒”过来一次,查看当前是否有需要运行的命令。 如果发现某个用户设置了 crontab 文件,它将以该用户的身份去运行文件中指定的命令。命令执行结束后,任何输出都将作为邮件发送给 crontab 的所有者,或者 /etc/crontab 文件中 MAILTO 环境变量中指定的用户。
cron crontab 文件格式 59 23 * * * tar czvf lhy.tar.gz /home/lhy crontab 命令用于安装、删除或者列出用于驱动 cron 后台进程的 crontab 文件  : crontab 源文件格式 <minute> <hour> <day-of-month> <month-of-year> <day-of-week> <commands> 59 23 * * * tar czvf lhy.tar.gz /home/lhy
格式 crontab [  - u user ]  文件 crontab [  - u user ] {  - l |  - r |  - e } 主要参数 - e :执行文字编辑器来设定时程表,内定的文字编辑器是 vi - r :删除目前的时程表 - l :列出目前的时程表 和 at 命令相比, crontab 命令适合完成固定周期的任务
Crontab 举例 以某一用户终端,输入 crontab  - e 此时系统会打开一个 vi 编辑器 在该编辑器中输入 35 17 * * 5 wall &quot;Tomorrow is Saturday I will go CS&quot;
进程管理命令  进程查看命令  ps  ps [ 选项 ] 主要选项的含义如下: -e :显示所有进程; -h :不显示标题; -l :采用详细的格式来显示进程; -a :显示所有终端上的进程,包括其他用户的进程; -r :只显示当前终端上正在运行的进程; -x :显示所有进程,不以终端来区分; -u :以用户为主的格式来显示进程;
删除进程命令 kill kill [-s < 信号 > | -p ] [ -a ] < 进程号 > ..  kill [-s < 信号 > | -p ] [ -a ] < 进程号 > ... kill -l [ 信号 ]  选项的含义如下: -s :指定需要送出的信号。既可以是信号名也可以是信号名对应的数字。 -p :指定 kill 命令只显示命名进程的 pid ,并不真正送出任何信号。 -l :显示信号名称列表,该列表也可以在 /usr/include/linux/signal.h 文件中找到。
强行中止(经常使用杀掉)一个进程标识号为 324 的进程: # kill  - 9 324   解除 Linux 系统的死锁  使用命令回收内存  killall 命令 Linux 下还提供了一个 killall 命令,可以直接使用进程的名字而不是进程标识号,例如: #  killall -HUP inetd
系统监视  系统监控命令 top  :能显示实时的进程列表,而且还能实时监视系统资源,包括内存、交换分区和 CPU 的使用率等。
 
top 命令使用过程中,可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。 < 空格 > :立刻刷新。 P :根据 CPU 使用大小进行排序。 T :根据时间、累计时间排序。 q :退出 top 命令。 m :切换显示内存信息。 t :切换显示进程和 CPU 状态信息。 c :切换显示命令名称和完整命令行。 M :根据使用内存大小进行排序。
内存查看命令 free  磁盘空间用量查看命令 df
图形化的系统监视器
 
日志查看  日志文件( log files )是包含关于系统消息的文件,包括内核、服务、在系统上运行的应用程序等。 不同的日志文件记载不同的信息。  多数的日志文件位于 /var/log 目录下。 某些程序(如 apache )在 /var/log 中有单独的日志文件目录。  日志可以滚动
 
日志查看  多数日志文件都使用纯文本格式,可以使用任何文本编辑器如 vi 来查看它们。 大多数日志文件都需要拥有特权才允许查看。  图形化的日志查看器
 
Grep 用法 grep  ( global search regular expression(RE) and print out the line, 全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具  使用正则表达式搜索文本  linux 使用 GNU 版本的 grep
grep 正则表达式元字符集(基本集)  ^  锚定行的开始 如: '^grep' 匹配所有以 grep 开头的行。  $  锚定行的结束 如: 'grep$' 匹配所有以 grep 结尾的行。  .  匹配一个非换行符的字符 如: 'gr.p' 匹配 gr 后接一个任意字符,然后是 p 。  *  匹配零个或多个先前字符 如: '*grep' 匹配所有一个或多个空格后紧跟 grep 的行。  .* 一起用代表任意字符。 []  匹配一个指定范围内的字符,如 '[Gg]rep' 匹配 Grep 和 grep 。  [^]  匹配一个不在指定范围内的字符,如: '[^A-FH-Z]rep' 匹配不包含 A-R 和 T-Z 的一个字母开头,紧跟 rep 的行。  \(..\)  标记匹配字符,如 '\(love\)' , love 被标记为 1 。
\<  锚定单词的开始,如 :'\<grep' 匹配包含以 grep 开头的单词的行。  \>  锚定单词的结束,如 'grep\>' 匹配包含以 grep 结尾的单词的行。  x\{m\}  重复字符 x , m 次,如: '0\{5\}' 匹配包含 5 个 o 的行。  x\{m,\}  重复字符 x, 至少 m 次,如: 'o\{5,\}' 匹配至少有 5 个 o 的行。  x\{m,n\}  重复字符 x ,至少 m 次,不多于 n 次,如: 'o\{5,10\}' 匹配 5--10 个 o 的行。 \w  匹配文字和数字字符,也就是 [A-Za-z0-9] ,如: 'G\w*p' 匹配以 G 后跟零个或多个文字或数字字符,然后是 p 。 \W  \w 的反置形式,匹配一个或多个非单词字符,如点号句号等。 \b  单词锁定符,如 : '\bgrep\b' 只匹配 grep 。
$ ls -l | grep '^a'  通过管道过滤 ls -l 输出的内容,只显示以 a 开头的行。 $ grep 'test' d*  显示所有以 d 开头的文件中包含 test 的行。 $ grep 'test' aa bb cc  显示在 aa , bb , cc 文件中匹配 test 的行。 $ grep '[a-z]\{5\}' aa  显示所有包含每个字符串至少有 5 个连续小写字符的字符串的行
awk 命令 最基本功能是在文件或字符串中基于指定规则浏览和抽取信息  df | awk '$4>1000000 '  通过管道符获得输入,如:显示第 4 个域满足条件的行
实验任务三(学号尾数为 0 , 1 的检查) 编写一个 Shell 过程完成如下功能(必须在脚本中使用函数): 1 、合并两个 $1 、 $2 文件为 $3 ,并显示。 2 、如果缺少 $3 ,那么先报告缺少 $3 ,然后将合并后的内容输出到 mydoc.txt 。如果有 $3 ,就合并到 $3 3 、如果缺少 $2 、 $3 那么先报告缺少 $2 、 $3 ,只显示 $1 的内容。
实验任务四(学号尾数为 3 的检查) 利用所学知识,实现如下目标: 某用户需要在每天晚上 11 点启动服务器的 ftp 服务,使得其他用户可以上传重要数据。而在每天凌晨 3 点就关闭 ftp 服务。在这个过程中要自动记录日志信息,每天是否成功启动 ftp 要体现在日志信息中,如果成功启动必须记录 ftp 的进程信息,如果没有启动,就记录错误信息。 约定如下: 日志文件为 /tmp/ftplog 实验任务四在上机检查时应把时间调整为当前具体可行的时间。
实验任务五(学号尾数为 7 的检查) 编写一个脚本,显示当天日期,查找给定的某用户是否在系统中工作。如果在系统中,就发一个问候给他。
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
主要内容 gcc 简介 功能 命令 利用 gcc 编译 c 程序 利用 make 工具简化编译过程 make 简介 Makefile 基本格式 调试 静态调试 动态调试 gdb 调试工具的使用
gcc 简介 名称: G NU project  C  and  C ++  C ompiler  G NU  C ompiler  C ollection  管理与维护 GNU 项目  对 C/C++ 编译的控制 预处理( Preprocessing ) 编译( Compilation ) 汇编( Assembly ) 链接( Linking  )
gcc 的使用 基本使用格式  $ gcc  [  选项  ]  < 文件名 > 常用选项及含义 将经过 gcc 处理过的结果存为文件 file ,这个结果文件可能是预处理文件、汇编文件、目标文件或者最终的可执行文件。假设被处理的源文件为 source.suffix ,如果这个选项被省略了,那么生成的可执行文件默认名称为 a.out ;目标文件默认名为 source.o ;汇编文件默认名为 source.s ;生成的预处理文件则发送到标准输出设备。 -o  file 含义 选项 gcc 常用选项
gcc 的常用选项 含义 选项 gcc 常用选项 将名为 name 的宏定义为 definition ,如果中括号中的部分缺省,则宏被定义为 1 -D name[=definition] 对生成的代码使用优化,中括号中的部分为优化级别,缺省的情况为 2 级优化, 0 为不进行优化。注意,采用更高级的优化并不一定得到效率更高的代码。 -O[0 、 1 、 2 、 3] 在可执行文件中加入调试信息,方便进行程序的调试。如果使用中括号中的选项,表示加入 gdb 扩展的调试信息,方便使用 gdb 来进行调试 -g[gdb] 仅对源文件进行编译,不链接生成可执行文件。在对源文件进行查错时,或只需产生目标文件时可以使用该选项。 -c
gcc 的常用选项 含义 选项 gcc 常用选项 允许产生 warning 类型的警告, warning 可以是: main 、 unused 等很多取值,最常用是 -Wall ,表示产生所有警告。如果 warning 取值为 error ,其含义是将所有警告作为错误( error ),即出现警告就停止编译。 -W warning 禁止所有警告 -w 在编译链接文件时增加一个额外的库,库名为 library .a -l library 在编译源文件时增加一个搜索库文件的额外目录—— dir -L dir 在编译源程序时增加一个搜索头文件的额外目录—— dir ,即 include 增加一个搜索的额外目录。 -I dir
gcc 文件扩展名规范  gcc 可以根据文件扩展名执行操作 链接 目标文件 .o 不进行任何操作 头文件 .h 预处理、汇编、链接 未预处理的汇编程序 .S 汇编、链接 预处理后的汇编程序 .s 编译、汇编、链接 预处理后的 c++ 语言源程序 .ii 编译、汇编、链接 预处理后的 c 语言源程序 .i 预处理、编译、汇编、链接 c++ 语言源程序 .C , .cc , .cp , .cpp , .c++ , .cxx 预处理、编译、汇编、链接 c 语言源程序 .c 可进行的操作方式 类型 扩展名 gcc 文件扩展名规范
使用 gcc 编译代码 源代码 示例源程序—— hello.c #include <stdio.h> int main(void) { printf(&quot;hello gcc!\r\n&quot;); return 0; }
生成预处理文件 命令 $gcc  –E  hello.c  –o  hello.i 预处理文件 hello.i 的部分内容 ...... extern void funlockfile (FILE *__stream) ; # 679 &quot;/usr/include/stdio.h&quot; 3 # 2 &quot;hello.c&quot; 2 int main(void) { printf(&quot;hello gcc!\n&quot;); return 0; }
生成汇编文件 命令 $gcc  –S  hello.c  –o  hello.s 汇编文件 hello.s 的部分内容 ...... main: pushl %ebp movl %esp, %ebp ........ addl $16, %esp movl $0, %eax leave ret ......&quot;
编译多个文件 文件清单 #endif  void greeting (char * name); #define _GREETING_H #ifndef _GREETING_H  greeting.h  { printf(&quot;Hello %s!\r\n&quot;,name);  }  void greeting (char * name) #include &quot;greeting.h&quot; #include <stdio.h> greeting.c  char name[N];  printf(&quot;Your Name,Please:&quot;);  scanf(&quot;%s&quot;,name);  greeting(name);  return 0;  int main(void) { }  #define N 10 #include &quot;greeting.h&quot; #include <stdio.h> my_app.c
生成二进制文件 生成目标文件 命令: $gcc  –c  hello.c  –o  hello.o 生成可执行文件 命令: $gcc hello.c  –o  hello 运行程序 $./hello hello gcc!
编译多个文件 目录结构 (1) 编译命令 $ gcc  my_app.c  greeting.c   –o  my_app 目录结构 (2) 编译方式 (1) $ gcc my_app.c  functions/greeting.c   –o my_app  -I function   greeting.h ./ greeting.c my_app.c greeting.h ./ greeting.c my_app.c functions
编译多个文件 目录结构 (2) 编译方式 (2) 分步编译 命令: 1 、 $gcc  -c  my_app.c  -Ifunctions  2 、 $gcc  -c   functions/greeting.c 3 、 $gcc  my_app.o  greeting.o   –o my_app 思路: 编译每一个 .c 文件,得到 .o 的目标文件; 将每一个 .o 的目标文件链接成一个可执行的文件;
使用 make 工具 适用场合: 多个文件组成的软件项目 基本格式: 目标:欲生成的目标文件 依赖项:生成目标需要的文件 原理: 判断依赖项是否为最新,否则,生成新的目标 make 工具的使用格式: make [[ 命令选项 ] [ 命令参数 ]] 通常使用 make 就可以了, make 会寻找 Makefile 作为编译指导文件; 目标:依赖项列表 ( Tab 缩进)命令
使用 make 工具 Makefile 示例 gcc –c my_app.c –Ifunctions 6 my_app.o:my_app.c functions\greeting.h 5 gcc -c functions\greeting.c 4 greeting.o:functions\greeting.c functions\greeting.h 3 gcc my_app.o greeting.o -o my_app 2 my_app:greeting.o my_app.o 1 Makefile 文件
使用 make 工具 目标的依赖关系 my_app my_app.o greeting.o my_app.c functions\greeting.h functions\greeting.c gcc –c my_app.c –Ifunctions  gcc -c functions\greeting.c  gcc my_app.o greeting.o -o my_app
使用 make 工具 更实用的 Makefile ${CC} ${CFLAGS} -c my_app.c -Ifunctions 9 my_app.o:my_app.c functions\greeting.h 8 ${CC} ${CFLAGS} -c functions\greeting.c 7 greeting.o:functions\greeting.c functions\greeting.h 6 ${CC} ${OBJS} -o my_app 5 my_app:${OBJS} 4 CFLAGS = -Wall -O –g 3 CC = gcc 2 OBJS = greeting.o my_app.o 1 更实用的 Makefile 文件
调试 调试 静态调试: 在程序编译阶段查错并修正错误; 主要为语法错误: 输入错误; 类型匹配错误; 排错方式: 利用错误、警告信息,并结合源文件环境排错 动态调试: 在程序运行阶段差错并修正错误; 主要错误类型: 算法错误; 输入错误; 排错方式: 利用调试工具定位并修正错误;
调试举例 源文件 #endif  void greeting (char * name); #define _GREETING_H #ifndef _GREETING_H  greeting.h  { printf(&quot;Hello !\r\n&quot;);  }  void greeting (char * name) #include &quot;greeting.h&quot; #include <stdio.h> greeting.c  11 10 9 8 7 6 5 4 3 2 1 char name[n];  printf(&quot;Your Name,Please:&quot;);  scanf(&quot;%s&quot;,name) greeting(name);  /*return 0;*/  int main(void) { }  #define N 10 #include &quot;greeting.h&quot; #include <stdio.h> my_app.c
静态调试举例 分块编译 greeting.c $gcc  -g  -Wall   -c  functions/greeting.c -g :将调试信息加入到编译的目标文件中 ; -Wall : 将编译过程中的所有级别的警告都打印出来  ; 无错误 my_app.c $gcc  -g  -Wall  -c  my_app.c  -Ifunctions 参数含义同上 错误信息:
调试举例 错误信息: 错误记录格式: 文件名:行好:错误描述 my_app.c: In function `main': my_app.c:6: `n' undeclared (first use in this function) my_app.c:6: (Each undeclared identifier is reported only once my_app.c:6: for each function it appears in.) my_app.c:9: parse error before &quot;greeting&quot; my_app.c:6: warning: unused variable `name'
静态调试举例 分析、定位错误(警告): my_app.c 的第 6 行: 描述含义: n 是一个没有声明的变量; 分析: 声明数字 name 时用到了变量 n ,但变量 n 在之前没有声明; 改正: 声明一个新变量 n ; 或者 将 n 改为宏 N 这里取第 2 种改正方法;
静态调试举例 my_app.c 的第 9 行: 描述含义: 在“ greeting” 之前出现解析错误; 分析: c 中每行程序以;结束,第 9 行 greeting 之前的程序行没有以;结束; 改正: 第 8 行末尾增加“;” 重新编译 错误信息: my_app.c: In function `main': my_app.c:11: warning: control reaches end of non-void function
静态调试举例 分析、定位错误(警告): 警告: my_app.c 的 11 行 描述含义: 控制以非空函数结束; 分析: main 函数返回类型为 int ,源程序没有以 return  整数 形式结束; 改正: 将 main 改为返回 void 类型; 或者: 在 main 程序后增加 return  返回语句; 采用第 2 种解决方式; 重新编译,无错误或警告信息,完成静态调试
静态调试举例 静态调试总结 主要为语法错误: 输入错误; 类型匹配错误; 分析信息: 主要来自 gcc 编译时产生的提示信息 错误警告定位: 不一定在提示信息描述的地方; 综合分析提示信息及提示行的上下文环境,定位并修正错误、警告。 有的警告可以不用修复;
动态调试举例 常见的动态调试方法: 增加调试语句 ; 记录程序的执行状况 ; 观察内存变化 ; 使用调试工具; GUN Debuger 的功能: 启动程序,设置程序执行的上下文环境; 在指定的条件下停止程序; 程序停止时,检查程序的状态; 在程序运行时,改变程序状态,使其按照改变后的状态继续执行。
动态调试举例 查看指定文件或者函数的源代码,并标出行号 list 执行其后的 shell 命令 shell 设置断点,程序执行到断点就会暂停起来 break 查看变量或者表达式的值 print 退出 gdb 调试环境 quit 启动被执行的程序 run 单步(行)执行,如果遇到函数不会进入函数内部 next 单步(行)执行,如果遇到函数会进入函数内部 step 指定需要进行调试的程序 file 含义 命令 gdb 常用的调试命令
动态调试举例 对静态调试中的例子继续进行动态调试 工具 :gdb 启动 gdb $gdb GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type &quot;show copying&quot; to see the conditions. There is absolutely no warranty for GDB.  Type &quot;show warranty&quot; for details. This GDB was configured as &quot;i386-redhat-linux-gnu&quot;. (gdb) 启动命令 启动提示 启动完毕
动态调试举例 调试指定程序( ./my_app ) 问题: 期望的输出和实际输出不一致 (gdb)  file  ./my_app Reading symbols from ./my_app...done (gdb)  run Starting program: /home/tom/shell_script/cpp/my_app/my_app Your Name,Please: tom Hello ! Program exited normally. (gdb) 加载调试程序 启动调试程序 程序输出 提示信息
动态调试举例 初次错误定位: 输出有错误 错误定位 重新开始一次调试 ; 启动 gdb; 加载调试程序( ./my_app ) ; 查看程序源代码 命令: list  文件名
动态调试举例 (gdb)  list  my_app.c:1,20 1 #include <stdio.h> 2 #include &quot;greeting.h&quot; 3 #define N 10 4 int main(void) 5 { 6 char name[N]; 7 printf(&quot;Your Name,Please:&quot;); 8 scanf(&quot;%s&quot;,name); 9 greeting(name); 10 return 0; 11 } (gdb)  break 7 BreakPoint 1 at 0x8048384:  file my_app.c, line 7. 在程序第 7 行设置断点 命令:  (gdb)  break 7 查看源代码 设置断点 提示信息
动态调试举例 错误详细定位 9  greeting(name); 9 Your Name,Please :tom 8 (gdb)  next 7 8  scanf(&quot;%s&quot;,name); 6 (gdb)  next 5 7 printf(&quot;Your Name,Please:&quot;); 4 Breakpoint 1 , main ()  at my_app.c : 7 3 Starting program: /home/tom/shell_script/cpp/my_app/my_app 2 (gdb)  run 1 启动调试程序 断点激活 步进下一步
动态调试举例 错误详细定位 (gdb)  quit 20 Kill the programe being debugged?(y or n)y 19 (gdb)  kill 18 6  } 17 Hello ! 16 (gdb)  step 15 5  printf (” Hello !\r\n” ) ; 14 greeting ( name=0xbfffdf20 “tom” ) at functions/greeting.c : 5 13 (gdb)  step 12 $1 = “tom\000 ò·000©® 11 (gdb)  print name 10 查看变量值 进入函数内部 步进执行 停止调试 退出 gdb
动态调试举例 分析 : 11 行说明 name 变量被正确赋值( tom ) 13 行说明 name 变量值被正确赋予 greeting 的参数变量 name 16 说明打印出现了错误,即错误出现在函数 greeting 中; 综合分析 错误出现在 greeting.c 的第 5 行; 原因: 没有输出字符串的格式不对; 改正错误
动态调试举例 动态调试总结 主要错误类型: 算法错误; 输入错误; 定位方法: 设置断点; 单步步进执行; 查看变量取值变化; 反复执行,逐步缩小错误范围;
课后习题 1 、从文本源代码到可执行文件, gcc 可以对哪些步骤进行控制? 2 、编一个简单的 helloworld 程序,利用 gcc 控制程序生成的四个步骤。 3 、简述 gcc 的用法和常用参数的含义。 4 、上机查找 gcc 利用的库文件和头文件都放在什么路径下? 5 、 make 工具如何使用? Makefile 的基本格式是什么? 6 、简述 gdb 的用法和常用命令的含义。
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
主要内容 Gtk +的主要功能 Gtk +简介 利用 Gtk+ 开发图形界面程序 基本程序示例 应用容器的程序示例
X 窗口 X 服务器 运行在用户的本地机器上,在屏幕上完成低层的绘图操作 X 客户端 是以 X 窗口系统作为 GUI 的任何程序,它等候 X 服务器传送的用户事件,然后通过给 X 服务器发送重绘消息来响应 X 协议 X 服务器和 X 客户端之间的通讯协议 Xlib 库 是 X 客户端间接用于产生 X 协议消息的库,它提供一个非常底层的 API 、允许客户端在 X 服务器上绘出非常基本的元素
X 工具包 X 工具是一个 GUI 库, X 客户端用它极大地简化了窗口、菜单、按钮等的创建 其他平台无关的窗口 API JAVA 语言使用 swing 和 AWT API 来支持 GUI 程序设计 Tcl/Tk 脚本语言
Gtk +的作用 Gtk+ 工具包在 XWindows 中的作用 是 Xlib 之上更高层的开发工具包,它们将底层的 Xlib 的 API 进行封装,提供更高级的接口,达到降低开发难度,提高开发效率的目的。  网络协议 X 客户端(应用程序) X 工具包、 Gtk+,Qt XLib X 客户端(应用程序) X 工具包、 Gtk+,Qt XLib X 服务器 设备驱动程序
Gtk +简介 来源: Gimp ( GUN Image Manipulation Program ) 以 Gtk+ 为基础的应用软件 Gimp Glade Gnome Abiword dia 等 Gtk +的主要组成 Glib :底层核心库 Pango :界面布局和国际化 Atk :其它功能
简而言之, GTK+ 一个库,它提供一组已制作好的称作“窗口部件”的组件,我们通过简单易用的函数调用把这些组件和应用程序逻辑组合在一起,从而极大地简化了 GUI 的创建 GTK+ 完全是用 c 语言写,因此大多数 GTK+ 软件也用 c 语言写
GtkWindow 对象层次 GObject GtkObject GtkWidget GtkContainer GtkBin -- GtkWindwo
GtkWidget  窗口小部件 所有窗口部件创建函数都返回一个 GtkWidget 类型
#include <gtk/gtk.h> int main(int argc,char *argv[]) { GtkWidget *window; gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_show(window); gtk_main(); return 0; }
开发图形界面程序 基本程序示例 on_btn_clicked(), 按钮事件处理程序 on_delete(), 窗口关闭事件处理程序 } 8 gtk_main_quit(); 7 g_print(&quot;Window Closed.\n&quot;); 6 void on_delete(GtkWidget *widget, GdkEvent *event, gpointer data){ 5 } 4 g_print(&quot;Hello World!\n&quot;); 3 void on_btn_clicked(GtkWidget *widget, gpointer data){ 2 #include <gtk/gtk.h> 1 helloworld.c 代码片断 1 部分辅助函数
} 26 return 0; 25 gtk_main();// 启动消息循环 24 gtk_widget_show_all(window);// 显示窗口 23 gtk_container_add (GTK_CONTAINER (window), button); 22   G_CALLBACK (on_btn_clicked), NULL);// 关联按钮事件 21 g_signal_connect (G_OBJECT (button), &quot;clicked&quot;, 20 button = gtk_button_new_with_label (&quot;Hello World&quot;); 19   G_CALLBACK (on_delete), NULL);// 关联窗口关闭事件 18 g_signal_connect (G_OBJECT (window), &quot;delete_event&quot;, 17 gtk_container_set_border_width (GTK_CONTAINER (window), 10); 16 gtk_window_set_title(GTK_WINDOW(window),&quot;Hello World!&quot;); 15 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);// 创建窗口 14 gtk_init(&argc,&argv);// 初始化运行环境 13 gtk_set_locale(); 12 GtkWidget *button; 11 GtkWidget *window; 10 int main(int argc, char * argv[ ]){ 9 helloworld.c 代码片断 2—— 主函数部分
基本程序示例 程序运行效果 组成: 一个按钮 一个窗口 动作: 点击按钮,在终端输出一个字符串 点击关闭窗口,在终端输出一个字符串后,退出
基本程序示例 程序的编译运行 假设条件: 源文件保存在当前工作目录中; 源文件命名为 helloworld.c 利用 gcc 编译: 命令:   $gcc helloworld.c –o helloworld `pkg-config  gtk+-2.0  --cflags  --libs` 说明 输出文件为 helloworld 以命令 pkg-config  gtk+-2.0  --cflags  --libs 的运行结果为 gcc 的额外参数; 运行 : ./helloworld 运行
常用事件及处理函数原型 void  user_function (GtkList *list ,   gpointer data); selection-changed void  user_function(GtkList *list, GtkWidget *widget , gpointer data); select-child GtkList void  user_function(GtkComboBox *widget, gpointer data); changed GtkComboBox enter clicked void  user_function( GtkButton *widget ,   gpointer data); activate GtkButton delete-event gboolean user_function(GtkWidget*widget, GdkEventExpose *event ,  gpointer data); expose-event void  user_function (GtkWidget *widget, gpointer data); show GtkWidget 处理函数原型 事件名 事件源 常用的 gtk+ 事件及处理函数原型
应用容器的 Gtk +程序 容器: 所谓容器,就是可以在其中放置其它界面元素的元素。其中放置的元素可以是可见的按钮、图标,也可以还是一个容器;  以继承的观点来理解, GtkWidget 有一个直接的派生类—— GtkContainer 作为所有容器类的基类; 按照容器中可以容纳元素的个数,容器又可以分为两类: 只能容纳一个元素的容器; 可以容纳多个元素的容器。
应用容器的 Gtk +程序 常见的容器: 容纳一个元素:( GtkBin 的子类  ) GtkWindow  GtkButton GtkFrame 容纳多个元素 :( GtkContainer  的子类) GtkBox  GtkTable GtkPanel 这类容器通常称为布局
事件、信号和回调函数 GUI 库有一个共同点:必须有某种机制响应用户动作以执行代码 命令行程序的做法:就是暂停执行,等待用户输入,然后采用 switch 语句等机制使程序根据输入不同而分支执行 GUI 程序:由事件和事件监听器系统来解决问题
GTK+ 有自己的事件和事件监听器系统,叫做信号( signal )和回调函数( callback ) GTK+ 信号:当某事件发生时 GtkObject 对象发出的数据 回调函数:与信号相连接,一旦信号发出就会被调用的函数。
控制权的传递是使用“信号”的办法来完成的  有所有构件都继承的信号,如 “ destroy” ,有构件专有的信号,如开关  (toggle)  按钮发出的 “ toggled”  信号
连接回调函数 要使一个按钮执行一个动作,我们需设置信号和信号处理函数之间的连接 g_signal_connect(gpointer *object,const gchar *name,GCallback func,gpointer user_data) 第一个参数是要发出信号的构件,第二个参数是你想要连接的信号的名称,第三个参数是信号被捕获时所要调用的函数,第四个参数是你想传递给这个函数的数据  连接回调函数没有任何限制,可以将多个信号连接到一个回调函数,也可以将多个回调函数连接到一个信号
回调函数的原型 void a_callback_function(GtkWidget *widget,gpointer user_data) 两个参数:第一个是指向发出信号的窗口部件的指针,第二个是将回调函数与信号连接时定义的任一个指针
GtkWindow GtkWidget * gtk_window_new(GtkWindowType type) void gtk_window_set_title(GtkWindow *window,const gchar *title) Void gtk_window_set_position(GtkWindow *window,GtkWindowPosition position) Void gtk_window_set_default_size(GtkWindow *window,gint width,gint height) Void gtk_window_resize(GtkWindow *window,gint width,gboolean resizable) Void gtk_windwo_set_resizable(GtkWindow *window,gboolean resizebale)
gtk_window_set_position 值 GTK_WIN_POS_NONE  位置由窗口管理器决定 GTK_WIN_POS_CENTER GTK_WIN_POS_MOUSE GTK_WIN_POS_CENTER_ALWAYS GTK_WIN_POS_CENTER_ON_PARENT( 对话框有用 )
GtkEntry—— 单行文字输入框 GtkWidget * gtk_entry_new(void) GtkWidget * gtk_entry_new_width_max_length(gint max) Void gtk_entry_set_max_length(GtkEntry *entry,gint max) G_CONST_RETURN gchar* gtk_entry_get_text(GtkEntry *entry) void gtk_entry_set_text(GtkEntry *entry,const gchar *text) void gtk_entry_append_text(GtkEntry *entry,const gchar *text) void gtk_entry_prepend_text(GtkEntry *entry,const gchar *text)
hbox vbox 组装部件 创建一个新的横向盒我们调用  gtk_hbox_new() ,对于纵向盒,用  gtk_vbox_new()  gtk_box_pack_start()  将对象从上到下组装到纵向盒中,或者从左到右组装到横向盒中  gtk_box_pack_end()  则相反,从下到上组装到纵向盒中,或者从右到左组装到横向盒中
GtkWidget* gtk_hbox_new(gboolean homogeneous,gint spacing) GtkWidget* gtk_vbox_new(gboolean homogeneous,gint spacing) Homogeneous 是布尔值,如果为 TRUE ,则强制每个窗口部件都占据相同大小的空间, spacing 设置窗口部件间距像素值
Void gtk_box_pack_start(GtkWidget *box,GtkWidget *child,gboolean expand,gboolean fill,guint padding) Void gtk_box_pack_start(GtkWidget *box,GtkWidget *child,gboolean expand,gboolean fill,guint padding) 参数: 第一个:将被填充的包装盒 第二个:填入包装盒的部件 第三个:如果为 TRUE ,则窗口部件填充与其他标志为 TRUE 的窗口部件共享的可用空间 第四个:如果为 TRUE ,则这个窗口部件填满分配给它的空间,而不是在边缘垫衬,只有 expand 为 TRUE 时才有效 第五个:窗口部件周围垫衬的大小像素值
应用容器的 Gtk +程序 程序界面 btn_quit  btn_start  btn_go  label  entry  text+scroll_win   window
应用容器的 Gtk +程序 程序源文件目录组织 guess.c  定义主函数的地方  functions funtion.h  其它函数的头文件 function.c 其它函数的实现文件 当前工作目录 ./
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
gtk-demo pkg-config
GTK+ 程序示例 登录程序 按钮
#include <gtk/gtk.h> #include <stdio.h> #include <string.h> const char * password=&quot;secret&quot;; void closeApp(GtkWidget *window,gpointer data){  gtk_main_quit(); } void button_clicked(GtkWidget *window,gpointer data){  const char *password_text=gtk_entry_get_text(GTK_ENTRY((GtkWidget *)data));  if (strcmp(password_text,password)==0)  printf(&quot;Access granted!\n&quot;);  else  printf(&quot;Access denied!\n&quot;); }
int main(int argc,char *argv[]){  GtkWidget *window;  GtkWidget *username_label,*password_label;  GtkWidget *username_entry,*password_entry;  GtkWidget *ok_button;  GtkWidget *hbox1,*hbox2;  GtkWidget *vbox;  gtk_init(&argc,&argv);  window=gtk_window_new(GTK_WINDOW_TOPLEVEL);  gtk_window_set_title(GTK_WINDOW(window),&quot;GtkEntryBox&quot;);  gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);  gtk_window_set_default_size(GTK_WINDOW(window),200,200);  g_signal_connect(GTK_OBJECT(window),&quot;destroy&quot;,GTK_SIGNAL_FUNC(closeApp),NULL);
username_label=gtk_label_new(&quot;Login:&quot;);  password_label=gtk_label_new(&quot;Password:&quot;);  username_entry=gtk_entry_new();  password_entry=gtk_entry_new();  gtk_entry_set_visibility(GTK_ENTRY(password_entry),FALSE);  ok_button=gtk_button_new_with_label(&quot;OK&quot;);  g_signal_connect(GTK_OBJECT(ok_button),&quot;clicked&quot;,GTK_SIGNAL_FUNC(button_clicked),password_entry);   hbox1=gtk_hbox_new(TRUE,5);  hbox2=gtk_hbox_new(TRUE,5);  vbox=gtk_vbox_new(FALSE,10);  gtk_box_pack_start(GTK_BOX(hbox1),username_label,TRUE,FALSE,5);  gtk_box_pack_start(GTK_BOX(hbox1),username_entry,TRUE,FALSE,5);  gtk_box_pack_start(GTK_BOX(hbox2),password_label,TRUE,FALSE,5);  gtk_box_pack_start(GTK_BOX(hbox2),password_entry,TRUE,FALSE,5);  gtk_box_pack_start(GTK_BOX(vbox),hbox1,FALSE,FALSE,5);  gtk_box_pack_start(GTK_BOX(vbox),hbox2,FALSE,FALSE,5);  gtk_box_pack_start(GTK_BOX(vbox),ok_button,FALSE,FALSE,5);  gtk_container_add(GTK_CONTAINER(window),vbox);  gtk_widget_show_all(window);  gtk_main();  return 0; }
GtkButton GtkButton GtkToggleButton GtkCheckButton GtkRadioButton
#include <gtk/gtk.h> #include <stdio.h> GtkWidget *togglebutton; GtkWidget *checkbutton; GtkWidget *radiobutton1,*radiobutton2; void closeApp(GtkWidget *window,gpointer data) { gtk_main_quit(); } void add_widget_with_label(GtkContainer *box,gchar *caption,GtkWidget *widget) { GtkWidget *label=gtk_label_new(caption); GtkWidget *hbox=gtk_hbox_new(TRUE,4); gtk_container_add(GTK_CONTAINER(hbox),label); gtk_container_add(GTK_CONTAINER(hbox),widget); gtk_container_add(box,hbox); }
void print_active(char *button_name,GtkToggleButton *button) { gboolean active=gtk_toggle_button_get_active(button); printf(&quot;%s is %s\n&quot;,button_name,active?&quot;active&quot;:&quot;not active&quot;); } void button_clicked(GtkWidget *button,gpointer data) { print_active(&quot;Checkbutton&quot;,GTK_TOGGLE_BUTTON(checkbutton); print_active(&quot;Togglebutton&quot;,GTK_TOGGLE_BUTTON(togglebutton); print_active(&quot;Radiobutton1&quot;,GTK_TOGGLE_BUTTON(radiobutton1); print_active(&quot;Radiobutton2&quot;,GTK_TOGGLE_BUTTON(radiobutton2); printf(&quot;\n&quot;); }
gint main(gint argc,gchar *argv[]) { GtkWidget *window; GtkWidget *button; GtkWidget *vbox; gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),200,200); g_signal_connect(GTK_OBJECT(window),&quot;destroy&quot;,GTK_SIGNAL_FUNC(closeApp),NULL); button=gtk_button_new_with_label(&quot;OK&quot;); togglebutton=gtk_toggle_button_new_with_label(&quot;Toggle&quot;); checkbutton=gtk_check_button_new(); radiobutton1=gtk_radio_button_new(NULL); radiobutton2=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(radiobutton1));
vbox=gtk_vbox_new(TRUE,4); add_widget_with_label(GTK_CONTAINER(vbox),&quot;ToggleButton:&quot;,togglebutton); add_widget_with_label(GTK_CONTAINER(vbox),&quot;CheckButton:&quot;,checkbutton); add_widget_with_label(GTK_CONTAINER(vbox),&quot;Radio 1:&quot;,radiobutton1); add_widget_with_label(GTK_CONTAINER(vbox),&quot;Radio 2:&quot;,radiobutton2); add_widget_with_label(GTK_CONTAINER(vbox),&quot;Button:&quot;,button); g_signal_connect(GTK_OBJECT(button),&quot;clicked&quot;,GTK_SIGNAL_FUNC(button_clicked),NULL); gtk_container_add(GTK_CONTAINER(window),vbox); gtk_widget_show_all(window); gtk_main(); return 0; }
程序的参数处理 Shell 脚本程序使用 $0,$1 接收参数 C 程序: int main(int argc,char *argv[]) argc 是程序参数的个数, argv 是代表参数自身的字符串数组 如果不声明 argc , argv ,就不能使用
Shell 接收用户输入的命令行,将命令行分解成单词,然后把单词放入 argv 数组 如  myapp left right ‘and center’ argc : 4 argv : {“myapp”,”left”,”right”,”and center”} 参数个数包括程序自身名称
命令行选项 ls –l –s –t –r df –m 命令行开关都应以一个短横线开头,包含单个字母或数字
C 程序处理命令行选项 演示
利用 getopt 函数处理命令行选项 getopt 是 linux 的函数,它支持需要关联值和不需要关联值的选项 Int getopt(int argc,char *const argv[],const char *optstring) *optstring 是选项指定字符串,告诉 getopt 哪些选项可用,以及每个选项是否有关联值 optstring 每个字符代表一个单字符选项,如果一个字符后面紧跟一个冒号,则表明选项有关联值
getopt  ( argc  , argv ,” if:lr” ) 该函数返回值是 argv 数组的下一个选项字符 如果选项有关联值,则外部变量 optarg 指向这个值 如果选项处理完毕, getopt 返回 -1 ,特殊参数 - - 使函数停止 如果遇到无法识别的选项,返回一个?号,并把它保存在外部变量 optopt 中 如果选项要求关联值,但未提供该值,则返回:
程序参数 演示
时间和日期 所有的 unix 系统都使用同一个时间和日期的起点:格林尼治时间( GMT ) 1970 年 1 月 1 日 0 点,这是 unix 纪元的起点, linux 也不例外 Linux 系统中所有的时间都以从那时起经过的秒数来衡量 MS-DOS 也是类似,只是它的纪元始于 1980 年
时间通过一个预定义的类型 time_t 处理,是长整数 #include <time.h> time_t time(time_t *tloc)
#include <time.h> #include <stdio.h> #include <unistd.h> int main() { int i; time_t thetime; for (i=1;i<=10;i++) { thetime=time((time_t *)0); printf(&quot;the time is %ld \n&quot;,thetime); sleep(2); } exit(0); }
gmtime 函数 struct tm *gmtime(const time_t timeval) tm 的结构 Int tm_sec Int tm_min Int tm_hour Int tm_mday Int tm_mon Int tm_year Int tm_wday  星期几 Int tm_yday Int tm_isdst  是否夏令时
#include <time.h> #include <stdio.h> int main() { struct tm *tm_ptr; time_t thetime; (void)time(&thetime); tm_ptr=gmtime(&thetime); printf(&quot;raw time is %ld \n&quot;,thetime); printf(&quot;gmtime gives:\n&quot;); printf(&quot;date: %02d/%02d/%02d\n&quot;,tm_ptr->tm_year,tm_ptr->tm_mon+1,tm_ptr->tm_mday); printf(&quot;time:  %02d:%02d:%02d\n&quot;,tm_ptr->tm_hour,tm_ptr->tm_min,tm_ptr->tm_sec); exit(0); }
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
临时文件 程序经常利用一些文件形式的临时存储手段 必须确保应用程序为临时文件选取的文件名是唯一的,否则 linux 是一个多任务的系统,另一个程序就可能选择同样的文件名,导致两个程序互相干扰
tmpnam tmpnam 函数可以生成唯一的文件名 #include <stdio.h> char *tmpnam(char *s) 该函数返回一个不与任何已存在文件同名的有效文件名,如果字符串 s 不为空,文件名会写入它
tmpfile 如果需要立刻使用临时文件,可以用 tmpfile 函数在给它命名的同时打开它 由于别的程序可能会创建出一个与 tmpnam 返回的文件名同名的文件,所以 tmpfile 很有用 该函数返回一个文件流指针,以读写方式打开临时文件 FILE *tmpfile(void)
演示
用户信息 用户都有一个唯一的标识符 UID Linux 运行的每一个程序实际上都是被某一个用户运行的,因此都有一个关联的 UID
用户 UID 信息 #include <sys/types.h> #include <unistd.h> uid_t getuid(void); char *getlogin(void); UID 类型—— uid_t ,定义在 sys/types.h 中 getuid 返回程序关联的 UID ,它通常是启动程序的用户的 UID getlogin 函数返回与当前用户关联的登录名
用户密码信息 #include <sys/types.h> #include <pwd.h> struct passwd *getpwuid(uid_t uid); struct passwd *getpwnam(const char *name); 以上两函数返回一个指针,指向与某个用户对应的 passwd 结构
Passwd 结构 Char *pw_name  用户登录名  Uid_t pw_uid  UID 编号 Gid_t pw_gid  gid 编号 Char *pw_dir  用户主目录 Char *pw_gecos  用户全名 Char *pw_shell  用户默认 shell
演示
主机信息 主机名 #include <unistd.h> int gethostname(char *name,size_t namelen); 该函数把主机名写入 name 字符串,该字符串至少有 namelen 个字符长,成功就返回 0 ,否则返回 -1
主机信息 通过 uname 获得更多主机信息 #include <sys/utsname.h> int uname(struct utsname *name); uname 函数把主机信息写入 name 参数指向的结构,结构包含成员: Char sysname[] 操作系统名 Char nodename[] 主机名 Char release[] 系统发行级别 Char version[] 系统版本号 Char machine[] 硬件类型
演示
日志 对于 linux 系统,文件 /var/log/messages 包含所有系统日志信息 /var/log/mail 包含邮件系统日志信息 /var/log/debug 包含调试信息
向系统发送日志信息 #include <syslog.h> #void syslog(int priority,const char *message,arguments …); Syslog 函数向系统的日志工具发送一条日志信息,每条信息有一个 priority 参数,该参数是一个严重级别与一个设施值的按位或。
设施值 LOG_USER( 默认 ) LOG_LOCAL0 LOG_LOCAL1 … LOG_LOCAL7
严重级别优先级递减排列 LOG_EMERG 紧急情况 LOG_ALERT 高优先级故障,如数据库崩溃 LOG_CRIT 严重错误,如硬件故障 LOG_ERR 错误 LOG_WARNING 警告 LOG_NOTICE 需要注意的特殊情况 LOG_INFO 一般信息 LOG_DEBUG 调试信息
演示
Linux 内核发展
Linux 操作系统的体系结构 最上面是用户(或应用程序)空间。这是用户应用程序执行的地方。用户空间之下是内核空间。
Linux  内核可以进一步划分成  3  层。 最上面是系统调用接口,它实现了一些基本的功能,例如  read  和  write 。 系统调用接口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码。这些代码是  Linux  所支持的所有处理器体系结构所通用的。 在这些代码之下是依赖于体系结构的代码,构成了通常称为  BSP ( Board Support Package )的部分。这些代码用作给定体系结构的处理器和特定于平台的代码。
linux 内核基本知识 内核组成( 600 万行代码) 系统调用接口 进程管理 内存管理 虚拟文件系统 网络堆栈 设备驱动程序 硬件架构
结构图
系统调用接口 SCI  层提供了某些机制执行从用户空间到内核的函数调用。这个接口依赖于体系结构,甚至在相同的处理器家族内也是如此。 SCI  实际上是一个非常有用的函数调用多路复用和多路分解服务。
进程管理 进程管理的重点是进程的执行。在内核中,这些进程称为 线程 ,代表了单独的处理器虚拟化(线程代码、数据、堆栈和  CPU  寄存器)。在用户空间,通常使用 进程  这个术语,不过  Linux  实现并没有区分这两个概念(进程和线程)。
内存管理 内核所管理的另外一个重要资源是内存。为了提高效率,如果由硬件管理虚拟内存,内存是按照所谓的 内存页  方式进行管理的(对于大部分体系结构来说都是  4KB )。 Linux  包括了管理可用内存的方式,以及物理和虚拟映射所使用的硬件机制。
虚拟文件系统 虚拟文件系统( VFS )是  Linux  内核中非常有用的一个方面,因为它为文件系统提供了一个通用的接口抽象。 VFS  在  SCI  和内核所支持的文件系统之间提供了一个交换层
网络堆栈 网络堆栈在设计上遵循模拟协议本身的分层体系结构。回想一下, Internet Protocol (IP)  是传输协议(通常称为传输控制协议或  TCP )下面的核心网络层协议。 TCP  上面是  socket  层,它是通过  SCI  进行调用的。
设备驱动程序 Linux  内核中有大量代码都在设备驱动程序中,它们能够运转特定的硬件设备。 Linux  源码树提供了一个驱动程序子目录,这个目录又进一步划分为各种支持设备,例如  Bluetooth 、 I2C 、 serial  等。
依赖体系结构的代码 尽管  Linux  很大程度上独立于所运行的体系结构,但是有些元素则必须考虑体系结构才能正常操作并实现更高效率。
Linux  系统应用与程序设计 主讲:邝颖杰 电邮: [email_address]
题型 选择题 简答题 综合应用
Linux 、类 unix 基本常识 什么是 linux Linux 的特性 GNU 、 GPL 概念 Linux 的版本 Linux 各个目录的意义
Linux 的一些基本指令 附录 B 知道各个指令是什么意思 重点是文件与目录操作指令、用户及用户组指令、网络检测指令 关闭系统、启动系统、重启系统
Shell ( * ) 什么是 shell 常用的 shell 有哪些 Shell 处于 linux 系统的哪个模块 如何指定用户使用某个 shell
VI 的几种工作模式:命令模式、插入模式、末行模式 如何保存、退出、设置行号
Linux 文件( * ) 文件属性,如何修改,如何计算 有多少种文件类型,如何辨别 P23 硬链接、软链接 P31
挂载的概念 文件系统类型 虚拟文件系统结构( * ) 磁盘在 linux 下的标识 如何挂载 U 盘
如何配置机器的 ip ,如何查看 网络相关配置文件有哪些,有何作用 ftp 服务配置、启动、停止 telnet 服务配置、启动、停止 Xinetd 服务配置、启动、停止 守护进程概念原理( * ) 网络服务独立模式与 xinetd 模式区别( * )
Shell 编程( * ) 变量:自定义的变量、环境变量 程序结构:条件判断( * )、循环结构( * )、函数 如何执行 文件属性的判断、字符串属性和整数关系的判断 写过的程序( * )
Xwindow 概念 原理( * ) 有哪些 xwindow
进程、父进程、子进程、程序概念 Cron 的使用( * ) Grep 命令的使用 Awk 命令的使用
Gcc 概念( * ):各个选项的意义 各个阶段的编译及生成的文件 Makefile ( * ) Gtk+ 概念 如何开发 gtk+ 的程序 如何布局
补充的知识: 获取程序参数 时间函数的使用 临时文件 用户信息 主机信息 日志信息
Linux 的系统体系结构 Linux 的内核组成
cron 实验答案:  0 23 * * * /root/startftp 0  3 * * * /root/stopftp 脚本 startftp : /usr/sbin/vsftpd start sleep 2 tmp=`ps -ef | grep vsftp |grep -v grep |awk '{print $2}'` if [ -n $tmp ] then    echo `ps -ef | grep vsftp |grep -v grep`  >> mylog else    echo &quot;ftp start error&quot; >> mylog fi exit 0 同理,可写出 stopftp

Linux 系统应用与程序设计

  • 1.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 2.
    Linux 的发音 A: ['linju:ks] B : ['linэks] C : ['linΛks] D : ['liniks] 正确发音 GO “ hello,this is linus torvalds and i pronounce linux as linux”
  • 3.
    Linux 入门历史、背景、版本、安装 Linux 系统管理 基本操作、各类服务的架设 Linux 程序设计 Vi 、 SHELL 、 C 、可视化程序 课程介绍
  • 4.
    什么是 UNIX UNIX是有 OPEN GROUP 管理的一个商标,它指的是一个遵循特定规范的计算机操作系统 这个规范称为单一 UNIX 规范( The Single UNIX Specification ) UNIX 的源代码属于 SCO 公司
  • 5.
    类 UNIX 系统多数为商用,如 SCO 的 Unixware 、 IBM 的 AIX 、 HP 的 HP-UX 和 Sun 的 Soloris 免费的有 FreeBSD 和 Linux
  • 6.
    认识 Linux 什么是 Free Software ? Shareware/Freeware 不提供 Source Code 无法让 使用者自由更改或散播
  • 7.
    认识 Linux 什么 是 自由软件 Opensource? Freedom( 自由 )/Open( 开 放 ) Source Code 必须公开 任何人都可以自由 传播 、 下载 、使用或 改写
  • 8.
    什么是 Linux 是一个类UNIX 内核的可以自由发布的实现版本,是一个操作系统的底层核心 可以获得内核源代码,编译并安装,然后获得并安装许多其他自由发布的软件,从而创建一个完整的 Linux ,通常称为 Linux 系统 Linux 发行版
  • 9.
    发行版简介 Linux 操作系统(kernel+ultiliteies ):专家才会用 Linux 发行版( Distribution ):整合更多配套软件,普通用户也能用
  • 10.
    LINUX 源起 1991 年 8 月 芬兰 的一 个学 生在 comp.os.minix 新闻组贴 上了以下 这 段 话 : 「 你好,所有使用 minix 的人 - 我正在 为 386 ( 486 ) AT 做一個 免费 的操作系統 ( 只是 为 了 爱 好 ) ,不 会 像 GNU 那 样 很大很 专业 。 」
  • 11.
    1990 年秋, Linus修读 Unix 课程,基于 minix 编写仿真程序 1991 年 10 月发布 linux0.02 版本 1993 年发布 linux0.99 版本 1994 年 3 月发布 linux1.0 版本 1994 年加入 GNU 组织
  • 12.
    GNU 计划 1983 年 Richard Stallman( 自由 软件业 的精神教父 ) 创办 GNU(GNU’s not Unix) 计划 开始于 1984 年,旨在 发展 一個 类 -Unix 且 为 自由 软件 的完整 操作 系統 http://www.gnu.org/
  • 13.
    自由 软件基金会 GNU计划 的 赞助单位 FSF(Free Software Fundation) 提倡 免费软件 FSF 自由使用 权 的三個 意义 : 可自由 复制 GNU 的 软件 可自由修改 源代码 可自由 散布 修改 过 的 源代码 ,但不得收取任何 版权费用
  • 14.
    GNU Gen eral Public License 大 众 公有 版权 / 通用公共 版权 官方 翻译 :自由文件 许可 Copy left (是 copyright 的反话,就是防止有人给自由软件的使用加上限制) http://www.linux.org.tw/CLDP/GNU/licences/fdl.zh.html http://www.gnu.org/copyleft/gpl.html
  • 15.
    在 GPL 条款下发布的主要GNU 项目软件 GCC G++ GDB GNU make Bash GNU Emacs
  • 16.
    GNU 与 LinuxGNU 仍自行 发展 Hurd Kernel 开发许多 以 GPL 发 行的 应 用程 序与 工具程 序 Linux ( Linus’s Unix ) 由 网络上热心 的朋友一起 发 展 Linux Kernel 采 用 GNU 发 展的 许多应 用程 序与 工具 应该称作 GNU/Linux
  • 17.
    Linux 品牌 RedHatLinux SuSE Linux Mandrake Linux Caldera Linux Turbolinux Debian GNU/Linux Gentoo Linux Linpus Linux
  • 18.
    内核版本号与发行版本号 内核版本号:由 Linus等人制定和维护,全球统一 发行版本号:由各个发行公司或者组织自行制定,不同公司的发行版本号之间无可比性 内核版本号格式: x.y.zz-www , x 为主版本号, y 为次版本号, zz 为次次版本号, www 发行号
  • 19.
    Linux Kernel 现状与认证Kerenl 版本 http://www.kernel.org 主版本号、次版本号、次次版本号 稳 定版本- 2. 6 . 1 2 Linux 认证 RedHat RHCE http://www.redhat.com/ LPI Level one/two/three http://www.lpi.org
  • 20.
    Linux 产业现状 国内Linux 市场普及度越来越高 银行、证券、电信、邮政、税务、航空等对稳定性、安全性要求颇高的领域应用广(服务器端) 手机软件也用到了 Linux 嵌入式开发平台 桌面市场不成熟
  • 21.
    Linux 人才现状 Linux在中国前景光明,但缺少这方面的人才已成为其发展的瓶颈 国内熟练的 Linux 开发人员只有 3000 人左右,而且有很大一部分都是自由软件的爱好者,并没有经过专业的课程培训 根据 EvansData 发表的有关 Linux 开发状况的调查结果,目前 Linux 应用软件开发人员中,有 52% 是从 Windows 应用软件开发领域转行过来的,另外还有 30% 曾经从事过 UNIX 的应用开发
  • 22.
    人才问题 其一,人才培养跟不上。企业能直接从学校或社会上招聘到的 Linux人才少,一般只能招到公司后再慢慢培训; 其二,高层次的 Linux 技术人才少。很多人对 Linux 都是一知半解,只懂点皮毛,对内核级别有研究的更是凤毛麟角; 其三, Linux 企业以外的 Linux 人才少。
  • 23.
    薪水如何? Linux 普通网络管理人员的月薪大约5000 元左右 负责编程的 Linux 软件工程师月薪大约在 8000 - 12000 元之间 近年来特别红火的 Linux 嵌入式软件开发人员的月薪大约在 1.2 万元以上 项目经理的工资可能更高 在美国的一些大城市,经验丰富的 Linux 管理人员的薪金待遇普遍比 Unix 和 Windows 同行高出 20% ~ 30%
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
    man 男人? 在线 查詢 man page # man ls # man 1 ls # info ls info 也可以
  • 33.
    系統 关机 关机shutdown –h now halt poweroff init 0 重新 启动 shutdown –r now reboot init 6
  • 34.
    Linux 与 XP双系统 参考资料: http://soft.yesky.com/os/lin/36/2300036_1.shtml 要点: 硬盘中有独立的分区留出来 先装 XP 后装 Linux ,否则 XP 会吃掉 linux 的引导 双系统是由 linux 的 GRUB 来引导启动
  • 35.
    关于课本 《 linux系统应用与开发教程》 机械工业出版社 刘海燕等编著 ftp dns dhcp telnet
  • 36.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 37.
    Linux 终端使用基础 Linux 终端也称为虚拟控制台 . 一台计算机的输入输出设备就是一个物理的控制台 . 如果在一台计算机上用软件的方法实现了多个互不干扰独立工作的控制台界面,就是实现了多个虚拟控制台。 Linux 终端的工作方式是字符命令行方式,用户通过键盘输入命令进行操作,可以通过 Linux 终端对系统进行控制。
  • 38.
    什么是 shell Shell是一个作为用户与 linux 系统间接口的程序,它允许用户向操作系统输入需要执行的命令 在 linux 中可有多种 shell Linux 是高度模块化的 可用多个 shell 内核 csh bash xwindow 其他程序
  • 39.
    shell 的基本形式 shell 的种类 : ash :是贝尔实验室开发的 shell , bsh 是对 ash 的符号链接。 bash :是 GNU 的 Bourne Again shell ,是 GNU 操作系统上默认的 shell 。 sh 以及 bash2 都是对它的符号链接。 tcsh :是 Berkeley UNIX C shell 。 csh 是对它的符号链接
  • 40.
    shell 命令的基本格式是: 命令名 [ 选项 ] < 参数 1> < 参数 2> …… 命令自动补齐与历史记录 shell 提示符 :# $
  • 41.
    我们用的 shell GNU工具中的 bash 作为 /bin/sh 被默认安装 大多数 linux 发行版中, shell 程序 /bin/sh 实际上是对程序 /bin/bash 的一个连接 /bin/sh -version
  • 42.
    Linux 文件 链接数所属组 所属用户 文件属性 文件大小 修改时间 文件名
  • 43.
    文件与目录的基本概念 文件是Linux 用来存储信息的基本结构,它是被命名的存储在某种介质上的一组信息的集合。 Linux 系统中有三种基本的文件类型 . 普通文件:又分为文本文件和二进制文件; 目录文件:目录文件存储了一组相关文件的位置、大小等与文件有关的信息; 设备文件: Linux 系统把每一个 I/O 设备都看成一个文件,与普通文件一样处理,这样可以使文件与设备的操作尽可能统一 ;
  • 44.
  • 45.
  • 46.
    Linux 文件种类正规文件 ( regular file ) 第一个属性为 [ - ] 纯文字文件 (ascii) 二进制文件 (binary)   目录 (directory) : 第一个属性为 [ d ] 链接文件 (link) : 第一个属性为 [ l ] 设备文件 (device) : 区块 (block) 设备文件 , 第一个属性为 [ b ] ; 字 符 (character) 设备文件 , 第一个属性为 [ c ] 。
  • 47.
    Linux 程序 Linux中的应用程序有两种类型 可执行文件(相当于 windows 中的 .exe 文件) 脚本文件(相当于 windows 中的 .bat .cmd 文件) Linux 并不要求应用程序具有特殊的文件名或扩展名
  • 48.
    Linux 文件属性可读 可写 可执行 无此属性 文件类型 拥有者属性 组属性 其他人对该文件属性
  • 49.
    目录 Linux 系统以目录的方式来组织和管理系统中的所有文件 Linux 系统通过目录将系统中所有的文件分级、分层组织在一起,形成了 Linux 文件系统的树型层次结构。以根目录“ /” 为起点,所有其他的目录都由根目录派生而来。 特殊目录 :“.” 代表该目录自己, “ ..” 代表该目录的父目录,对于根目录,“ .” 和“ ..” 都代表其自己。
  • 50.
    观察目录文件的信息 目录文件也包含数据,它与普通文件的差别是:内核对这些数据进行结构化处理,它是由成对的“ I节点号 / 文件名”构成的列表 当把文件添加到一个目录中时,该目录的尺寸会增大,以便容纳新文件名。当删除文件时,目录的尺寸并不减小,而是内核对该目录项做上特殊标记,以便下次添加一个文件时重新使用它。
  • 51.
    Linux 目录结构/bin :常用系統 程序目录 /boot : 开机设定目录 ,也是 摆放 核心 vmlinuz 的地方 /dev : 摆放系统设备装置文件的目录 /etc : 系统配置文件 ,尤其 passwd, shadow /etc/rc.d/init.d :系統 开机 的時候 载入服务 的 scripts 的 摆放地点 /home :系統使用者的目 录
  • 52.
    Linux 目录结构/lib : Linux 执行 或 编译程序函数库目录 /mnt : 软驱与光驱接入挂载 的地方 /proc :系 统 核心 与执 行程序的一些 信息 /root :系 统 管理 员 的目 录 /usr/bin, /bin : 一般执行文件摆放 的地方 /usr/sbin, /sbin : 系统管理员 常用 指令 集 /var : 摆放系统日志文件 的地方 /lost+fount : 摆放系统 不正常 产 生 错误时遗 失的片段
  • 53.
  • 54.
    工作目录:用户登录到 Linux 系统后,每时每刻都处在某个目录之中,此目录被称为“工作目录”或“当前目录” 用户主目录( Home Directory ):是系统管理员在增加用户时为该用户建立起来的目录,每个用户都有自己的主目录。 使用符号 ~ 表示。
  • 55.
    路径是指从树型目录结构中的某个目录到某个文件的一条道路。此路径的主要构成是目录名称,中间用“ /” 分开。绝对路径是指从“根”开始的路径,也称为完全路径; 相对路径是指从用户工作目录开始的路径。 通配符 通配符 * 通配符? 字符组模式:通配符“ [” 、“ ]” 、“ -” 用于构成字符组模式。 转义字符 \
  • 56.
    Linux 用正斜线( /)分隔文件名里的目录名 Windows 用反斜线( \ )分隔
  • 57.
    目录和文件的基本操作 文件列表ls [-a] [-l] [-i] 文件查看和连接命令 cat cat [ 选项 ] <file1> … 分屏显示命令 more more [ 选项 ] <file>… 按页显示命令 less less [ 选项 ] <filename>
  • 58.
    复制、删除和移动命令 复制命令cp cp [ 选项 ] <source> <dest> 或者 cp [ 选项 ] <source>... <directory> 删除命令 rm rm [ 选项 ] <name>... 移动或重命名命令 mv mv [ 选项 ] <source> <dest> 或者 mv [ 选项 ] <source>... <directory>
  • 59.
    创建和删除目录命令 创建目录命令mkdir mkdir [-p] <dirName>… 删除空目录命令 rmdir rmdir [-p] <dirName>
  • 60.
    切换工作目录和显示目录命令 切换工作目录命令cd cd <dirName> 显示当前路径命令 pwd pwd 查看目录命令 ls ls [ 选项 ] [<name>...]
  • 61.
    查找与定位命令 查找文件或者目录命令find find [path…] [expression] 文件定位命令 locate/slocate locate [ 选项 ] <search string>
  • 62.
    链接 ln ln[ 选项 ] <source> <dest> 硬链接 hard link 软链接 symbolic link 改变文件或目录时间的命令 touch touch [ 选项 ] <file1> [file2 ...]
  • 63.
    压缩解压缩命令 命令格式为: tar< 主选项 > [ 辅选项 ] < 文件或者目录 > 压缩和解压命令 gzip gzip [ 选项 ] < 文件名 > 解压命令 unzip unzip [ 选项 ] < 压缩文件名 >
  • 64.
    常用命令 显示文字命令 echo echo [ -n ] < 字符串 > 显示日历命令 cal cal [ 选项 ] [[ 月 ] 年 ] 日期时间命令 date 显示日期和时间的命令格式为: date [ 选项 ] [+FormatString] 设置日期和时间的命令格式为: date <SetString> 清除屏幕命令 clear
  • 65.
    软件包管理命令 rpm 安装软件 rpm -i ( 或者 --install) [ 安装选项 ] <file1.rpm> ... <fileN.rpm> 删除 rpm -e ( 或者 --erase) [ 删除选项 ] pkg1 ... pkgN 升级 rpm -U ( 或者 --upgrade) [ 升级选项 ] file1.rpm ... fileN.rpm 查询 rpm -q ( 或者 --query) [ 查询选项 ] pkg1 ... pkgN 校验已安装的软件包 rpm -V ( 或者 --verify) [ 校验选项 ] pkg1 ... pkgN
  • 66.
  • 67.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 68.
    更改 Linux 文件属性命令 u g o a +( 加入 ) -( 除去 ) =( 设定 ) r w x 文件或目录 chmod r=4,w=2,x=1 # chmod 770 test owner  = rwx  = 4+2+1 = 7 group  = rwx  = 4+2+1 = 7 others = ---  = 0+0+0 = 0
  • 69.
    练习 系统中有用户 user1和 user2 ,同属于 users 组。在 user1 用户目录下有一文件 file1 ,它拥有 644 的权限,如果 user2 用户想修改 user1 用户目录下的 file1 文件,应拥有  权限。 A  744  B  664  C   646  D  746
  • 70.
    Linux 上的 XWindow 系统 整个 X Window 由三个部分组成: X Server :是控制输出及输入设备并维护相关资源的程序,它接收输入设备的信息,并将其传给 X Client ,而将 X Client 传来的信息输出到屏幕上( 在屏幕上构造方块(窗口),然后画出里面的元素 )。 X Client :是应用程序的核心部分,它与硬件无关,每个应用程序就是一个 X Client 。 X Client 可以是终端仿真器( Xterm )或图形界面程序,它不直接对显示器绘制或者操作图形,而是与 X Server 通信,由 X Server 控制显示。 X protocol : X Client 与 X Server 之间的通信协议。
  • 71.
    X 服务程序响应 X客户程序的请求,直接与图形设备通信,负责打开和关闭窗口,控制字体和颜色等底层的具体操作。每一个显示设备只有一个惟一的 X 服务程序。
  • 72.
    X 客户程序是使用系统窗口功能的一些应用程序,无法直接影响窗口或显示,它们只能请求 X服务程序,并通过 X 服务程序提供的服务在指定的窗口中完成特定的操作 X 协议是一个抽象的应用服务协议,包括了终端的输入请求和对 X 服务程序发出的屏幕输出命令,不包括对底层硬件的访问和控制。 X 协议是 X 服务程序和 X 客户程序进行通信的途径
  • 73.
    X Window 的特点 良好的网络支持: X Window 采用了 C/S 网络结构, X Client 和 X Server 可以通过网络来通信,而且有良好的网络透明性。 个性化的窗口界面: X Window 并未对窗口界面作统一的规范,程序员可以根据需求自行设计,其中最有名的就是后面将要介绍的 GNOME 与 KDE 。 不内嵌于操作系统: X Window 只定义了一个标准,而不属于某个操作系统,因此可在不同的操作系统上运行相同的 X Window 软件
  • 74.
    在 Mac OS和 Windows ,构件图形界面的功能都做在了操作系统里面,你只能使用那些。这个方法很简单,但是却不灵活。 Unix 和类 Unix 的操作系统没有内建这个功能,要使用 GUI 你就不得不使用窗口系统( X Window )。
  • 75.
    GNOME : GNOME项目有两个目标:提供一个完整的、易学易用的桌面环境 -GNOME 桌面环境,为程序设计人员提供强大的应用程序开发环境- GNOME 开发平台,用于建立桌面上的应用。 KDE :其目的是在 X Window 上建立一个与 MacOS 或者微软的 Windows 类似的完整易用的桌面环境,从而使 UNIX 更接近广大普通用户。 KDE 不仅提供了一个方便易用的超级桌面环境,而且还提供了一套免费的计算开发平台。
  • 76.
    总结几个概念 DE (Destop Environment ):桌面环境 GNOME 、 KDE (必须在 X Winodw 上运行) 窗口管理器(必须在 X Winodw 上运行) GNOME 的 Enlightenment KDE 的 KVM TWM : Tab Window Manager for the X Window System
  • 77.
    注意 X Winodw里的 X Server 只负责显示窗口画面 窗口管理器负责选择在哪里放置窗口、移动、改变大小、最大化、最小化等
  • 78.
    窗口管理器 窗口 主题 工作区菜单 终端窗口
  • 79.
    GNOME 桌面环境 GNOME 是 GNU 网络对象模型环境( GNU Network Object Model Environment )的缩写,它是 GNU 项目的一部分 GNOME 操作界面由 GNOME 面板( Panel )和桌面组成
  • 80.
    GNOME 面板的组成 主菜单:主菜单是系统中所有应用程序的起点。程序启动器:是 Linux 应用程序的启动链接,如同 Windows 中的快捷方式。 工作区切换器: 可以将 GNOME 的桌面分为相互独立的工作区,每个工作区是桌面的一部分 . 窗口列表:窗口列表显示了当前工作区上运行着的应用程序的名称。 通知区域: Red Hat 网络更新通知工具是通知区域的一部分。它提供了一种简捷的系统更新方式,确保系统时刻使用 Red Hat 的最新勘误和错误修正来更新。 插件小程序( Applets ):插件小程序是完成特定任务的小程序。 GNOME 有很多十分有用并且非常有趣的插件小程序,例如,电子邮件检查器、时钟日历、 CPU 和内存情况查看器等。
  • 81.
    组合面板的内容元素 主菜单、程序启动器、工作区切换器、窗口列表、通知区域、插件小程序都可以看成是GNOME 面板上的内容元素,它们可以自由组合和排列 ; 组合主菜单 组合程序启动器 使用抽屉组合
  • 82.
    组合面板的属性元素 GNOME有边缘面板、角落面板、浮动面板、滑动面板和菜单面板 5 种不同属性的面板 设置边缘面板、角落面板、浮动面板、滑动面板和菜单面板的属性 .
  • 83.
    GNOME 桌面 初始桌面 : 初始桌面包括 “ < 用户名 > 的主目录”、“从这里开始”和“回收站”。 root 用户桌面上所保存的所有项目都保存在目录 /root/.gnome-desktop/ 下,其它用户的桌面上所保存的所有项目都位于该用户主目录下的 .gnome-desktop 目录中 . 该目录是个点文件,一般隐藏显示。
  • 84.
    GNOME 桌面 将程序启动器拖放到桌面上 把项目从文件管理器窗口拖放到桌面上 建立链接 : 两种方法 桌面菜单 桌面属性的设置 : 背景、屏幕保护程序 . 工作区切换器属性设置
  • 85.
    GNOME 的窗口管理器 调整窗口大小、移动窗口、最大化、最小化、关闭窗口等操作与 Windows 的对应操作几乎一样 与 Windows 下的窗口不同的操作有: 卷起:窗口卷起后只剩下窗口标题栏可见, GNOME 默认将鼠标在窗口标题栏上双击作为窗口的卷起操作,也可以右单击窗口标题栏,选择【卷起】命令。对于卷起以后的窗口,鼠标双击标题栏或者右单击窗口标题栏,选择【展开】命令可使窗口恢复原样。 移动到别的工作区:右单击窗口标题栏,选择“移动到工作区 < 工作区名 >” ,可将该窗口移动到指定的工作区,同时该窗口从原来的工作区消失。 复制到别的工作区:右单击窗口标题栏,选择“放在所有工作区上”命令,将该窗口在各个工作区生成一个备份。
  • 86.
    GNOME 的文件管理器 Nautilus 文件管理器主要由菜单栏、工具栏、位置栏、状态栏、侧栏和浏览窗格等组成 。
  • 87.
  • 88.
    文件管理器的基本操作 选择文件 打开文件 更改文件名 移动和复制文件 给文件建立链接 删除文件 :文件被删除后都暂时存放到回收站中,回收站的内容存放在用户主目录下的 .Trash 目录下中 定位 改变文件查看方式 排列和布局文件
  • 89.
  • 90.
  • 91.
    文件管理器的个性化设置 改变鼠标动作的关联给文件增加徽标 改变侧栏和浏览窗格的背景或者颜色
  • 92.
    KDE 桌面环境 KDE 从外表上看同 GNOME 几乎相同,也是由面板和桌面组成 KDE 是遵守 GNU 的自由软件。在 LGPL 下所有 KDE 库都允许开发 KDE 桌面的程序,所 有 KDE 应用程序得到 GPL 许可, KDE 使用 Qt C++ 跨平台工具包 , 有各自的授权。 Qt 的授权允许你免费使用 Qt 来开发 X Windows 下的软件,只要你的原始代码也自由地 被使用。
  • 93.
    KDE 桌面环境 如果你希望你的原始代码不允许修改,你必须获得Qt 的商业授权 Qt 是建造使用者接口的 C++ 基类库。它提供大多数 widgets 、菜单、按钮、 sliders 等 等。 Qt 是一个跨平台库,写的代码可在 Unix 编译,也可在 Windows 编译。
  • 94.
  • 95.
    KDE 面板 组合KDE 面板内容元素:可以将 KDE 面板上的内容分为小程序、应用程序按钮、特殊程序按钮和扩展 4 大类。用户可以对这 4 类元素自由组合。 设置 KDE 属性 : KDE 面板设置控制模块 改变 KDE 面板的布局和大小 隐藏 KDE 面板和添加隐藏按钮 淡化小程序面板把手
  • 96.
    KDE 主菜单 菜单编辑器 菜单的编辑 为程序定义快捷键 菜单的其它属性设置
  • 97.
    KDE 桌面 初始桌面图: 包括起点目录、 floppy 、从这里开始和回收站 。 Floppy 图标用来对软驱进行操作。 拖放操作 :拖放操作的来源分为菜单、面板和文件夹。 桌面快捷菜单 桌面属性的设置 :外观、桌面行为、背景
  • 98.
  • 99.
    文件导航系统 1 )目录树导航 2 )多视图导航 3 )标签导航 4) 书签导航
  • 100.
    Konqueror 的其它功能Konqueror 和终端的紧密结合 Konqueror 的网络功能
  • 101.
    桌面切换 在字符终端下切换桌面:命令: switchdesk KDE|GNOME 在 X Window 下切换桌面: 在桌面环境中完成切换选择 “ 主菜单 / 系统工具 / 更多系统工具 /Desktop Switching tool ” 在登录界面实现选择 Ctrl+alt+backspace ,重新进入登录界面 主题的切换与安装 http://www.gnome-look.org http://art.gnome.org
  • 102.
    vi 文本编辑器 vi 管理 员 至少一定要 会 一 种编辑器 vi 的使用: 一般模式: 移动 、 复制 、 删除 、 黏贴 编辑 模式:插入 与 取代文件 命令 模式: 查询 、自 动 取代、 保存 等
  • 103.
    vi help h,j,k,l 移动 yy 复制 dd 刪除 p 黏贴 o,i,a 插入 R,r 取代 u 回复 / 查询 :%s/x/y/g 自 动 取代 :w 保存 :q 退出 :wq! 保存 強制 退出
  • 104.
    账号 Linux系统的账号分为用户账号和组账号两类: 用户账号:通常一个操作者拥有一个用户账号,每个用户账号有唯一的识别号 UID ( User ID )和自己所属组的识别号 GID ( Group ID )。 Linux 系统中可以有两类用户账号: root 用户和普通用户。 组账号:是一组用户账号的集合。通过使用组账号,可以设置使一组用户对文件具有相同的权限。
  • 105.
    用户和组的配置信息保存在以下三个文件中: /etc/passwd 对所有用户都可读 /etc/shadow /etc/group
  • 106.
    /etc/passwd 文件 每一行存储一个用户的账号信息,每一行可以包含如下域,各域之间以冒号分隔:登录名:即用户账号 口令:通常是一个“ x” ,表示口令已被加密,加密后的口令存储在 /etc/shadow 文件中。如果是“ *” ,则表示该账号已被停用。 UID :每个用户账号都有一个不同的 ID ,它是一个整数。 GID :用户所属的组的 ID ,每个组也都具有不同的 ID 。 用户信息:这是账号附加的信息,如用户名、电话、住址等,可以使用命令 finger 和 chfn 查询和修改这些信息。 主目录:在默认状态下,每个用户都有一个主目录, root 用户的主目录是 /root ,管理员新建立的用户的主目录默认为 /home/< 用户名 > 。 登录 shell :设置用户在登录时使用的 shell ,系统默认使用 /bin/bash 。 例如: root : x : 0 : 0 : root : /root : /bin/bash
  • 107.
    伪 用 户 含 义 bin 拥有可执行的用户命令文件 sys 拥有系统文件 adm 拥有帐户文件 uucp UUCP 使用 lp lp 或 lpd 子系统使用 nobody NFS 使用
  • 108.
    /etc/shadow etc/shadow 中的记录行与/etc/passwd 中的一一对应,它由 pwconv 命令根据 /etc/passwd 中的数据自动产生 登录名 : 加密口令 : 最后一次修改时间 : 最小时间间隔 : 最大时间间隔 : 警告时间 : 不活动时间 : 失效时间 : 标志
  • 109.
    /etc/shadow 是根据 /etc/passwd文件产生的,一行存储一个用户的信息,各域之间以冒号分隔: 用户账号 加密的口令密文 最后一次修改时间 , 从 1970 年 1 月 1 日到上次口令修改日期的天数。 最小间隔时间,口令上次修改后,要过多少天才能再修改。若为 0 表示没有时间限制。 最大间隔时间 警告时间,如果口令有期限限制,要过期前多少天向用户示警。一般系统默认为 7 天。
  • 110.
    /etc/group 存储所有组账号的数据,一行表示一个组的信息,各域之间以冒号分隔,包括: 组名x 表示加密的组口令,口令的相关信息存储在 /etc/gshadow 文件中,其形式与 /etc/shadow 相似。 组 ID ( GID ),系统生成的组 ID 小于 500 ,管理员新建的第一个组 ID 为 500 ,以后依次递增。 该组包含的用户账号列表,以逗号分隔。 例如: bin : x : 1 : root , bin , daemon
  • 111.
    用户管理 / 命令 增加用户: adduser [ 选项 ] <newusername> -d <dirName> :指定用户主目录,默认情况下,将会在 /home 目录下新建一个与用户名相同的用户主目录。 -s <shellName> :指定用户登录时使用的 shell ,默认的 shell 为 /bin/bash 。 -g <gName> :指定用户归属的组名。 默认地,每当创建一个新用户的时候,一个与用户名相同的组就会被创建,而这个用户就是该组的成员。( UPG 方案) -G < 组列表 > :在 Linux 系统中,一个用户可以属于一个组,也可以属于多个组,其中用户在初始化时属于的组称为主组。如果要让用户属于其它的组,应该使用选项 -G< 组列表 > 。 -u <uid> :指定新用户的 UID 。
  • 112.
    设置和修改口令 : passwd [ 用户名 ] 只有超级用户可以使用“ passwd 用户名”修改其他用户的口令,普通用户只能用不带参数的 passwd 命令修改自己的口令
  • 113.
  • 114.
    删除用户的命令为 userdel ,该命令的格式为:userdel < 用户名 > 如果系统不要保存这些文件,可以使用带选项的命令: userdel -r < 用户名 >
  • 115.
    修改用户属性 usermod –g<主组名 > -G < 组名 > -d < 用户主目录 > -s < 用户 shell> 增加用户组 groupadd < 新组名 > 删除用户组 groupdel < 组名 > 修改组成员:直接编辑 /etc/group 文件,将用户名写到对应的组名的后面。
  • 116.
  • 117.
    账号管理和查看命令 whoami 命令的功能在于显示用户自身的用户名。 who [ 选项 ] :该命令主要用于查看当前在线的用户情况 w 命令 :用于显示登录到系统的用户情况 finger 命令可用于查找和显示用户信息,并且在查找后显示指定账号的相关信息 chfn 命令能够改变系统存储的用户信息 切换用户身份: su - [ 用户名 ]
  • 118.
    更改 Linux 文件拥有者命令 语 法: chown [ -R ] 帐号名称 文件或目录 chown [ -R ] 帐号名称 : 组名 文件 或 目录 示例 : [root@test root]# chown games test [root@test root]# ls -l test drw-r--r--    1 games     root        0 Jun 20 14:36 test [root@test root]# chown –R root:root tmp
  • 119.
    更改 Linux 文件 所 属 群 组 语法 : chgrp 群 组 名 文件 或 目录 示例 : [root@test root]# chgrp users test [root@test root]# ls -l drw-r--r--    1 root     users        1 Jun 20 14:36 test
  • 120.
    系统安全设置 / 系统管理 BIOS 安全设置 安全分区 系统文件的权限 限制用户资源 系统升级
  • 121.
    系统安全设置 / 用户安全管理 账号安全管理 suid 程序 口令安全管理 自动注销账号
  • 122.
    suid 程序就是在运行的时候可以拥有比自己用户高的权限的用户的权限。 假设你有一个程序是属于nobody 这个用户的,这个程序的功能是要修改一个文件,而这个文件的属性是只有 root 才能修改。所以如果这个程序在以写方式打开该文件的时候肯定出错,提示没有权限。 因此使用 chmod u+s 命令给程序授权,这样程序在运行后就会得到 root 的权限,从而就可以修改那个文件了。 最常用的就是 ping 这个命令,就是 suid 程序。 任何用户都可以使用这个命令,但是 ping 里面实际上是使用了 raw_socket ,而 raw_socket 只有 root 用户才可以创建。 所以 ping 命令大都放在 /bin 下,而不是 /usr/bin 下 而且使用 ls -l 察看 ping 的权限,是 -r-sr-xr-x
  • 123.
    系统安全设置 / 网络服务安全管理关闭不必要的服务 禁止响应 ping 命令 屏蔽系统信息
  • 124.
    上机实验 实验内容:书本 219页实验 1 上机地点:院楼 801 , 803 用户名: root 密码: xxxyjsjx
  • 125.
    实验参考 一、修改配置文件的方法 (一 ) 、修改系统级的 PATH 环境变量 1, 编辑 /etc/profile, 文件,添加下面一行 export PATH=$PATH:/path1:/path2:/pahtN 2, 运行该文件 source /etc/profile ( 二 ) 、修改用户级别的 PATH 环境变量 先进入用户目录: #cd /home/aaa #vi .bash_profile 添加同样一行 存盘退出 # souce .bash_profile 以上一个是全局的 PROFILE 一个是单独用户的 profile   二、命令行状态下直接修改环境变量 修改环境变量,在 bash 下用 export, 在 csh 下用 setenv 。比如:      export   PATH=$PATH:/usr/local/bin 
  • 126.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 127.
    用户管理 / 命令 增加用户: adduser [ 选项 ] <newusername> -d <dirName> :指定用户主目录,默认情况下,将会在 /home 目录下新建一个与用户名相同的用户主目录。 -s <shellName> :指定用户登录时使用的 shell ,默认的 shell 为 /bin/bash 。 -g <gName> :指定用户归属的组名。 默认地,每当创建一个新用户的时候,一个与用户名相同的组就会被创建,而这个用户就是该组的成员。( UPG 方案) -G < 组列表 > :在 Linux 系统中,一个用户可以属于一个组,也可以属于多个组,其中用户在初始化时属于的组称为主组。如果要让用户属于其它的组,应该使用选项 -G< 组列表 > 。 -u <uid> :指定新用户的 UID 。
  • 128.
    设置和修改口令 : passwd [ 用户名 ] 只有超级用户可以使用“ passwd 用户名”修改其他用户的口令,普通用户只能用不带参数的 passwd 命令修改自己的口令
  • 129.
  • 130.
    删除用户的命令为 userdel ,该命令的格式为:userdel < 用户名 > 如果系统不要保存这些文件,可以使用带选项的命令: userdel -r < 用户名 >
  • 131.
    修改用户属性 usermod –g<主组名 > -G < 组名 > -d < 用户主目录 > -s < 用户 shell> 增加用户组 groupadd < 新组名 > 删除用户组 groupdel < 组名 > 修改组成员:直接编辑 /etc/group 文件,将用户名写到对应的组名的后面。
  • 132.
  • 133.
    更改 Linux 文件拥有者命令 语 法: chown [ -R ] 帐号名称 文件或目录 chown [ -R ] 帐号名称 : 组名 文件 或 目录 示例 : [root@test root]# chown games test [root@test root]# ls -l test drw-r--r--    1 games     root        0 Jun 20 14:36 test [root@test root]# chown –R root:root tmp
  • 134.
    更改 Linux 文件 所 属 群 组 语法 : chgrp 群 组 名 文件 或 目录 示例 : [root@test root]# chgrp users test [root@test root]# ls -l drw-r--r--    1 root     users        1 Jun 20 14:36 test
  • 135.
    账号管理和查看命令 whoami 命令的功能在于显示用户自身的用户名。 who [ 选项 ] :该命令主要用于查看当前在线的用户情况 w 命令 :用于显示登录到系统的用户情况 finger 命令可用于查找和显示用户信息,并且在查找后显示指定账号的相关信息 chfn 命令能够改变系统存储的用户信息 切换用户身份: su [ 用户名 ]
  • 136.
    用户的安全管理 限制用户使用资源 编辑/etc/security/limits.conf 自动注销账号 编辑 /etc/profile ,设置 tmout 变量的数值 Suid 程序
  • 137.
    suid 程序就是在运行的时候可以拥有比自己用户高的权限的用户的权限。 假设你有一个程序是属于nobody 这个用户的,这个程序的功能是要修改一个文件,而这个文件的属性是只有 root 才能修改。所以如果这个程序在以写方式打开该文件的时候肯定出错,提示没有权限。 因此使用 chmod u+s 命令给程序授权,这样程序在运行后就会得到 root 的权限,从而就可以修改那个文件了。 最常用的就是 ping 这个命令,就是 suid 程序。 任何用户都可以使用这个命令,但是 ping 里面实际上是使用了 raw_socket ,而 raw_socket 只有 root 用户才可以创建。 所以 ping 命令大都放在 /bin 下,而不是 /usr/bin 下 而且使用 ls -l 察看 ping 的权限,是 -r-sr-xr-x
  • 138.
    如何去掉程序的 suid 位find / -perm -4000 查找 chmod –s filename 去掉文件的 suid 位
  • 139.
    存储设备 计算机系统中,所有的存储设备都是以目录树的形式对文件进行管理的 . 在 Linux 系统中,所有的文件都是在以“ /” 目录为根的一棵“大”目录树中进行管理。 如果要使用 USB 存储设备、光盘或软盘等存储设备,必须将这些设备中的“小”目录树像嫁接一样挂载( mount )到 Linux 系统的“大”目录树中。
  • 140.
    挂载的文件系统类型 ext 、FAT 、 ext2 ( extended file system )、 ext3 、 MINIX 、 MSDOS 、 SYSV Linux 系统的第一个文件系统是 Minix (文件名不能超过 14 个字符,文件大小不能超过 64MB ) ext : 1992 年设计,是第一个专为 linux 设计的文件系统,文件大小可到 2GB ,文件名支持 255 字符,性能不佳 ext2 : 1993 年设计,提高性能 ext3 :采用日志式文件系统技术( Journalling Filesystem ),目前各个 linux 发行版使用
  • 141.
    Linux 引进 ext文件系统时有了一个重大的改进:真正的文件系统从操作系统和系统服务中分离出来,在它们之间使用了一个接口层—虚拟文件系统 VFS(Virtual File System)
  • 142.
    VFS Linux 系统可以支持多种文件系统,为此,必须使用一种统一的接口,这就是虚拟文件系统(VFS) 。通过 VFS 将不同文件系统的实现细节隐藏起来,因而从外部看上去,所有的文件系统都是一样的。
  • 143.
    VFS 并不是一个实际的文件系统 只存在于内存,系统启动时建立,系统关闭时消亡VFS 功能包括: 记录可用文件系统的类型 将设备同对应的文件系统联系起来 处理面向文件的通用操作 涉及到针对文件系统的操作时,把他们映射到相关的物理文件系统
  • 144.
    确定挂载信息 挂载对象的文件系统类型;vfat ext2 ext3 iso9660 挂载对象的设备名称; 在 Linux 系统中,设备名称通常都在 /dev 目录下,设备名称的命名是有规则的 ; /dev/hda1 /dev/sda2 /dev/fd0 /dev/cdrom 设备挂载到哪一目录,即挂载点。 Linux 系统中有一个 /mnt 目录,专门用作挂载点( mount Point )目录 在挂载设备时首先查看挂载点目录是否存在,如果不存在必须首先创建该目录,否则 mount 命令无法正常执行。
  • 145.
    挂载命令 mount mount [ 选项 ] < 挂载设备名称 > < 挂载点 > 选项: -t 挂载的文件系统 例如: mount –t ext2 /dev/fd0 /mnt/floppy -o [ 参数 = 值 ] ,对于挂载的不同类型的设备可以使用一组不同的参数。 mount -o iocharset=cp936 /dev/sda1 /mnt/usb
  • 146.
    挂载设备的过程 查看设备:使用命令“ fdisk –l” 可以查看系统的存储设备 挂载设备 :首先使用 mkdir 命令建立挂载点目录,然后再使用 mount 命令挂载相关设备 访问设备 卸载设备 :用户在使用完挂载设备后,不能直接将挂载设备从系统拔出,否则会出现问题,严重的会导致系统崩溃。用户必须先执行卸载命令然后再该设备拔出 umount [ 挂载点或设备名 ]
  • 147.
    自动挂载 使用配置文件/etc/fstab 来自动挂载存储设备。 文件 /etc/fstab 存放的是系统中的文件系统信息。每个文件系统在文件中都对应一个独立的行 。 fsck 、 mount 、 umoun t 的等命令都利用这个文件 。 fstab 每一行为一个分区记录,包含六个域: <fs_spec> <fs_file> <fs_type> <fs_options> <fs_dump> <fs_pass> 例如: /dev/hda1 /mnt/c vfat iocharset=cp936 0 0
  • 148.
    mount 命令 利用fstab 文件, mount 还有另外两种使用格式 : mount –a 该命令将文件 /etc/fstab 中提到的所有文件系统,凡没使用 noauto 选项的,一律按照指定的方式自动挂载。该命令一般在系统的启动脚本中执行。 mount < 挂载点 > 或者 mount < 挂载设备名称 > 当挂载 fstab 中提到的文件系统时,可以只指定挂载设备或者只指定挂载点即可完成挂载。
  • 149.
    图形化挂载工具 执行【主菜单/ 系统工具 / 磁盘管理】
  • 150.
    磁盘格式化 mkfs[ 选项 ][-t < 文件系统类型 >] [ 设备名称 ] [ 区块数 ] 说明:把指定的设备格式为指定的文件系统。 例如格式化硬盘时: mkfs –t ext3 /dev/hda4 格式化软盘时,需要指定设备名和区块数,每个区块大约 1000 个字节,一张 1.44MB 的软盘对应 1440 个区块。格式化指令为: mkfs –t ext3 /dev/fd0 1440 执行菜单【主菜单 / 系统工具 / 软盘格式化器】,打开“ floppy formatter” 窗口 。图形化的格式化界面。
  • 151.
    声卡 用户可以从声卡的生产厂商获取相应的驱动程序,并按相应的要求进行安装。如果用户无法获取正确的驱动程序,也可以使用两种通用的驱动程序 : OSS (开放声音系统),它是一个商业声卡驱动程序,需要花钱购买,否则每次启动后,只可以免费使用 240 分钟; ALSA (高级 Linux 声音架构),是自由软件,可以免费使用。
  • 152.
    安装 OSS 声卡驱动程序 可以从 http:// www.opensound.com / 下载最新的 OSS 驱动程序 ,假设下载了 ossLinux393q-2217-UP.tar.gz 解压缩源文件: 运行安装文件:以 root 用户身份运行 oss-install 文件 声卡驱动命令:安装完毕后,在默认的安装目录 /usr/local/bin 里有一个 soundon 命令,它用来打开 oss 驱动,命令 soundoff 用于关闭 oss 驱动。
  • 153.
    安装 ALSA 声卡驱动程序ALSA 源程序文件需要如下 4 个软件包,用户可以到 http://www.heihei.com/ 下载: alsa-driver-0.5.9.tar.gz :驱动程序包,包括所支持的声卡的驱动程序。 alsa-conf-0.4.3b.tar.gz :配置工具包,能够自动配置软件包中的配置文件。 alsa-lib-0.5.9.tar.gz :专用库函数包。 alsa-utils-0.5.9.tar.gz :工具软件包,提供支持混音调制的工具软件。
  • 154.
    安装声卡驱动程序库:对文件 alsa-driver-0.5.9.tar.gz ,依次执行: 1 )解压缩 2 ) ./configure # 自动配置命令 3 ) make install # 安装声卡驱动库 4 ) ./snddevices # 这是一个脚本程序,在 /dev 目录下自动创建相关的声卡设备。 配置声卡驱动程序 安装混音程序
  • 155.
    鼠标 :在终端输入命令 /usr/sbin/mouseconfig,可以打开鼠标配置界面 在 X Window 下,选择【主菜单 / 系统设置 / 鼠标】打开图形界面的鼠标配置窗口
  • 156.
    显卡 首先找到显卡支持 Linux的驱动程序,绝大多数的 3D 显卡都已有了支持 Linux 的驱动程序,用户可以从各显卡厂商的网站或 Linux 的相关站点上去寻找。 如果用户能够进入 X Window ,但是无法使用显卡的特殊功能,那么可以通过图形界面的配置工具配置显卡。 选择【主菜单 / 系统配置 / 显示】,弹出显示设置窗口 。
  • 157.
    打印机 获取打印机驱动程序 阅读安装文档 安装驱动程序 配置打印机 ,向系统添加打印机 测试打印机
  • 158.
    上机实验 开机、登录 重启ls 查看目录,进入 tmp 目录,在 tmp 下创建 test 目录,进入 test 目录,用 touch 创建一个文件,以自己学号命名,用 ls 查看该文件属性 压缩以上文件 解压以上文件 删除以上文件,删除以上目录
  • 159.
  • 160.
  • 161.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 162.
  • 163.
    网络接口配置 配置网络接口可以使用三种不同的工具来完成:使用网络接口配置程序 netconfig 使用图形配置工具 使用终端命令 ifconfig
  • 164.
    使用网络接口配置程序 netconfig 在终端中输入命令 netconfig
  • 165.
    使用图形配置工具 【主菜单/ 系统工具 / 网络设备控制】
  • 166.
  • 167.
    使用终端命令 ifconfig ifconfig < 设备名 > <IP 地址 > netmask < 掩码 > 例如: ifconfig eth0 192.168.15.11 netmask 255.255.255.0 fconfig eth1 21.156.299.13 netmask 255.255.255.0 ifconfig eth0:0 192.168.17.21 netmask 255.255.255.0
  • 168.
    网络接口的启动与禁用 在网络配置界面中,通过“激活”或者“解除”按钮可以启动或者禁用网络接口,网络控制程序 network /etc/rc.d/init.d/network start|stop|restart 命令 ifconfig : ifconfig < 设备名 > [up|down] 命令 ifup/ifdown ifup eth0 ifdown eth0
  • 169.
    网络接口的启动与禁用 执行【主菜单 /系统工具 / 网络设备控制】,打开 “网络设备控制”窗口
  • 170.
    网络接口的查看 使用终端命令ifconfig 方便地查看系统目前所有活跃的网络接口的详细信息 例如: ifconfig ifconfig eth0
  • 171.
    常用网络命令 网络测试命令 : ping [ 选项 ] < 目的主机名或 IP 地址 > ping 大数据包 -c num 发送 num 个数据包后停止 -s bytes 默认值是 64 字节 显示数据包经过路由的命令 traceroute traceroute < 目的主机 IP 或域名 >
  • 172.
    管理路由表命令 route 显示路由表内容: 不加任何参数的 route 命令显示本机路由表的内容, 添加 / 删除路由记录 route add|del –net < 网络号 > netmask < 网络掩码 > dev < 设备名 > route add –net 200.1.1.0 netmask 255.255.255.0 dev eth0 添加或者删除默认网关: route add|del default gw < 网关名或网关 IP> 例如: route add default gw 200.1.1.254 route del default gw 200.1.1.254
  • 173.
    远程登录命令 telnet < 主机名 /IP> rlogin <B 主机名或 IP 地址 >
  • 174.
    网络相关配置文件 设定主机的不同端口的网络服务 /etc/services定义使用的网络互联协议及协议号 /etc/protocols 域名服务器设置文件 /etc/resolv.conf 域名或主机名与 IP 地址的映射文件 /etc/hosts 域名解析的控制文件 /etc/host.conf 此目录下的文件是系统启动时用来初始化网络的一些信息,例如:第一块以太网卡对应的文件为 ifcfg-eth0 /etc/sysconfig/network-scripts/* 最基本的网络信息,系统启动时读取该文件 /etc/sysconfig/network 功能 配置文件名
  • 175.
    /etc/sysconfig/network 对本机的网络进行配置,常见的几个配置项如下: NETWORKING:值为 yes 或 no ,表示主机是否支持网络功能。 HOSTNAME :主机名(即域名)。 GATEWAY: 默认网关。 FORWARD_IPV4: 设置本机是否允许转发 IPV4 的数据包。 DOMAINNAME: 此台主机所属的网络域。 GATEWAYDEV: 连接网关的设备,例如 eth0 ,如果是拨号用户则设为 ppp0 。
  • 176.
    /etc/sysconfig/network-scripts/ DEVICE=eth0 // 设备名称 ONBOOT=yes // 起动时是否起动该设备,省略该行表示 yes BOOTPROTO=none // 启动协议 ,none 表示使用用户设置的 ip 地址 ,dhcp 表示从 dhcp 获得 ip 地址。省略该行表示使用设置的 IP 地址。 IPADDR=192.168.14.11 //IP 地址 NETMASK=255.255.255.0 // 子网掩码 BROADCAST=192.168.14.255// 广播地址 , NETWORK=192.168.14.0 // 网络地址
  • 177.
    域名解析配置文件 /etc/host.conf order hosts,bind multi on nospoof on
  • 178.
    主机名列表文件 /etc/hosts IP 地址 主机名 别名 例如: 192.168.14.15 qq.yys.com qq
  • 179.
    域名服务器设置文件 /etc/resolv.conf nameserver <DNS 服务器 IP> domain < 域名 > search < 域名列表 >
  • 180.
    协议定义文件 /etc/protocols 协议名称 协议号 别名 例如: tcp 6 TCP udp 17 UDP
  • 181.
    网络服务列表文件 /etc/services列出了系统支持的服务名称、服务使用的端口号和协议类型、服务的别名、功能注释等。 例如 http 80/tcp www www-http #WorldWideWeb HTTP
  • 182.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 183.
    网络服务管理工具 /etc/services文件列出了 Linux 系统支持的所有服务的名称 介绍三种不同的管理工具 网络进程服务程序 xinetd
  • 184.
    图形界面的管理工具 在X Window 下执行【主菜单 / 系统配置 / 服务器设置 / 服务】
  • 185.
  • 186.
    命令行界面的管理工具 命令chkconfig 用于检查和设置系统的各种服务 添加指定的新服务: chkconfig --add 服务名 删除指定服务: chkconfig --del 服务名 显示所有或指定服务,以及他们在每个运行级别是否启动等: chkconfig --list 或 chkconfig --list [ 服务名 ] 检查指定服务的状态 : chkconfig 服务名 改变服务的运行级别及启动信息: chkconfig [--level 运行级 ] 服务名 [ 状态 ]
  • 187.
    终端命令 service 用于设置网络服务的当前状态:service 服务名 [start|stop|restart] 管理员可以通过查看当前的进程树命令 pstree 来获知系统正在运行哪些服务 : pstree
  • 188.
    超级服务器 xinetd 支持对 TCP 、 UDP 、 RPC 服务的管理 可以实施基于时间段的访问控制 功能完备的 log 功能,可以记录连接成功、连接失败的行为 能够有效地防止拒绝服务( DoS )的攻击 能够限制同时运行的同一类型的服务器的数目 能够限制 log 文件大小 能够将某个服务绑定在特定的系统接口上,从而实现只能允许私有网络访问某项服务。 能够实现作为其它系统的代理。
  • 189.
    守护进程原理 在 Clie nt/Server 模式下。服务器监听( Listen )在一个特定的端口上等待客户连接。连接成功后服务器和客户端通过端口进行数据通信。守护进程的工作就是打开一个端口,并且等待( Listen )进入连接。 如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听其他的服务请求。
  • 190.
    独立的守护进程 独立运行的守护进程由 init脚本负责管理,所有独立运行的守护进程的脚本在 /etc/rc.d/init.d/ 目录下。 系统服务都是独立运行的守护进程包括: syslogd 和 cron 等。 运行独立的守护进程工作方式称作: stand - alone 。它是 Unix 传统的 C/S 模式的访问模式。服务器监听( Listen )在一个特点的端口上等待客户端的联机。如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听。以保持多个子服务器池等待下一个客户端请求。
  • 191.
  • 192.
    Web 服务器 Apache 和邮件服务器 Sendmail 、域名服务器 Bind 应用独立守护进程模式启动。 因为这些负载很大服务器上,预先创子服务器,可以通过客户的服务速度。
  • 193.
    Xinetd 模式 从守护进程的概念可以看出,对于系统所要通过的每一种服务,都必须运行一个监听某个端口连接所发生的守护进程,这通常意味着资源浪费。为了解决这个问题, Linux 引进了“网络守护进程服务程序”的概念。 Redhat Linux 9.0 使用的网络守护进程是 xinted ( eXtended InterNET daemon )。和 stand - alone 模式相比 xinted 模式也称 Internet Super - Server (超级服务器)。 xinetd 能够同时监听多个指定的端口,在接受用户请求时,他能够根据用户请求的端口不同,启动不同的网络服务进程来处理这些用户请求。 可以把 xinetd 看做一个管理启动服务的管理服务器,它决定把一个客户请求交给那个程序处理,然后启动相应的守护进程。
  • 194.
  • 195.
  • 196.
    超级服务器 xinetd 需要配置文件:/etc/xinetd.conf :控制 xinetd 程序运行的配置文件。其中,提供了所有服务的缺省配置。 /etc/xinetd.d/* :该目录包括所有由 xinetd 程序启动的服务的配置文件,每个服务都有自己单独的配置文件,配置文件名与服务名一致。
  • 197.
    系统默认的 /etc/xinetd.conf 文件内容如下:# Simple configuration file for xinetd # # Some defaults, and include /etc/xinetd.d/ defaults { Instances = 60 log_type = SYSLOG authpriv log_on_success = HOST PID log_on_failure = HOST cps = 25 30 }
  • 198.
    /etc/xinetd.d 目录 service telnet { disable =no # 表示允许 xinetd 启动本项服务 flags =REUSE # 表示当中断或重启 xinetd 时, TCP/IP Socket 可重用 socket_type =stream # 表示使用 TCP 的 Socket 类型 wait =no # 表示该服务提供多线程功能 user =root # 设置进程的 UID ,由 root 用户操作 server =/usr/sbin/in.telnetd # 设置服务程序文件 log_on_failure+=USERID # 表示当连接失败时,系统除记录 /etc/xinetd.conf 文件中设置的内容外,还需记录用户 ID 。 }
  • 199.
    演示一 配置 telnet服务 编辑 /etc/xinetd.d/telnet service telnet { …… disable=yes ( 这里要改为 no) … .. } 保存退出 重新启动服务 service xinetd restart
  • 200.
    vsFTPd 服务器 FTP 是一种文件传输协议,它实现了服务器与客户机之间的文件传输和资源的共享。 vsFTPd ( very secure FTP daemon )是一个功能强大的 FTP 服务器,能运行在大部分 UNIX 类作系统上,支持很多其他的 FTP 服务器不支持的特征: 支持虚拟 IP 支持虚拟用户 可以独立操作或者由 xinetd 管理 可以对每个用户进行配置 带宽限制 支持 IPv6 支持通过 SSL 的加密 高速
  • 201.
    安装 下载源代码文件,并将文件解压缩编译源代码: make 为 vsftpd 的运行准备条件 mkdir /var/ftp/ useradd -d /var/ftp ftp chown root.root /var/ftp chmod og-w /var/ftp 将可执行文件安装到 Linux 的系统目录中
  • 202.
    启动 vsFTPd 也可以工作在两种模式:一种是自己启动运行的独立工作模式,另一种是借助 xinetd 管理的工作模式。 独立工作模式 :在 vsFTPd 的配置文件 /etc/vsftpd/vsftpd.conf 中,设置选项“ listen=YES” ,使用服务管理工具操作 vsftpd 程序了。 借助 xinetd 管理的工作模式:将前面的选项设置为“ listen=NO” ,并配置 /etc/xinetd.d/vsftpd 文件(以前的模式)
  • 203.
    vsFTPd 的配置文件有三个: /etc/vsftpd/vsftpd.conf: vsFTPd 的主配置文件 /etc/vsftpd.ftpusers :vsFTPd 的访问控制 /etc/vsftpd.user_list:
  • 204.
    vsftpd.conf anonymous_enable=YES //允许匿名登录 local_enable=YES // 允许本地用户登录 write_enable=YES // 开放本地用户的写权限 dirmessage_enable=YES // 当切换目录时,显示该目录的信息。 connect_from_port_20=YES // 使用 FTP 数据端口 20 的连接请求 userlist_enable=YES // 与前面介绍的 vsftpd.user_list 配置文件有关,后面介绍 listen=YES // 是否允许 vsFTPd 运行在独立启动模式;如果值为 NO ,则需要使用其它软件启动 vsFTPd 。 tcp_wrappers=YES
  • 205.
    userlist_enable 用法:YES/NO 若是启动此功能,则会读取 /etc/vsftpd.user_list 当中的使用者名称。此项功能可以在询问密码前就出现失败讯息,而不需要检验密码的程序。默认值为关闭。 userlist_deny 用法: YES/NO 这个选项只有在 userlist_enable 启动时才会被检验。如果将这个选项设为 YES ,则在 /etc/vsftpd.user_list 中的使用者将无法登入﹔ 若设为 NO , 则只有在 /etc/vsftpd.user_list 中的使用者才能登入。而且此项功能可以在询问密码前就出现错误讯息,而不需要检验密码的程序。
  • 206.
    应用实例 匿名登录:anonymous_enable=YES 本地用户登录: 1 )允许登录 为使用 FTP 的用户在本地建立账号 在 vsftpd.conf 中设置配置项: local_enable=YES 2) 上传文件 : 在 vsftpd.conf 中设置配置项: write_enable=YES
  • 207.
    演示二 配置 vsftp,按照独立模式配置
  • 208.
    使用 xinetd 模式配置vsftp--- 第一步 修改 /etc/vsftpd/vsftpd.conf 将 listen=YES 改为 listen=NO
  • 209.
    使用 xinetd 模式配置vsftp--- 第二步 新增一个文件: /etc/xinetd.d/vsftpd 内容如下: service vsftpd { disable = no socket_type = stream wait = no user = root server = /usr/sbin/vsftpd port = 21 log_on_success += PID HOST DURATION log_on_failure += HOST } 重启 xinetd
  • 210.
    3 )访问控制 限制指定的本地用户不能访问,而其它本地用户可以访问。userlist_enable= YES userlist_deny= YES userlist_file= /etc/vsftpd.user_list 限制指定的本地用户可以访问,而其它本地用户不可以访问。 userlist_enable= YES userlist_deny= NO userlist_file= /etc/vsftpd.user_list 无论何时都禁止指定的本地用户访问服务器 在 /etc/vsftpd.ftpusers 配置文件中保存了一个用户列表,如果哪个用户名在这个列表中,它就不能通过网络进行 FTP 登录。
  • 211.
    DNS DNS (Domain Name System )是一个分布式数据库,本地负责控制整个分布式数据库的部分段,每一段中的数据通过客户 / 服务器模式在整个网络上均可存取,通过采用复制技术和缓存技术,在保证整个数据库可靠的同时,又拥有良好的性能。 DNS 的数据库的结构是一个倒立的树状结构,根的名字用空字符串“”来表示,但在文本中用“ .” 来书写。树的每一个节点都表示整个分布式数据库中的一个分区(域),每个域可再进一步划分成子分区(域),每个域都有一个标签( LABEL ),标明了它与父域的关系。在 DNS 中,完整域名是一个从该域到根之间路径上的标签序列,以“ .” 分隔这些标签。
  • 212.
    域名解析的工作原理主要由以下几步实现: 客户机将域名查询请求发送到本地 DNS服务器,服务器在本地数据库中查找客户机要求的映射。 如果不能在本地找到客户机查询的信息,将客户机请求发送到根域名服务器。根域名服务器负责解析客户机请求的根域部分,它将包含下一级域名信息的服务器的地址返回给客户机的 DNS 服务器。 客户机的 DNS 服务器利用根域名服务器解析的地址访问下一级 DNS 服务器,得到维护再下一级域名的 DNS 服务器的地址。 按照上述方法递归地逐级接近查找目标,最后在维护目标域名的 DNS 服务器上找到相应的 IP 地址信息。 客户机的本地 DNS 服务器将查询结果返回客户机。 客户机利用从本地 DNS 服务器查询得到的 IP 地址访问目标主机。
  • 213.
    配置实例 myoffice.myschool.org 192.168.14.11 shao.myoffice.myschool.org 主机 192.168.14.15 jing.myoffice.myschool.org 主机 192.168.14.16 zhao.myoffice.myschool.org 主机 192.168.14.16 ftp.myoffice.myschool.org FTP 服务器 192.168.14.16 www.myoffice.myschool.org Web 服务器 192.168.14.16 mail.myoffice.myschool.org 邮件服务器 192.168.14.12 dns.myoffice.myschool.org 域名服务器 IP 地址 域名 功能
  • 214.
    配置 将IP 地址映射为主机名的区文件 /var/named/14.168.192.in-addr.arpa.zone 将主机名映射为 IP 地址的区文件 /var/named/myoffice.myschool.org.zone 用户配置的区文件 用于回环 IP 地址 (127.0.0.1 ) 到本机名的映射 /var/named/0.0.127.in-addr.arpa.zone 本地主机正向解析 /var/named/localhost.zone localhost 区文件(默认) 根域名服务器的配置信息 /var/named/named.ca 根域名服务器指向文件 设置一般的 named 参数,指定该服务器使用的域数据库的信息源 /etc/named.conf 主配置文件 说明 文件名
  • 215.
  • 216.
    实验内容 1 配置telnet 服务 1 、为 linux 配置一 ip 地址,并与隔壁的机器协商配置同一段的 ip 地址,即两台机器采用同一段 ip 地址,然后互相 ping 通; 2 、在本机以自己学号创建用户,并给予密码; 3 、编辑 /etc/xinetd.d/telnet service telnet { …… disable=yes ( 这里要改为 no) … .. } 保存退出 4 、重新启动服务 service xinetd restart 5 、从另一台机器 telnet 到本机 6 、把第 3 步当中的 yes 改回 no ,保存并退出,并重启服务
  • 217.
    实验内容 2—— 配置vsftp 服务 根据实验内容 1 的网络情况,默认已经安装了 vsftp ,使用 service vsftpd restart 启动服务 使用实验内容 1 中自己创建的用户进行登录 如 创建的是 test 用户,本机或另外一台机器命令行输入 ftp X.X.X.X ,提示输入用户名和密码 尝试修改 vsftp 的三个配置文件,修改后必须重启服务 使用命令行上传下载文件
  • 218.
    假设两台机器 ip 地址为10.1.3.9 和 10.1.3.10 在 10.1.3.9 有 jack 用户,启动 ftp 服务后,在 10.1.3.10 机器终端输入命令 ftp 10.1.3.9 这时会提示输入用户名和密码,这里假设使用 jack 用户登录,登录 ftp 后当前目录为 /home/jack ,用 ls 看有何文件 lcd /tmp ( 把客户机目录切换到 tmp 下 ) bin (使用二进制模式传输文件) get filename 或 put filename bye
  • 219.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 220.
    主要内容 Shell 的作用Shell 程序的编辑和运行 基于 Bash 的 Shell 程序设计 变量声明 表达式 条件判断 控制结构 参数访问
  • 221.
    Shell 的作用 shell是用户和系统内核之间的接口程序 shell 是命令解释器 在本章中, shell 指 linux 的终端 即解释用户命令和 shell 程序的文字终端 用户 硬件 shell 操作系统 图形界面 其它用户界面
  • 222.
    linux 下的 shell用户使用 shell 的设定 通过查看 /etc/passwd 文件可以查看用户使用的 shell 类型 例子: /etc/passwd 部分节选 webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin gdm:x:42:42::/var/gdm:/sbin/nologin htt:x:100:101:IIIMF Htt:/usr/lib/im:/sbin/nologin tom:x:500:500:tom:/home/tom:/bin/bash # 可见, tom 用户使用的 shell 为 bash
  • 223.
    linux 下的 shelllinux 下的 shell 通过 cat /ect/shells 命令查看安装的 shell shell 及路径 查看 shell 的命令
  • 224.
    shell 程序 Shell程序的特点及用途: shell 程序可以认为是将 shell 命令按照控制结构组织到一个文本文件中,批量的交给 shell 去执行 不同的 shell 解释器使用不同的 shell 命令语法 shell 程序解释执行,不生成可以执行的二进制文件 可以帮助用户完成特定的任务,提高使用、维护系统的效率 了解 shell 程序可以更好的配置和使用 linux
  • 225.
  • 226.
    基于 bash 的shell 程序 简单程序示例 greeting.sh echo &quot;Programme Ends.&quot; 12 say_hello 11 echo &quot;Programme Starts Here.....&quot; 10 } 9 echo &quot;Hello $name&quot; 8 read name 7 echo &quot;Enter Your Name,Please. :&quot; 6 { 5 function say_hello() 4 #a Function 3 #a Simple shell Script Example 2 #!/bin/bash 1 解释 输出提示,提示程序结束 调用函数 程序开始的第一条命令,输出提示信息 函数结束 输出 读入用户的输入到变量 name echo 命令输出字符串 函数开始 以 functin 开始,定义函数 同上 以 # 开始,其后为程序注释 以 #! 开始,其后为使用的 shell
  • 227.
    如何执行 可以使用 /bin/sh filename 或给该文件属性添加执行权限,然后直接执行
  • 228.
    基于 bash 的shell 程序 程序编译和运行过程 一般步骤: 编辑文件 保存文件 将文件赋予可以执行的权限 运行及排错 常用到的命令: vi ,编辑、保存文件 ls -l 查看文件权限 chmod 改变程序执行权限 直接键入文件名运行文件
  • 229.
    shell 程序的编辑和执行 查看权限查看权限,初始状态无执行( x )权限 增加可执行( x )的权限 查看权限,已经具备执行( x )权限 运行程序 程序运行过程输出
  • 230.
    shell 程序设计 一般结构shell 类型 函数 主过程 #!/bin/bash function fun1(){ } ...... funciton funn(){ } ........... . . . . . . 函数定义 shell 类型 主过程
  • 231.
    变量的声明和使用 变量的声明和使用 变量是弱类型的声明变量不用声明类型 可以存储不同类型的内容 使用灵活 使用时要明确变量的类型 大小写区分 变量声明及赋值格式 格式: 变量=值 (注意:等号两侧不能有空格) 例如: a=”hello ” b=9
  • 232.
    变量的声明和使用 变量的引用 格式: $ 变量名,或者 ${ 变量名 } 变量名为一个字符用方式一,变量名多于一个字符建议用第 2 中方式 例子: a=1 abc=&quot;hello&quot; echo $a echo ${abc}
  • 233.
    Linux 是一个大小写敏感的系统, shell认为变量 foo 与 Foo 是不同的,与 FOO 也不同 当为变量赋值时,只需要使用变量名,该变量会被自动创建 要使用变量,必须在变量前加 $ 符号
  • 234.
    演示 salutation=hello echo$salutation hello salutation=“yes dear” echo $salutation yes dear salutation=7+5 echo $salutation 7+5
  • 235.
  • 236.
    使用 read 将用户的输入赋值给变量read salutation I’m jack. echo $salutation I’m jack
  • 237.
    使用引号 如果在参数中包含一个或多个空白字符,必须给参数加双引号 如果把一个带有$ 字符的变量放在双引号中,程序执行到该行时会把变量替换为它的值 如果你把它放在单引号中,不会发生替换现象 可用 \ 字符取消 $ 的特殊含义 字符串通常被放在双引号中
  • 238.
    演示 #!/bin/sh myvar=“Hithere” echo $myvar echo “$myvar” echo ‘$myvar’ echo \$myvar echo Enter some text read myvar echo ‘$myvar’ now equals $myvar exit 0
  • 239.
    环境变量 $HOME 当前用户的主目录 $PATH 以冒号分隔的用来搜索命令的目录列表 $PS1 命令提示符,通常是 $ 字符 $PS2 二级提示符 $IFS 输入域分隔符,当 shell 读取输入时,用来分隔单词的一组字符,它们通常是空格、制表符 $0 shell 脚本的名字 $# 传递给脚本的参数个数 $$ shell 脚本的进程号
  • 240.
    提示符特殊字符代码 字符 含义\! 显示该命令的历史记录编号。 \# 显示当前命令的命令编号。 \$ 显示 $ 符作为提示符,如果用户是 root 的话,则显示 # 号。 \\ 显示反斜杠。 \d 显示当前日期。 \h 显示主机名。 \n 打印新行。 \nnn 显示 nnn 的八进制值。 \s 显示当前运行的 shell 的名字。 \t 显示当前时间。 \u 显示当前用户的用户名。 \W 显示当前工作目录的名字。 \w 显示当前工作目录的路径。
  • 241.
    参数变量 $1 $2$3 ….. 脚本程序的参数 $* 在一个变量中列出所有的参数,各个参数之间用环境变量 IFS 中的第一个字符分隔开 $@ 它是 $* 的一种变体,它不使用 IFS 环境变量,所以当 IFS 为空时,参数的值不会结合在一起
  • 242.
    演示 $ IFS=‘’$ set foo bar bam $ echo “$@” foo bar bam $ echo “$*” foobarbam $ unset IFS $ echo “$*” foo bar bam
  • 243.
    演示 #!bin/sh sa=&quot;Hello&quot;echo $sa echo &quot;the program $0 is now running&quot; echo &quot;the second parameter was $2&quot; echo &quot;the first parameter was $1&quot; echo &quot;the parameter list was $*&quot; echo &quot;the user's home directory is $HOME&quot; echo &quot;please enter a new word&quot; reas sa echo $sa echo &quot;the script is now complete&quot; exit 0
  • 244.
    常用的运算符 整数的算术运算符 + 、-、 * 、 / 、 % ; 赋值运算符 +=、-=、 * =、 / =、%= 位运算符 << 、 >> 、 & 、 | 、 ~ 、 ^ ; 位运算赋值运算符 << =、 >> =、 & =、 | =、 ~ =、 ^ =; 逻辑运算符: && , || , ! , > , > =, < , < =,!=,==
  • 245.
    简单数学表达式 expr 命令计算一个表达式的值 格式 :expr arg 例子:计算( 2 + 3 ) ×4 的值 1 、分步计算,即先计算 2 + 3 ,再对其和乘 4 s=`expr 2 + 3` expr $s \* 4 2 、一步完成计算: expr `expr 2 + 3 ` \* 4 说明: 运算符号和参数之间要有空格分开; 通配符号( * ) , 在作为乘法运算符时要用 \ 、“”、‘’符号修饰
  • 246.
    简单数学表达式 let 命令 格式: let arg1 [arg2 ......] 例子:计算( 2 + 3 ) ×4 的值 let s=(2+3)*4 说明: 与 expr 命令相比, let 命令更简洁直观 当运算符中有 < 、 > 、 & 、 | 等符号时,同样需要用引号(单引号、双引号)或者斜杠来修饰运算符
  • 247.
    条件判断 常见的条件: 变量属性;文件属性; 命令执行结果; 多种条件的逻辑组合; 判断结果的一般定义: 真: 0 假: 1 格式: test condition [ condition ]
  • 248.
    条件判断 测试文件属性 如果fn 存在且 fn 为符号链接则返回真,否则返回假。 -L fn 如果 fn 存在且被当前用户拥有则返回真,否则返回假。 -O fn 如果 fn 存在且 fn 可执行则返回真,否则返回假。 -x fn 如果 fn 存在且 fn 可写则返回真,否则返回假。 -w fn 如果 fn 存在且 fn 可读则返回真,否则返回假。 -r fn 如果 fn 存在且 fn 为目录则返回真,否则返回假。 -d fn 如果 fn 存在则返回真,否则返回假。 -e fn 如果 fn 存在且 fn 为块设备则返回真,否则返回假。 -b fn 如果 fn 存在且 fn 为普通文件则返回真,否则返回假。 -f fn 常用的文件属性条件判断
  • 249.
    条件判断 字符串属性 同 -n string ,如果字符串 string 长度不为 0 返回真,否则返回假。 string 如果字符串 string 长度不为 0 则返回真,否则返回假; -n string 如果字符串 string 的长度为 0 则返回真,否则返回假; -z string 如果 string_1 和 string_2 两个字符串不相等则返回真,否则返回假; string_1 != string_2 如果 string_1 和 string_2 两个字符串相等则返回真,否则返回假; string_1 = string_2 常用字符串属性条件判断
  • 250.
    整数关系 整数间关系判断 如果num_1 大于等于 num_2 则返回真,否则返回假; mum_1 –ge num_2 如果 num_1 小于等于 num_2 则返回真,否则返回假; mum_1 –le num_2 如果 num_1 小于 num_2 则返回真,否则返回假; mum_1 –lt num_2 如果 num_1 大于 num_2 则返回真,否则返回假; mum_1 –gt num_2 如果 num_1 不等于 num_2 则返回真,否则返回假; mum_1 –ne num_2 如果 num_1 和 num_2 相等则返回真,否则返回假; mum_1 –eq num_2 常用的整数关系条件判断
  • 251.
    管道和重定向 ls –l> lsoutput.txt 该命令把 ls –l 的结果输出到 lsoutput.txt 文件中 通过 > 把标准输出重定向到一个文件,如果该文件已经存在,会覆盖文件的内容 可以用 >> 追加文件内容,而不是覆盖
  • 252.
    重定向 文件描述符 0代表一个程序的标准输入 文件描述符 1 代表一个程序的标准输出 文件描述符 2 代表一个程序的标准错误输出
  • 253.
    重定向 如果想对标准错误进行重定向,需要把准备重定向的文件描述符编号加在 >操作符的前面,即 2> ,当需要丢弃错误信息并阻止它显示在屏幕,这个方法很有用 kill –HUP 1234 >killout.txt 2>killerr.txt kill –l 1234 >killouterr.txt 2>&1 (2>&1 意思是把标准输出重定向到文件 killouterr.txt ,然后将标准错误输出重定向到与标准输出相同的地方,顺序不可有误 ) Kill –l 1234 >/dev/null 2>&1 (可以用“回收站” /dev/null 来有效丢弃所有输出信息)
  • 254.
    管道 管道符 | 用于连接进程 通过管道连接的进程可以同时运行 , 并且随着数据流在它们之间的传递可以自动地进行协调 ls –l | grep hello ls –l | more ls –l | grep hello > lsoutput.txt
  • 255.
  • 256.
    if 分支 格式:说明: 中括号中的部分可省略; 当条件为真( 0 )时执行 then 后面的语句,否则执行 else 后面的语句; 以 fi 作为 if 结构的结束。 if 条件 1 then 命令 [elif 条件 2 then 命令 ] [else 命令 ] fi
  • 257.
    #!/bin/sh echo –n“Is it morning? Please answer yes or no? read timeofday If [ $timeofday = “yes” ] then echo “Good morning” elif [ $timeofday = “no” ]; then echo “Good afternoon” else echo “sorry,$timeofday not recognized. Enter yes or no” exit 1 fi exit 0
  • 258.
    echo 语法 echo–n 命令去除换行符
  • 259.
    case 分支 格式:说明: “ 条件”可以是变量、表达式、 shell 命令等; “ 模式”为条件的值,并且一个“模式”可以匹配多种值,不同值之间用竖线( | )联结 ; 一个模式要用双分号(;;)作为结束 ; 以逆序的 case 命令( esac )表示 case 分支语句的结束 case 条件 in 模式 1) 命令 1 ;; [ 模式 2 ) 命令 2 ;; ............... 模式 n ) 命令 n ;; ] esac
  • 260.
    ? :仅与一个任意字符匹配 *:匹配任意字符 [...] :同方括号中的任意一个字符相匹配。这些字符可以用字符范围 ( 比如 1-9) 或者 离散值 或同时使用两者表示。例如: [a-zBE5-7] 同所有 a 到 z 之间的字符和 B 、 E 、 5 、 6 、 7 相匹配。 [!...] :与所有 不在 方括号中的某个字符匹配。例如 [!a-z] 同某个非小写字母相匹配 [ 5 ] ; {c1,c2} :同 c1 或者 c2 相匹配。其中 c1 和 c2 也是通配符。因此,您可以使用 {[0-9]*,[acr]} 。
  • 261.
    以下是一些通配符模式及其说明: /etc/*conf :/etc 目录中所有以 conf 结尾的文件。它将同 /etc/inetd.conf 、 /etc/conf.linuxconf , 并且也会同 /etc/conf 相匹配。请注意, * 也匹配空字符串。 image/{cars,space[0-9]}/*.jpg : image/cars 、 image/space0 、 (...) 、 image/space9 目录中以 .jpg 结尾的文件。 /usr/share/doc/*/README :所有 /usr/share/doc 的直接子目录中的全部 README 文件。比如 /usr/share/doc/mandrake/README 。但是不包括 /usr/share/doc/myprog/doc/README 。 *[!a-z] :当前目录中 不以 小写字符结尾的全部文件。
  • 262.
    #!/bin/sh echo &quot;Isit morning? Please answer yes or no?&quot; read timeofday case &quot;$timeofday&quot; in yes | y | Yes | YES ) echo &quot;good morning&quot; ;; [nN]* ) echo &quot;good afternoon&quot; ;; * ) echo &quot;error&quot; exit 1 ;; esac exit 0
  • 263.
    for 循环 格式说明: “ 列表”为存储了一系列值的列表,随着循环的进行,变量从列表中的第一个值依次取到最后一个值; do 和 done 之间的命令通常为根据变量进行处理的一系列命令,这些命令每次循环都执行一次; 如果中括号中的部分省略掉, Bash 则认为是“ in $@” ,即执行该程序时通过命令行传给程序的所有参数的列表。 for 变量 [in 列表 ] do 命令(通常用到循环变量) done
  • 264.
    #!/bin/sh for varin v1 v2 v3 do echo $var done exit 0
  • 265.
    #!/bin/sh for filein $(ls f*.sh); do lpr $file done exit 0
  • 266.
    while 循环与 until循环 格式: 说明: while 循环中,只要条件为真,就执行 do 和 done 之间的循环命令; until 循环中,只要条件不为真,就执行 do 和 done 之间的循环命令,或者说,在 until 循环中,一直执行 do 和 done 之间的循环命令,直到条件为真; 避免生成死循环。 while/until 条件 do 命令 done
  • 267.
    #!/bin/sh foo=1 while[ &quot;$foo&quot; -le 20 ] do echo &quot;$foo&quot; foo=$(($foo+1)) done exit 0
  • 268.
    #!/bin/sh until who| grep &quot;$1&quot; > /dev/null do sleep 30 done echo -e echo &quot;$1 has just logged in&quot; exit 0
  • 269.
    函数 格式: 定义:引用: 说明: 中括号中的部分可以省略; 如果在函数内部需要使用传递给函数的参数,一般用 $0 、 $1 、 ...... 、 $n ,以及 $# 、 $* 、 $@ 这些特殊变量 : $0 为执行脚本的文件名; $1 是传递给函数的第 1 个参数 ; $# 为传递给函数的参数个数; $* 和 $@ 为传递给函数的所有参数 [function] 函数名() { 命令 } 函数名 [ 参数 1 参数 2 ... 参数 n ]
  • 270.
    函数对变量的访问示例 即变为下一个变量 变量左移,$1 变为原来 $1 的右侧的变量 变量计数加 1 输出第一个变量 访问变量 $1, 即第一个变量 函数开始 ...... } done shift let count=$count+1 echo &quot;Parameters(\$$count) is:$1&quot; do while [ -n &quot;$1&quot; ] ...... { function demo_fun() 利用 shift 访问参数变量
  • 271.
    实验任务一 设计一个菜单驱动程序。如下:Use one of the following options: P:  To display current directory S:  To display the name of running file D:  To display today’s date and present time L:  To see the listing of files in your present working directory W:  To see who is logged in Q:  To quit this program Enter your option and hit : 菜单程序将根据用户输入的选择项给出相应信息。要求对用户的输入忽略大小写,对于无效选项的输入给出相应提示。 要求使用 case 语句实现以上功能,输入响应的字母后应该执行响应的命令完成每项功能,如输入 P 或 p ,就执行 pwd 命令。
  • 272.
    实验任务二 编写一段bash shell 程序,完成:根据从键盘输入的学生成绩,显示相应的成绩等级,其中 60 分以下为“ Failed !”, 60-70 分为“ Passed !”, 70-80 分为“ Medium !”, 80-90 分为“ Good !”, 90-100 为“ Excellent !”。 如果输入超过 100 的分数,则显示错误分数提示。
  • 273.
    注意事项:实验要求有良好格式,有正确的返回码指令,实验完成后所有人要提交实验报告,报告内容包括实验题目、程序流程图、程序代码、运行效果图。 学号尾数为 2的同学检查任务一,学号尾数为 8 的同学检查任务二。检查时间为 11 月 12 日上机,报告提交时间为 11 月 12 日理论课中。
  • 274.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 275.
    进程的概念 Linux 系统上所有运行的东西都可以称之为一个进程。每个用户任务、每个系统管理任务,都可以称之为进程。进程是一个程序的运行。 进程与程序是有区别的。程序只是一个静态的指令集合,不占系统的运行资源;而进程是一个随时都可能发生变化的、动态的、使用系统运行资源的程序。一个程序可以启动多个进程。
  • 276.
    进程的概念 Linux 操作系统包括三种不同类型的进程,每种进程都有自己的特点和属性:交互进程 : 由 shell 启动的进程。 批处理进程 : 这种进程和终端没有联系,是一个进程序列。 守护进程 : 在后台持续运行的进程。
  • 277.
    启动进程 / 手工启动 前台启动 : 一般地,用户键入一个命令,就已经启动了一个前台的进程。 后台启动 : 对于非常耗时进程,可以让进程在后台运行。从后台启动进程其实就是在命令结尾加上一个“ &” 号
  • 278.
    启动进程 / 调度启动 1 ) at 命令 在 shell 提示符下输入” at 时间”,然后按回车键。这时在下一行 shell 会等待用户继续输入要执行的命令。每一行输入一个命令,所有命令都输入完毕后按 Ctrl+d 键结束。 将各个命令写入 shell 脚本中,然后使用下面格式设置在指定时间执行 shell 脚本中的命令: at 时间 – f 脚本文件。 batch 命令
  • 279.
    启动进程 / 调度启动 /cron 命令 cron 命令在系统启动时由一个 shell 脚本自动启动,进入后台。 cron 启动后搜索 /var/spool/cron 目录,寻找以 /etc/passwd 文件中的用户名命名的 crontab 文件,被找到的这种文件将载入内存。 如果没有 crontab 文件,就转入“休眠”状态,释放系统资源。 cron 每分钟“醒”过来一次,查看当前是否有需要运行的命令。 如果发现某个用户设置了 crontab 文件,它将以该用户的身份去运行文件中指定的命令。命令执行结束后,任何输出都将作为邮件发送给 crontab 的所有者,或者 /etc/crontab 文件中 MAILTO 环境变量中指定的用户。
  • 280.
    cron crontab 文件格式59 23 * * * tar czvf lhy.tar.gz /home/lhy crontab 命令用于安装、删除或者列出用于驱动 cron 后台进程的 crontab 文件 : crontab 源文件格式 <minute> <hour> <day-of-month> <month-of-year> <day-of-week> <commands> 59 23 * * * tar czvf lhy.tar.gz /home/lhy
  • 281.
    格式 crontab [ - u user ] 文件 crontab [ - u user ] { - l | - r | - e } 主要参数 - e :执行文字编辑器来设定时程表,内定的文字编辑器是 vi - r :删除目前的时程表 - l :列出目前的时程表 和 at 命令相比, crontab 命令适合完成固定周期的任务
  • 282.
    Crontab 举例 以某一用户终端,输入crontab - e 此时系统会打开一个 vi 编辑器 在该编辑器中输入 35 17 * * 5 wall &quot;Tomorrow is Saturday I will go CS&quot;
  • 283.
    进程管理命令 进程查看命令 ps ps [ 选项 ] 主要选项的含义如下: -e :显示所有进程; -h :不显示标题; -l :采用详细的格式来显示进程; -a :显示所有终端上的进程,包括其他用户的进程; -r :只显示当前终端上正在运行的进程; -x :显示所有进程,不以终端来区分; -u :以用户为主的格式来显示进程;
  • 284.
    删除进程命令 kill kill[-s < 信号 > | -p ] [ -a ] < 进程号 > .. kill [-s < 信号 > | -p ] [ -a ] < 进程号 > ... kill -l [ 信号 ] 选项的含义如下: -s :指定需要送出的信号。既可以是信号名也可以是信号名对应的数字。 -p :指定 kill 命令只显示命名进程的 pid ,并不真正送出任何信号。 -l :显示信号名称列表,该列表也可以在 /usr/include/linux/signal.h 文件中找到。
  • 285.
    强行中止(经常使用杀掉)一个进程标识号为 324 的进程:# kill - 9 324 解除 Linux 系统的死锁 使用命令回收内存 killall 命令 Linux 下还提供了一个 killall 命令,可以直接使用进程的名字而不是进程标识号,例如: # killall -HUP inetd
  • 286.
    系统监视 系统监控命令top :能显示实时的进程列表,而且还能实时监视系统资源,包括内存、交换分区和 CPU 的使用率等。
  • 287.
  • 288.
    top 命令使用过程中,可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。 <空格 > :立刻刷新。 P :根据 CPU 使用大小进行排序。 T :根据时间、累计时间排序。 q :退出 top 命令。 m :切换显示内存信息。 t :切换显示进程和 CPU 状态信息。 c :切换显示命令名称和完整命令行。 M :根据使用内存大小进行排序。
  • 289.
    内存查看命令 free 磁盘空间用量查看命令 df
  • 290.
  • 291.
  • 292.
    日志查看 日志文件(log files )是包含关于系统消息的文件,包括内核、服务、在系统上运行的应用程序等。 不同的日志文件记载不同的信息。 多数的日志文件位于 /var/log 目录下。 某些程序(如 apache )在 /var/log 中有单独的日志文件目录。 日志可以滚动
  • 293.
  • 294.
    日志查看 多数日志文件都使用纯文本格式,可以使用任何文本编辑器如vi 来查看它们。 大多数日志文件都需要拥有特权才允许查看。 图形化的日志查看器
  • 295.
  • 296.
    Grep 用法 grep ( global search regular expression(RE) and print out the line, 全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具 使用正则表达式搜索文本 linux 使用 GNU 版本的 grep
  • 297.
    grep 正则表达式元字符集(基本集) ^ 锚定行的开始 如: '^grep' 匹配所有以 grep 开头的行。 $ 锚定行的结束 如: 'grep$' 匹配所有以 grep 结尾的行。 . 匹配一个非换行符的字符 如: 'gr.p' 匹配 gr 后接一个任意字符,然后是 p 。 * 匹配零个或多个先前字符 如: '*grep' 匹配所有一个或多个空格后紧跟 grep 的行。 .* 一起用代表任意字符。 [] 匹配一个指定范围内的字符,如 '[Gg]rep' 匹配 Grep 和 grep 。 [^] 匹配一个不在指定范围内的字符,如: '[^A-FH-Z]rep' 匹配不包含 A-R 和 T-Z 的一个字母开头,紧跟 rep 的行。 \(..\) 标记匹配字符,如 '\(love\)' , love 被标记为 1 。
  • 298.
    \< 锚定单词的开始,如:'\<grep' 匹配包含以 grep 开头的单词的行。 \> 锚定单词的结束,如 'grep\>' 匹配包含以 grep 结尾的单词的行。 x\{m\} 重复字符 x , m 次,如: '0\{5\}' 匹配包含 5 个 o 的行。 x\{m,\} 重复字符 x, 至少 m 次,如: 'o\{5,\}' 匹配至少有 5 个 o 的行。 x\{m,n\} 重复字符 x ,至少 m 次,不多于 n 次,如: 'o\{5,10\}' 匹配 5--10 个 o 的行。 \w 匹配文字和数字字符,也就是 [A-Za-z0-9] ,如: 'G\w*p' 匹配以 G 后跟零个或多个文字或数字字符,然后是 p 。 \W \w 的反置形式,匹配一个或多个非单词字符,如点号句号等。 \b 单词锁定符,如 : '\bgrep\b' 只匹配 grep 。
  • 299.
    $ ls -l| grep '^a' 通过管道过滤 ls -l 输出的内容,只显示以 a 开头的行。 $ grep 'test' d* 显示所有以 d 开头的文件中包含 test 的行。 $ grep 'test' aa bb cc 显示在 aa , bb , cc 文件中匹配 test 的行。 $ grep '[a-z]\{5\}' aa 显示所有包含每个字符串至少有 5 个连续小写字符的字符串的行
  • 300.
    awk 命令 最基本功能是在文件或字符串中基于指定规则浏览和抽取信息 df | awk '$4>1000000 ' 通过管道符获得输入,如:显示第 4 个域满足条件的行
  • 301.
    实验任务三(学号尾数为 0 ,1 的检查) 编写一个 Shell 过程完成如下功能(必须在脚本中使用函数): 1 、合并两个 $1 、 $2 文件为 $3 ,并显示。 2 、如果缺少 $3 ,那么先报告缺少 $3 ,然后将合并后的内容输出到 mydoc.txt 。如果有 $3 ,就合并到 $3 3 、如果缺少 $2 、 $3 那么先报告缺少 $2 、 $3 ,只显示 $1 的内容。
  • 302.
    实验任务四(学号尾数为 3 的检查)利用所学知识,实现如下目标: 某用户需要在每天晚上 11 点启动服务器的 ftp 服务,使得其他用户可以上传重要数据。而在每天凌晨 3 点就关闭 ftp 服务。在这个过程中要自动记录日志信息,每天是否成功启动 ftp 要体现在日志信息中,如果成功启动必须记录 ftp 的进程信息,如果没有启动,就记录错误信息。 约定如下: 日志文件为 /tmp/ftplog 实验任务四在上机检查时应把时间调整为当前具体可行的时间。
  • 303.
    实验任务五(学号尾数为 7 的检查)编写一个脚本,显示当天日期,查找给定的某用户是否在系统中工作。如果在系统中,就发一个问候给他。
  • 304.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 305.
    主要内容 gcc 简介功能 命令 利用 gcc 编译 c 程序 利用 make 工具简化编译过程 make 简介 Makefile 基本格式 调试 静态调试 动态调试 gdb 调试工具的使用
  • 306.
    gcc 简介 名称:G NU project C and C ++ C ompiler G NU C ompiler C ollection 管理与维护 GNU 项目 对 C/C++ 编译的控制 预处理( Preprocessing ) 编译( Compilation ) 汇编( Assembly ) 链接( Linking )
  • 307.
    gcc 的使用 基本使用格式 $ gcc [ 选项 ] < 文件名 > 常用选项及含义 将经过 gcc 处理过的结果存为文件 file ,这个结果文件可能是预处理文件、汇编文件、目标文件或者最终的可执行文件。假设被处理的源文件为 source.suffix ,如果这个选项被省略了,那么生成的可执行文件默认名称为 a.out ;目标文件默认名为 source.o ;汇编文件默认名为 source.s ;生成的预处理文件则发送到标准输出设备。 -o file 含义 选项 gcc 常用选项
  • 308.
    gcc 的常用选项 含义选项 gcc 常用选项 将名为 name 的宏定义为 definition ,如果中括号中的部分缺省,则宏被定义为 1 -D name[=definition] 对生成的代码使用优化,中括号中的部分为优化级别,缺省的情况为 2 级优化, 0 为不进行优化。注意,采用更高级的优化并不一定得到效率更高的代码。 -O[0 、 1 、 2 、 3] 在可执行文件中加入调试信息,方便进行程序的调试。如果使用中括号中的选项,表示加入 gdb 扩展的调试信息,方便使用 gdb 来进行调试 -g[gdb] 仅对源文件进行编译,不链接生成可执行文件。在对源文件进行查错时,或只需产生目标文件时可以使用该选项。 -c
  • 309.
    gcc 的常用选项 含义选项 gcc 常用选项 允许产生 warning 类型的警告, warning 可以是: main 、 unused 等很多取值,最常用是 -Wall ,表示产生所有警告。如果 warning 取值为 error ,其含义是将所有警告作为错误( error ),即出现警告就停止编译。 -W warning 禁止所有警告 -w 在编译链接文件时增加一个额外的库,库名为 library .a -l library 在编译源文件时增加一个搜索库文件的额外目录—— dir -L dir 在编译源程序时增加一个搜索头文件的额外目录—— dir ,即 include 增加一个搜索的额外目录。 -I dir
  • 310.
    gcc 文件扩展名规范 gcc 可以根据文件扩展名执行操作 链接 目标文件 .o 不进行任何操作 头文件 .h 预处理、汇编、链接 未预处理的汇编程序 .S 汇编、链接 预处理后的汇编程序 .s 编译、汇编、链接 预处理后的 c++ 语言源程序 .ii 编译、汇编、链接 预处理后的 c 语言源程序 .i 预处理、编译、汇编、链接 c++ 语言源程序 .C , .cc , .cp , .cpp , .c++ , .cxx 预处理、编译、汇编、链接 c 语言源程序 .c 可进行的操作方式 类型 扩展名 gcc 文件扩展名规范
  • 311.
    使用 gcc 编译代码源代码 示例源程序—— hello.c #include <stdio.h> int main(void) { printf(&quot;hello gcc!\r\n&quot;); return 0; }
  • 312.
    生成预处理文件 命令 $gcc –E hello.c –o hello.i 预处理文件 hello.i 的部分内容 ...... extern void funlockfile (FILE *__stream) ; # 679 &quot;/usr/include/stdio.h&quot; 3 # 2 &quot;hello.c&quot; 2 int main(void) { printf(&quot;hello gcc!\n&quot;); return 0; }
  • 313.
    生成汇编文件 命令 $gcc –S hello.c –o hello.s 汇编文件 hello.s 的部分内容 ...... main: pushl %ebp movl %esp, %ebp ........ addl $16, %esp movl $0, %eax leave ret ......&quot;
  • 314.
    编译多个文件 文件清单 #endif void greeting (char * name); #define _GREETING_H #ifndef _GREETING_H greeting.h { printf(&quot;Hello %s!\r\n&quot;,name); } void greeting (char * name) #include &quot;greeting.h&quot; #include <stdio.h> greeting.c char name[N]; printf(&quot;Your Name,Please:&quot;); scanf(&quot;%s&quot;,name); greeting(name); return 0; int main(void) { } #define N 10 #include &quot;greeting.h&quot; #include <stdio.h> my_app.c
  • 315.
    生成二进制文件 生成目标文件 命令:$gcc –c hello.c –o hello.o 生成可执行文件 命令: $gcc hello.c –o hello 运行程序 $./hello hello gcc!
  • 316.
    编译多个文件 目录结构 (1)编译命令 $ gcc my_app.c greeting.c –o my_app 目录结构 (2) 编译方式 (1) $ gcc my_app.c functions/greeting.c –o my_app -I function greeting.h ./ greeting.c my_app.c greeting.h ./ greeting.c my_app.c functions
  • 317.
    编译多个文件 目录结构 (2)编译方式 (2) 分步编译 命令: 1 、 $gcc -c my_app.c -Ifunctions 2 、 $gcc -c functions/greeting.c 3 、 $gcc my_app.o greeting.o –o my_app 思路: 编译每一个 .c 文件,得到 .o 的目标文件; 将每一个 .o 的目标文件链接成一个可执行的文件;
  • 318.
    使用 make 工具适用场合: 多个文件组成的软件项目 基本格式: 目标:欲生成的目标文件 依赖项:生成目标需要的文件 原理: 判断依赖项是否为最新,否则,生成新的目标 make 工具的使用格式: make [[ 命令选项 ] [ 命令参数 ]] 通常使用 make 就可以了, make 会寻找 Makefile 作为编译指导文件; 目标:依赖项列表 ( Tab 缩进)命令
  • 319.
    使用 make 工具Makefile 示例 gcc –c my_app.c –Ifunctions 6 my_app.o:my_app.c functions\greeting.h 5 gcc -c functions\greeting.c 4 greeting.o:functions\greeting.c functions\greeting.h 3 gcc my_app.o greeting.o -o my_app 2 my_app:greeting.o my_app.o 1 Makefile 文件
  • 320.
    使用 make 工具目标的依赖关系 my_app my_app.o greeting.o my_app.c functions\greeting.h functions\greeting.c gcc –c my_app.c –Ifunctions gcc -c functions\greeting.c gcc my_app.o greeting.o -o my_app
  • 321.
    使用 make 工具更实用的 Makefile ${CC} ${CFLAGS} -c my_app.c -Ifunctions 9 my_app.o:my_app.c functions\greeting.h 8 ${CC} ${CFLAGS} -c functions\greeting.c 7 greeting.o:functions\greeting.c functions\greeting.h 6 ${CC} ${OBJS} -o my_app 5 my_app:${OBJS} 4 CFLAGS = -Wall -O –g 3 CC = gcc 2 OBJS = greeting.o my_app.o 1 更实用的 Makefile 文件
  • 322.
    调试 调试 静态调试:在程序编译阶段查错并修正错误; 主要为语法错误: 输入错误; 类型匹配错误; 排错方式: 利用错误、警告信息,并结合源文件环境排错 动态调试: 在程序运行阶段差错并修正错误; 主要错误类型: 算法错误; 输入错误; 排错方式: 利用调试工具定位并修正错误;
  • 323.
    调试举例 源文件 #endif void greeting (char * name); #define _GREETING_H #ifndef _GREETING_H greeting.h { printf(&quot;Hello !\r\n&quot;); } void greeting (char * name) #include &quot;greeting.h&quot; #include <stdio.h> greeting.c 11 10 9 8 7 6 5 4 3 2 1 char name[n]; printf(&quot;Your Name,Please:&quot;); scanf(&quot;%s&quot;,name) greeting(name); /*return 0;*/ int main(void) { } #define N 10 #include &quot;greeting.h&quot; #include <stdio.h> my_app.c
  • 324.
    静态调试举例 分块编译 greeting.c$gcc -g -Wall -c functions/greeting.c -g :将调试信息加入到编译的目标文件中 ; -Wall : 将编译过程中的所有级别的警告都打印出来 ; 无错误 my_app.c $gcc -g -Wall -c my_app.c -Ifunctions 参数含义同上 错误信息:
  • 325.
    调试举例 错误信息: 错误记录格式:文件名:行好:错误描述 my_app.c: In function `main': my_app.c:6: `n' undeclared (first use in this function) my_app.c:6: (Each undeclared identifier is reported only once my_app.c:6: for each function it appears in.) my_app.c:9: parse error before &quot;greeting&quot; my_app.c:6: warning: unused variable `name'
  • 326.
    静态调试举例 分析、定位错误(警告): my_app.c的第 6 行: 描述含义: n 是一个没有声明的变量; 分析: 声明数字 name 时用到了变量 n ,但变量 n 在之前没有声明; 改正: 声明一个新变量 n ; 或者 将 n 改为宏 N 这里取第 2 种改正方法;
  • 327.
    静态调试举例 my_app.c 的第9 行: 描述含义: 在“ greeting” 之前出现解析错误; 分析: c 中每行程序以;结束,第 9 行 greeting 之前的程序行没有以;结束; 改正: 第 8 行末尾增加“;” 重新编译 错误信息: my_app.c: In function `main': my_app.c:11: warning: control reaches end of non-void function
  • 328.
    静态调试举例 分析、定位错误(警告): 警告:my_app.c 的 11 行 描述含义: 控制以非空函数结束; 分析: main 函数返回类型为 int ,源程序没有以 return 整数 形式结束; 改正: 将 main 改为返回 void 类型; 或者: 在 main 程序后增加 return 返回语句; 采用第 2 种解决方式; 重新编译,无错误或警告信息,完成静态调试
  • 329.
    静态调试举例 静态调试总结 主要为语法错误:输入错误; 类型匹配错误; 分析信息: 主要来自 gcc 编译时产生的提示信息 错误警告定位: 不一定在提示信息描述的地方; 综合分析提示信息及提示行的上下文环境,定位并修正错误、警告。 有的警告可以不用修复;
  • 330.
    动态调试举例 常见的动态调试方法: 增加调试语句; 记录程序的执行状况 ; 观察内存变化 ; 使用调试工具; GUN Debuger 的功能: 启动程序,设置程序执行的上下文环境; 在指定的条件下停止程序; 程序停止时,检查程序的状态; 在程序运行时,改变程序状态,使其按照改变后的状态继续执行。
  • 331.
    动态调试举例 查看指定文件或者函数的源代码,并标出行号 list执行其后的 shell 命令 shell 设置断点,程序执行到断点就会暂停起来 break 查看变量或者表达式的值 print 退出 gdb 调试环境 quit 启动被执行的程序 run 单步(行)执行,如果遇到函数不会进入函数内部 next 单步(行)执行,如果遇到函数会进入函数内部 step 指定需要进行调试的程序 file 含义 命令 gdb 常用的调试命令
  • 332.
    动态调试举例 对静态调试中的例子继续进行动态调试 工具:gdb 启动 gdb $gdb GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type &quot;show copying&quot; to see the conditions. There is absolutely no warranty for GDB. Type &quot;show warranty&quot; for details. This GDB was configured as &quot;i386-redhat-linux-gnu&quot;. (gdb) 启动命令 启动提示 启动完毕
  • 333.
    动态调试举例 调试指定程序( ./my_app) 问题: 期望的输出和实际输出不一致 (gdb) file ./my_app Reading symbols from ./my_app...done (gdb) run Starting program: /home/tom/shell_script/cpp/my_app/my_app Your Name,Please: tom Hello ! Program exited normally. (gdb) 加载调试程序 启动调试程序 程序输出 提示信息
  • 334.
    动态调试举例 初次错误定位: 输出有错误错误定位 重新开始一次调试 ; 启动 gdb; 加载调试程序( ./my_app ) ; 查看程序源代码 命令: list 文件名
  • 335.
    动态调试举例 (gdb) list my_app.c:1,20 1 #include <stdio.h> 2 #include &quot;greeting.h&quot; 3 #define N 10 4 int main(void) 5 { 6 char name[N]; 7 printf(&quot;Your Name,Please:&quot;); 8 scanf(&quot;%s&quot;,name); 9 greeting(name); 10 return 0; 11 } (gdb) break 7 BreakPoint 1 at 0x8048384: file my_app.c, line 7. 在程序第 7 行设置断点 命令: (gdb) break 7 查看源代码 设置断点 提示信息
  • 336.
    动态调试举例 错误详细定位 9 greeting(name); 9 Your Name,Please :tom 8 (gdb) next 7 8 scanf(&quot;%s&quot;,name); 6 (gdb) next 5 7 printf(&quot;Your Name,Please:&quot;); 4 Breakpoint 1 , main () at my_app.c : 7 3 Starting program: /home/tom/shell_script/cpp/my_app/my_app 2 (gdb) run 1 启动调试程序 断点激活 步进下一步
  • 337.
    动态调试举例 错误详细定位 (gdb) quit 20 Kill the programe being debugged?(y or n)y 19 (gdb) kill 18 6 } 17 Hello ! 16 (gdb) step 15 5 printf (” Hello !\r\n” ) ; 14 greeting ( name=0xbfffdf20 “tom” ) at functions/greeting.c : 5 13 (gdb) step 12 $1 = “tom\000 ò·000©® 11 (gdb) print name 10 查看变量值 进入函数内部 步进执行 停止调试 退出 gdb
  • 338.
    动态调试举例 分析 :11 行说明 name 变量被正确赋值( tom ) 13 行说明 name 变量值被正确赋予 greeting 的参数变量 name 16 说明打印出现了错误,即错误出现在函数 greeting 中; 综合分析 错误出现在 greeting.c 的第 5 行; 原因: 没有输出字符串的格式不对; 改正错误
  • 339.
    动态调试举例 动态调试总结 主要错误类型:算法错误; 输入错误; 定位方法: 设置断点; 单步步进执行; 查看变量取值变化; 反复执行,逐步缩小错误范围;
  • 340.
    课后习题 1 、从文本源代码到可执行文件,gcc 可以对哪些步骤进行控制? 2 、编一个简单的 helloworld 程序,利用 gcc 控制程序生成的四个步骤。 3 、简述 gcc 的用法和常用参数的含义。 4 、上机查找 gcc 利用的库文件和头文件都放在什么路径下? 5 、 make 工具如何使用? Makefile 的基本格式是什么? 6 、简述 gdb 的用法和常用命令的含义。
  • 341.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 342.
    主要内容 Gtk +的主要功能Gtk +简介 利用 Gtk+ 开发图形界面程序 基本程序示例 应用容器的程序示例
  • 343.
    X 窗口 X服务器 运行在用户的本地机器上,在屏幕上完成低层的绘图操作 X 客户端 是以 X 窗口系统作为 GUI 的任何程序,它等候 X 服务器传送的用户事件,然后通过给 X 服务器发送重绘消息来响应 X 协议 X 服务器和 X 客户端之间的通讯协议 Xlib 库 是 X 客户端间接用于产生 X 协议消息的库,它提供一个非常底层的 API 、允许客户端在 X 服务器上绘出非常基本的元素
  • 344.
    X 工具包 X工具是一个 GUI 库, X 客户端用它极大地简化了窗口、菜单、按钮等的创建 其他平台无关的窗口 API JAVA 语言使用 swing 和 AWT API 来支持 GUI 程序设计 Tcl/Tk 脚本语言
  • 345.
    Gtk +的作用 Gtk+工具包在 XWindows 中的作用 是 Xlib 之上更高层的开发工具包,它们将底层的 Xlib 的 API 进行封装,提供更高级的接口,达到降低开发难度,提高开发效率的目的。 网络协议 X 客户端(应用程序) X 工具包、 Gtk+,Qt XLib X 客户端(应用程序) X 工具包、 Gtk+,Qt XLib X 服务器 设备驱动程序
  • 346.
    Gtk +简介 来源:Gimp ( GUN Image Manipulation Program ) 以 Gtk+ 为基础的应用软件 Gimp Glade Gnome Abiword dia 等 Gtk +的主要组成 Glib :底层核心库 Pango :界面布局和国际化 Atk :其它功能
  • 347.
  • 348.
    GtkWindow 对象层次 GObjectGtkObject GtkWidget GtkContainer GtkBin -- GtkWindwo
  • 349.
    GtkWidget 窗口小部件所有窗口部件创建函数都返回一个 GtkWidget 类型
  • 350.
    #include <gtk/gtk.h> intmain(int argc,char *argv[]) { GtkWidget *window; gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_show(window); gtk_main(); return 0; }
  • 351.
    开发图形界面程序 基本程序示例 on_btn_clicked(),按钮事件处理程序 on_delete(), 窗口关闭事件处理程序 } 8 gtk_main_quit(); 7 g_print(&quot;Window Closed.\n&quot;); 6 void on_delete(GtkWidget *widget, GdkEvent *event, gpointer data){ 5 } 4 g_print(&quot;Hello World!\n&quot;); 3 void on_btn_clicked(GtkWidget *widget, gpointer data){ 2 #include <gtk/gtk.h> 1 helloworld.c 代码片断 1 部分辅助函数
  • 352.
    } 26 return0; 25 gtk_main();// 启动消息循环 24 gtk_widget_show_all(window);// 显示窗口 23 gtk_container_add (GTK_CONTAINER (window), button); 22 G_CALLBACK (on_btn_clicked), NULL);// 关联按钮事件 21 g_signal_connect (G_OBJECT (button), &quot;clicked&quot;, 20 button = gtk_button_new_with_label (&quot;Hello World&quot;); 19 G_CALLBACK (on_delete), NULL);// 关联窗口关闭事件 18 g_signal_connect (G_OBJECT (window), &quot;delete_event&quot;, 17 gtk_container_set_border_width (GTK_CONTAINER (window), 10); 16 gtk_window_set_title(GTK_WINDOW(window),&quot;Hello World!&quot;); 15 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);// 创建窗口 14 gtk_init(&argc,&argv);// 初始化运行环境 13 gtk_set_locale(); 12 GtkWidget *button; 11 GtkWidget *window; 10 int main(int argc, char * argv[ ]){ 9 helloworld.c 代码片断 2—— 主函数部分
  • 353.
    基本程序示例 程序运行效果 组成:一个按钮 一个窗口 动作: 点击按钮,在终端输出一个字符串 点击关闭窗口,在终端输出一个字符串后,退出
  • 354.
    基本程序示例 程序的编译运行 假设条件:源文件保存在当前工作目录中; 源文件命名为 helloworld.c 利用 gcc 编译: 命令: $gcc helloworld.c –o helloworld `pkg-config gtk+-2.0 --cflags --libs` 说明 输出文件为 helloworld 以命令 pkg-config gtk+-2.0 --cflags --libs 的运行结果为 gcc 的额外参数; 运行 : ./helloworld 运行
  • 355.
    常用事件及处理函数原型 void user_function (GtkList *list , gpointer data); selection-changed void user_function(GtkList *list, GtkWidget *widget , gpointer data); select-child GtkList void user_function(GtkComboBox *widget, gpointer data); changed GtkComboBox enter clicked void user_function( GtkButton *widget , gpointer data); activate GtkButton delete-event gboolean user_function(GtkWidget*widget, GdkEventExpose *event , gpointer data); expose-event void user_function (GtkWidget *widget, gpointer data); show GtkWidget 处理函数原型 事件名 事件源 常用的 gtk+ 事件及处理函数原型
  • 356.
    应用容器的 Gtk +程序容器: 所谓容器,就是可以在其中放置其它界面元素的元素。其中放置的元素可以是可见的按钮、图标,也可以还是一个容器; 以继承的观点来理解, GtkWidget 有一个直接的派生类—— GtkContainer 作为所有容器类的基类; 按照容器中可以容纳元素的个数,容器又可以分为两类: 只能容纳一个元素的容器; 可以容纳多个元素的容器。
  • 357.
    应用容器的 Gtk +程序常见的容器: 容纳一个元素:( GtkBin 的子类 ) GtkWindow GtkButton GtkFrame 容纳多个元素 :( GtkContainer 的子类) GtkBox GtkTable GtkPanel 这类容器通常称为布局
  • 358.
    事件、信号和回调函数 GUI 库有一个共同点:必须有某种机制响应用户动作以执行代码命令行程序的做法:就是暂停执行,等待用户输入,然后采用 switch 语句等机制使程序根据输入不同而分支执行 GUI 程序:由事件和事件监听器系统来解决问题
  • 359.
    GTK+ 有自己的事件和事件监听器系统,叫做信号( signal)和回调函数( callback ) GTK+ 信号:当某事件发生时 GtkObject 对象发出的数据 回调函数:与信号相连接,一旦信号发出就会被调用的函数。
  • 360.
    控制权的传递是使用“信号”的办法来完成的 有所有构件都继承的信号,如“ destroy” ,有构件专有的信号,如开关 (toggle) 按钮发出的 “ toggled” 信号
  • 361.
    连接回调函数 要使一个按钮执行一个动作,我们需设置信号和信号处理函数之间的连接 g_signal_connect(gpointer*object,const gchar *name,GCallback func,gpointer user_data) 第一个参数是要发出信号的构件,第二个参数是你想要连接的信号的名称,第三个参数是信号被捕获时所要调用的函数,第四个参数是你想传递给这个函数的数据 连接回调函数没有任何限制,可以将多个信号连接到一个回调函数,也可以将多个回调函数连接到一个信号
  • 362.
    回调函数的原型 void a_callback_function(GtkWidget*widget,gpointer user_data) 两个参数:第一个是指向发出信号的窗口部件的指针,第二个是将回调函数与信号连接时定义的任一个指针
  • 363.
    GtkWindow GtkWidget *gtk_window_new(GtkWindowType type) void gtk_window_set_title(GtkWindow *window,const gchar *title) Void gtk_window_set_position(GtkWindow *window,GtkWindowPosition position) Void gtk_window_set_default_size(GtkWindow *window,gint width,gint height) Void gtk_window_resize(GtkWindow *window,gint width,gboolean resizable) Void gtk_windwo_set_resizable(GtkWindow *window,gboolean resizebale)
  • 364.
    gtk_window_set_position 值 GTK_WIN_POS_NONE 位置由窗口管理器决定 GTK_WIN_POS_CENTER GTK_WIN_POS_MOUSE GTK_WIN_POS_CENTER_ALWAYS GTK_WIN_POS_CENTER_ON_PARENT( 对话框有用 )
  • 365.
    GtkEntry—— 单行文字输入框 GtkWidget* gtk_entry_new(void) GtkWidget * gtk_entry_new_width_max_length(gint max) Void gtk_entry_set_max_length(GtkEntry *entry,gint max) G_CONST_RETURN gchar* gtk_entry_get_text(GtkEntry *entry) void gtk_entry_set_text(GtkEntry *entry,const gchar *text) void gtk_entry_append_text(GtkEntry *entry,const gchar *text) void gtk_entry_prepend_text(GtkEntry *entry,const gchar *text)
  • 366.
    hbox vbox 组装部件创建一个新的横向盒我们调用 gtk_hbox_new() ,对于纵向盒,用 gtk_vbox_new() gtk_box_pack_start() 将对象从上到下组装到纵向盒中,或者从左到右组装到横向盒中 gtk_box_pack_end() 则相反,从下到上组装到纵向盒中,或者从右到左组装到横向盒中
  • 367.
    GtkWidget* gtk_hbox_new(gboolean homogeneous,gintspacing) GtkWidget* gtk_vbox_new(gboolean homogeneous,gint spacing) Homogeneous 是布尔值,如果为 TRUE ,则强制每个窗口部件都占据相同大小的空间, spacing 设置窗口部件间距像素值
  • 368.
    Void gtk_box_pack_start(GtkWidget *box,GtkWidget*child,gboolean expand,gboolean fill,guint padding) Void gtk_box_pack_start(GtkWidget *box,GtkWidget *child,gboolean expand,gboolean fill,guint padding) 参数: 第一个:将被填充的包装盒 第二个:填入包装盒的部件 第三个:如果为 TRUE ,则窗口部件填充与其他标志为 TRUE 的窗口部件共享的可用空间 第四个:如果为 TRUE ,则这个窗口部件填满分配给它的空间,而不是在边缘垫衬,只有 expand 为 TRUE 时才有效 第五个:窗口部件周围垫衬的大小像素值
  • 369.
    应用容器的 Gtk +程序程序界面 btn_quit btn_start btn_go label entry text+scroll_win window
  • 370.
    应用容器的 Gtk +程序程序源文件目录组织 guess.c 定义主函数的地方 functions funtion.h 其它函数的头文件 function.c 其它函数的实现文件 当前工作目录 ./
  • 371.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 372.
  • 373.
  • 374.
    #include <gtk/gtk.h> #include<stdio.h> #include <string.h> const char * password=&quot;secret&quot;; void closeApp(GtkWidget *window,gpointer data){ gtk_main_quit(); } void button_clicked(GtkWidget *window,gpointer data){ const char *password_text=gtk_entry_get_text(GTK_ENTRY((GtkWidget *)data)); if (strcmp(password_text,password)==0) printf(&quot;Access granted!\n&quot;); else printf(&quot;Access denied!\n&quot;); }
  • 375.
    int main(int argc,char*argv[]){ GtkWidget *window; GtkWidget *username_label,*password_label; GtkWidget *username_entry,*password_entry; GtkWidget *ok_button; GtkWidget *hbox1,*hbox2; GtkWidget *vbox; gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window),&quot;GtkEntryBox&quot;); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),200,200); g_signal_connect(GTK_OBJECT(window),&quot;destroy&quot;,GTK_SIGNAL_FUNC(closeApp),NULL);
  • 376.
    username_label=gtk_label_new(&quot;Login:&quot;); password_label=gtk_label_new(&quot;Password:&quot;); username_entry=gtk_entry_new(); password_entry=gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(password_entry),FALSE); ok_button=gtk_button_new_with_label(&quot;OK&quot;); g_signal_connect(GTK_OBJECT(ok_button),&quot;clicked&quot;,GTK_SIGNAL_FUNC(button_clicked),password_entry); hbox1=gtk_hbox_new(TRUE,5); hbox2=gtk_hbox_new(TRUE,5); vbox=gtk_vbox_new(FALSE,10); gtk_box_pack_start(GTK_BOX(hbox1),username_label,TRUE,FALSE,5); gtk_box_pack_start(GTK_BOX(hbox1),username_entry,TRUE,FALSE,5); gtk_box_pack_start(GTK_BOX(hbox2),password_label,TRUE,FALSE,5); gtk_box_pack_start(GTK_BOX(hbox2),password_entry,TRUE,FALSE,5); gtk_box_pack_start(GTK_BOX(vbox),hbox1,FALSE,FALSE,5); gtk_box_pack_start(GTK_BOX(vbox),hbox2,FALSE,FALSE,5); gtk_box_pack_start(GTK_BOX(vbox),ok_button,FALSE,FALSE,5); gtk_container_add(GTK_CONTAINER(window),vbox); gtk_widget_show_all(window); gtk_main(); return 0; }
  • 377.
    GtkButton GtkButton GtkToggleButtonGtkCheckButton GtkRadioButton
  • 378.
    #include <gtk/gtk.h> #include<stdio.h> GtkWidget *togglebutton; GtkWidget *checkbutton; GtkWidget *radiobutton1,*radiobutton2; void closeApp(GtkWidget *window,gpointer data) { gtk_main_quit(); } void add_widget_with_label(GtkContainer *box,gchar *caption,GtkWidget *widget) { GtkWidget *label=gtk_label_new(caption); GtkWidget *hbox=gtk_hbox_new(TRUE,4); gtk_container_add(GTK_CONTAINER(hbox),label); gtk_container_add(GTK_CONTAINER(hbox),widget); gtk_container_add(box,hbox); }
  • 379.
    void print_active(char *button_name,GtkToggleButton*button) { gboolean active=gtk_toggle_button_get_active(button); printf(&quot;%s is %s\n&quot;,button_name,active?&quot;active&quot;:&quot;not active&quot;); } void button_clicked(GtkWidget *button,gpointer data) { print_active(&quot;Checkbutton&quot;,GTK_TOGGLE_BUTTON(checkbutton); print_active(&quot;Togglebutton&quot;,GTK_TOGGLE_BUTTON(togglebutton); print_active(&quot;Radiobutton1&quot;,GTK_TOGGLE_BUTTON(radiobutton1); print_active(&quot;Radiobutton2&quot;,GTK_TOGGLE_BUTTON(radiobutton2); printf(&quot;\n&quot;); }
  • 380.
    gint main(gint argc,gchar*argv[]) { GtkWidget *window; GtkWidget *button; GtkWidget *vbox; gtk_init(&argc,&argv); window=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),200,200); g_signal_connect(GTK_OBJECT(window),&quot;destroy&quot;,GTK_SIGNAL_FUNC(closeApp),NULL); button=gtk_button_new_with_label(&quot;OK&quot;); togglebutton=gtk_toggle_button_new_with_label(&quot;Toggle&quot;); checkbutton=gtk_check_button_new(); radiobutton1=gtk_radio_button_new(NULL); radiobutton2=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(radiobutton1));
  • 381.
    vbox=gtk_vbox_new(TRUE,4); add_widget_with_label(GTK_CONTAINER(vbox),&quot;ToggleButton:&quot;,togglebutton); add_widget_with_label(GTK_CONTAINER(vbox),&quot;CheckButton:&quot;,checkbutton);add_widget_with_label(GTK_CONTAINER(vbox),&quot;Radio 1:&quot;,radiobutton1); add_widget_with_label(GTK_CONTAINER(vbox),&quot;Radio 2:&quot;,radiobutton2); add_widget_with_label(GTK_CONTAINER(vbox),&quot;Button:&quot;,button); g_signal_connect(GTK_OBJECT(button),&quot;clicked&quot;,GTK_SIGNAL_FUNC(button_clicked),NULL); gtk_container_add(GTK_CONTAINER(window),vbox); gtk_widget_show_all(window); gtk_main(); return 0; }
  • 382.
    程序的参数处理 Shell 脚本程序使用$0,$1 接收参数 C 程序: int main(int argc,char *argv[]) argc 是程序参数的个数, argv 是代表参数自身的字符串数组 如果不声明 argc , argv ,就不能使用
  • 383.
    Shell 接收用户输入的命令行,将命令行分解成单词,然后把单词放入 argv数组 如 myapp left right ‘and center’ argc : 4 argv : {“myapp”,”left”,”right”,”and center”} 参数个数包括程序自身名称
  • 384.
    命令行选项 ls –l–s –t –r df –m 命令行开关都应以一个短横线开头,包含单个字母或数字
  • 385.
  • 386.
    利用 getopt 函数处理命令行选项getopt 是 linux 的函数,它支持需要关联值和不需要关联值的选项 Int getopt(int argc,char *const argv[],const char *optstring) *optstring 是选项指定字符串,告诉 getopt 哪些选项可用,以及每个选项是否有关联值 optstring 每个字符代表一个单字符选项,如果一个字符后面紧跟一个冒号,则表明选项有关联值
  • 387.
    getopt (argc , argv ,” if:lr” ) 该函数返回值是 argv 数组的下一个选项字符 如果选项有关联值,则外部变量 optarg 指向这个值 如果选项处理完毕, getopt 返回 -1 ,特殊参数 - - 使函数停止 如果遇到无法识别的选项,返回一个?号,并把它保存在外部变量 optopt 中 如果选项要求关联值,但未提供该值,则返回:
  • 388.
  • 389.
    时间和日期 所有的 unix系统都使用同一个时间和日期的起点:格林尼治时间( GMT ) 1970 年 1 月 1 日 0 点,这是 unix 纪元的起点, linux 也不例外 Linux 系统中所有的时间都以从那时起经过的秒数来衡量 MS-DOS 也是类似,只是它的纪元始于 1980 年
  • 390.
    时间通过一个预定义的类型 time_t 处理,是长整数#include <time.h> time_t time(time_t *tloc)
  • 391.
    #include <time.h> #include<stdio.h> #include <unistd.h> int main() { int i; time_t thetime; for (i=1;i<=10;i++) { thetime=time((time_t *)0); printf(&quot;the time is %ld \n&quot;,thetime); sleep(2); } exit(0); }
  • 392.
    gmtime 函数 structtm *gmtime(const time_t timeval) tm 的结构 Int tm_sec Int tm_min Int tm_hour Int tm_mday Int tm_mon Int tm_year Int tm_wday 星期几 Int tm_yday Int tm_isdst 是否夏令时
  • 393.
    #include <time.h> #include<stdio.h> int main() { struct tm *tm_ptr; time_t thetime; (void)time(&thetime); tm_ptr=gmtime(&thetime); printf(&quot;raw time is %ld \n&quot;,thetime); printf(&quot;gmtime gives:\n&quot;); printf(&quot;date: %02d/%02d/%02d\n&quot;,tm_ptr->tm_year,tm_ptr->tm_mon+1,tm_ptr->tm_mday); printf(&quot;time: %02d:%02d:%02d\n&quot;,tm_ptr->tm_hour,tm_ptr->tm_min,tm_ptr->tm_sec); exit(0); }
  • 394.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 395.
    临时文件 程序经常利用一些文件形式的临时存储手段 必须确保应用程序为临时文件选取的文件名是唯一的,否则linux 是一个多任务的系统,另一个程序就可能选择同样的文件名,导致两个程序互相干扰
  • 396.
    tmpnam tmpnam 函数可以生成唯一的文件名#include <stdio.h> char *tmpnam(char *s) 该函数返回一个不与任何已存在文件同名的有效文件名,如果字符串 s 不为空,文件名会写入它
  • 397.
    tmpfile 如果需要立刻使用临时文件,可以用 tmpfile函数在给它命名的同时打开它 由于别的程序可能会创建出一个与 tmpnam 返回的文件名同名的文件,所以 tmpfile 很有用 该函数返回一个文件流指针,以读写方式打开临时文件 FILE *tmpfile(void)
  • 398.
  • 399.
    用户信息 用户都有一个唯一的标识符 UIDLinux 运行的每一个程序实际上都是被某一个用户运行的,因此都有一个关联的 UID
  • 400.
    用户 UID 信息#include <sys/types.h> #include <unistd.h> uid_t getuid(void); char *getlogin(void); UID 类型—— uid_t ,定义在 sys/types.h 中 getuid 返回程序关联的 UID ,它通常是启动程序的用户的 UID getlogin 函数返回与当前用户关联的登录名
  • 401.
    用户密码信息 #include <sys/types.h>#include <pwd.h> struct passwd *getpwuid(uid_t uid); struct passwd *getpwnam(const char *name); 以上两函数返回一个指针,指向与某个用户对应的 passwd 结构
  • 402.
    Passwd 结构 Char*pw_name 用户登录名 Uid_t pw_uid UID 编号 Gid_t pw_gid gid 编号 Char *pw_dir 用户主目录 Char *pw_gecos 用户全名 Char *pw_shell 用户默认 shell
  • 403.
  • 404.
    主机信息 主机名 #include<unistd.h> int gethostname(char *name,size_t namelen); 该函数把主机名写入 name 字符串,该字符串至少有 namelen 个字符长,成功就返回 0 ,否则返回 -1
  • 405.
    主机信息 通过 uname获得更多主机信息 #include <sys/utsname.h> int uname(struct utsname *name); uname 函数把主机信息写入 name 参数指向的结构,结构包含成员: Char sysname[] 操作系统名 Char nodename[] 主机名 Char release[] 系统发行级别 Char version[] 系统版本号 Char machine[] 硬件类型
  • 406.
  • 407.
    日志 对于 linux系统,文件 /var/log/messages 包含所有系统日志信息 /var/log/mail 包含邮件系统日志信息 /var/log/debug 包含调试信息
  • 408.
    向系统发送日志信息 #include <syslog.h>#void syslog(int priority,const char *message,arguments …); Syslog 函数向系统的日志工具发送一条日志信息,每条信息有一个 priority 参数,该参数是一个严重级别与一个设施值的按位或。
  • 409.
    设施值 LOG_USER( 默认) LOG_LOCAL0 LOG_LOCAL1 … LOG_LOCAL7
  • 410.
    严重级别优先级递减排列 LOG_EMERG 紧急情况LOG_ALERT 高优先级故障,如数据库崩溃 LOG_CRIT 严重错误,如硬件故障 LOG_ERR 错误 LOG_WARNING 警告 LOG_NOTICE 需要注意的特殊情况 LOG_INFO 一般信息 LOG_DEBUG 调试信息
  • 411.
  • 412.
  • 413.
  • 414.
    Linux 内核可以进一步划分成 3 层。 最上面是系统调用接口,它实现了一些基本的功能,例如 read 和 write 。 系统调用接口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码。这些代码是 Linux 所支持的所有处理器体系结构所通用的。 在这些代码之下是依赖于体系结构的代码,构成了通常称为 BSP ( Board Support Package )的部分。这些代码用作给定体系结构的处理器和特定于平台的代码。
  • 415.
    linux 内核基本知识 内核组成(600 万行代码) 系统调用接口 进程管理 内存管理 虚拟文件系统 网络堆栈 设备驱动程序 硬件架构
  • 416.
  • 417.
    系统调用接口 SCI 层提供了某些机制执行从用户空间到内核的函数调用。这个接口依赖于体系结构,甚至在相同的处理器家族内也是如此。 SCI 实际上是一个非常有用的函数调用多路复用和多路分解服务。
  • 418.
    进程管理 进程管理的重点是进程的执行。在内核中,这些进程称为 线程,代表了单独的处理器虚拟化(线程代码、数据、堆栈和 CPU 寄存器)。在用户空间,通常使用 进程 这个术语,不过 Linux 实现并没有区分这两个概念(进程和线程)。
  • 419.
    内存管理 内核所管理的另外一个重要资源是内存。为了提高效率,如果由硬件管理虚拟内存,内存是按照所谓的 内存页 方式进行管理的(对于大部分体系结构来说都是 4KB )。 Linux 包括了管理可用内存的方式,以及物理和虚拟映射所使用的硬件机制。
  • 420.
    虚拟文件系统 虚拟文件系统( VFS)是 Linux 内核中非常有用的一个方面,因为它为文件系统提供了一个通用的接口抽象。 VFS 在 SCI 和内核所支持的文件系统之间提供了一个交换层
  • 421.
    网络堆栈 网络堆栈在设计上遵循模拟协议本身的分层体系结构。回想一下, InternetProtocol (IP) 是传输协议(通常称为传输控制协议或 TCP )下面的核心网络层协议。 TCP 上面是 socket 层,它是通过 SCI 进行调用的。
  • 422.
    设备驱动程序 Linux 内核中有大量代码都在设备驱动程序中,它们能够运转特定的硬件设备。 Linux 源码树提供了一个驱动程序子目录,这个目录又进一步划分为各种支持设备,例如 Bluetooth 、 I2C 、 serial 等。
  • 423.
    依赖体系结构的代码 尽管 Linux 很大程度上独立于所运行的体系结构,但是有些元素则必须考虑体系结构才能正常操作并实现更高效率。
  • 424.
    Linux 系统应用与程序设计主讲:邝颖杰 电邮: [email_address]
  • 425.
  • 426.
    Linux 、类 unix基本常识 什么是 linux Linux 的特性 GNU 、 GPL 概念 Linux 的版本 Linux 各个目录的意义
  • 427.
    Linux 的一些基本指令 附录B 知道各个指令是什么意思 重点是文件与目录操作指令、用户及用户组指令、网络检测指令 关闭系统、启动系统、重启系统
  • 428.
    Shell ( *) 什么是 shell 常用的 shell 有哪些 Shell 处于 linux 系统的哪个模块 如何指定用户使用某个 shell
  • 429.
  • 430.
    Linux 文件( *) 文件属性,如何修改,如何计算 有多少种文件类型,如何辨别 P23 硬链接、软链接 P31
  • 431.
    挂载的概念 文件系统类型 虚拟文件系统结构(* ) 磁盘在 linux 下的标识 如何挂载 U 盘
  • 432.
    如何配置机器的 ip ,如何查看网络相关配置文件有哪些,有何作用 ftp 服务配置、启动、停止 telnet 服务配置、启动、停止 Xinetd 服务配置、启动、停止 守护进程概念原理( * ) 网络服务独立模式与 xinetd 模式区别( * )
  • 433.
    Shell 编程( *) 变量:自定义的变量、环境变量 程序结构:条件判断( * )、循环结构( * )、函数 如何执行 文件属性的判断、字符串属性和整数关系的判断 写过的程序( * )
  • 434.
    Xwindow 概念 原理(* ) 有哪些 xwindow
  • 435.
    进程、父进程、子进程、程序概念 Cron 的使用(* ) Grep 命令的使用 Awk 命令的使用
  • 436.
    Gcc 概念( *):各个选项的意义 各个阶段的编译及生成的文件 Makefile ( * ) Gtk+ 概念 如何开发 gtk+ 的程序 如何布局
  • 437.
    补充的知识: 获取程序参数 时间函数的使用临时文件 用户信息 主机信息 日志信息
  • 438.
  • 439.
    cron 实验答案:  023 * * * /root/startftp 0  3 * * * /root/stopftp 脚本 startftp : /usr/sbin/vsftpd start sleep 2 tmp=`ps -ef | grep vsftp |grep -v grep |awk '{print $2}'` if [ -n $tmp ] then    echo `ps -ef | grep vsftp |grep -v grep`  >> mylog else    echo &quot;ftp start error&quot; >> mylog fi exit 0 同理,可写出 stopftp