Linux系统管理linux
Linux与Linux之间经过NFS(network file system)实现共享;
windows与windows之间经过共享目录实现共享;
Linux与windows之间经过Samba实现共享。
Wireshark抓包软件,分析网络协议。
shell编程:
1)#!/bin/bash ,符号#!用来指定该脚本文件的解析程序。
2)# 开头表示该行是注释。
3)全部变量都是由字符串组成,而且不须要预先对变量进行声明。使用变量需在变量名前$。有时候变量名很容易与其余文字混淆,这时须要用{}将变量名括起来。
4)默认变量:
$#:传入脚本的命令行参数个数
$*:全部命令行参数值,在各个参数之间留有空格
$0:命令自己(shell文件名)
$1:第一个命令行参数
$2:第二个命令行参数
5)局部变量,在变量首次赋值时加local能够声明一个局部变量。
6)变量注意事项:
变量赋值时“=”号左右两边都不能空格
语句结尾不加“;”
7)if语句
if [ expression ]
then
#code block
fi
if [ expression ]
then
#code block
else
#code block
fi
比较操做 整数 字符串
相同 -eq =
不一样 -ne !=
大于 -gt >
小于 -lt <
小于等于 -le
大于等于 -ge
为空 -z
不为空 -n
注意:
在“[”和“]”符号的左右都留有空格
“=”左右都有空格
判断:
-e 文件已经存在
-f 文件是普通文件
-s 文件大小不为0
-d 文件是一个目录
-r 文件对当前用户能够读取
-w 文件对当前用户能够写入
-x 文件对当前用户能够执行
8)for循环和while循环
for var in [list]
do
# code
done
注意:
for所在那行变量是没有加“$”的,而在循环体内,变量是要加“$”的
list若是用“”括起来是被看成一个值赋给var
while [ condition ]
do
#code
done
until [ condition ] 条件为假时执行
do
#code
done
9)case语句
case "$var" in
condition1)
;;
condition2)
;;
*)
#default statments;;
esac程序员
gcc学习算法
Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大、性
能优越的多平台编译器,是GNU的表明做之一。gcc能够在多种硬体平台上编译出可执行程序,其执行效率与通常的编译器相比平均效率要高20%~30%。
GCC编译器能将C,C++语言源程序,汇编程序编译,连接成可执行文件。Linux经过属性来决定文件的可执行性。
GCC编译4个阶段:
预处理(pre-processing),编译(compling),汇编(assembing),
连接(linking)
处理的输入文件类别:.c.a.C.h.i.ii.o.s.S
gcc最基本的用法是:
gcc [options] [filename]
options:
-o output_filename:指定输出的可执行文件名称。
-c:只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件。
-g:产生调试工具(GNU的gdb)所必要的符号信息,要想对编译出的程序进行调试,就必须加入这个选项。
-O:对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、链接过程当中进行优化处理,这样产生的可执行文件的执行效率能够提升,可是,编译、链接的速度就相应地要慢一些。
-O2,比-O更好的优化编译、链接,固然整个编译、链接过程会更慢。
-I dirname: 将dirname所指出的目录加入到程序头文件目录列表
中。C程序中的头文件包含两种状况∶
#include <A.h>和#include “B.h”对于<>,预处理程序cpp在系统预设的头文件目录(如/usr/include)中搜寻相应的文件;而对于””,cpp在当前目 录中搜寻头文件。这个选项的做用是告诉cpp,若是在当前目录
中没有找到须要的文件,就到指定的dirname目录中去寻找。
-L dirname:将dirname所指出的目录加入到库文件的目录列表中。在默认状态下,链接程序ld在系统的预设路径中(如/usr/lib)寻找所须要的库文件,这个选项告诉链接程序,首先到-L指定的目录中去寻找,而后再到系统预设路径中寻找。
-l name:在链接时,装载名字为“libname.a”的函数库,该函数库位于
系统预设的目录或者由-L选项肯定的目录下。例如,-l m表示链接名为
“libm.a”的数学函数库。
-static:静态连接库文件 例:gcc –static hello.c -o hello
库有动态与静态两种,动态一般用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a。当使用静态库时,链接器找出程序所需的函数,而后将它们拷贝到可执行文件,一旦链接成功,静态程序库也就再也不须要了。然 而,对动态库而言,就不是这样,动态库会在执行程序内留下一个标记‘指明当程序执行时,首先必须载入这个库。因为动态库节省空间,linux下进行链接的 缺省操做是首先链接动态库。
-Wall:生成全部警告信息
-w:不生成任何警告信息
-DMACRO: 定义 MACRO 宏,等效于在程序中使用#define MACROshell
GDB程序调试express
GDB是GNU发布的一款功能强大的程序调试工具。GDB主要完成下面三个方面的功能:编程
一、启动被调试程序。windows
二、让被调试的程序在指定的位置停住。数组
三、当程序被停住时,能够检查程序状态bash
(如变量值)。网络
GDB调试的通常步骤:
1.编译生成可执行文件:
gcc -g tst.c -o tst
2.启动GDB
gdb tst
3. 在main函数处设置断点
break main
4. 运行程序
run
5. 单步运行
next
6. 继续运行
continue
经常使用GDB命令:
list(l) 查看程序
break(b) 函数名 在某函数入口处添加断点
break(b) 行号 在指定行添加断点
break(b) 文件名:行号在指定文件的指定行添加断点
break(b) 行号 if 条件当条件为真时,指定行号处断点生效,例b 5 if i=10,当i等于10时第5行断点生效
info break 查看全部设置的断点
delete 断点编号 删除断点
run(r) 开始运行程序
next(n) 单步运行程序(不进入子函数)
step(s) 单步运行程序(进入子函数)
continue(c) 继续运行程序
print(p) 变量名 查看指定变量值
finish 运行程序,直到当前函数结束
watch 变量名 对指定变量进行监控
quit(q) 退出gdb
Makefile工程管理
Linux程序员必须学会使用GNU make来构建和管理本身的软件工程。GNU 的make可以使整个软件工程的编译、连接只须要一个命令就可
以完成。
make在执行时, 须要一个命名为Makefile的文件。Makefile文件描述了整个工程的编译,链接等规则。其中包括:工程中的哪些源文件须要编译以及如何编译;须要建立那些库文件以及如何建立这些库文件、如何最后产生咱们想要得可执行文件。
makefile规则:用于说明如何生成一个或多个目标文件,
规则格式以下:
targets :prerequisites
command
目标 依赖 命令
main.o : main.c
gcc –c main.c
**命令须要以【TAB】键开始**
目标:在Makefile 中,规则的顺序是很重要的,由于,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,因此必定要让make知道你的最终目 标是什么。通常来讲,定义在Makefile中的目标可能会有不少,可是第一条规则中的目标将被确立为最终的目标。
文件名:make命令默认在当前目录下寻找名字为makefile或者Makefile的工程文件,当名字不为这二者之一时,可使用以下方法指定:
make –f 文件名
伪目标:Makefile中把那些没有任何依赖只有执行动做的目标称为“伪目标”(phony targets)。
.PHONY : clean
clean :
rm –f hello main.ofunc1.o func2.o
“.PHONY” 将“clean”目标声明为伪目标。
变量的使用:obj=main.o func1.o func2.o func3.o
hello: $(obj)
gcc $(obj) -o hello
在makefile中,存在系统默认的自动化变量
$^:表明全部的依赖文件
$@:表明目标
$<:表明第一个依赖文件
Makefile中“#”字符后的内容被视做注释。
@:取消回显
hello: hello.c
@gcc hello.c –ohello
linux文件编程
Linux系统调用
系统调用-建立
int creat(const char*filename,mode_t mode)
vfilename:要建立的文件名(包含路径,缺省为当前路径)
vmode:建立模式,常见建立模式:
S_IRUSR 可读
S_IWUSR 可写
S_IXUSR 可执行
S_IRWXU 可读、写、执行
除了可使用上述宏之外,还能够直接使用数字来表示文件的访问权限:
v可执行 -> 1
v可写 -> 2
v可读 -> 4
v上述值的和,如可写可读 -> 6
v无任何权限 -> 0
文件描述
在Linux系统中,全部打开的文件都对应一个文件描述符。文件描述符的本质是一个非负整数。当打开一个文件时,该整数由系统来分
配。文件描述符的范围是0 - OPEN_MAX 。早期的UNIX版本OPEN_MAX =19,即容许每一个进程同时打开20个文件,如今不少系统则将其增长至1024。
系统调用-打开
int open(const char*pathname, int flags)
int open(const char*pathname, int flags,mode_t mode)
pathname:要打开的文件名(包含路径,缺省为当前路径)
flags:打开标志,常见的打开标志:
O_RDONLY 只读方式打开
O_WRONLY 只写方式打开
O_RDWR 读写方式打开
O_APPEND 追加方式打开
O_CREAT 建立一个文件
O_NOBLOCK 非阻塞方式打开
若是使用了O_CREATE标志,则使用的函数是:
int open(const char*pathname,int flags,mode_t mode);
这时须要指定mode来表示文件的访问权限。
当咱们操做完文件之后,须要关闭文件:
int close(int fd) ,fd: 文件描述符
系统调用-读
int read(int fd,const void *buf, size_t length)
功能:从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。
系统调用-写
int write(int fd,const void *buf, size_t length)
功能:把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。
系统调用-定位
int lseek(int fd,offset_t offset, int whence)
功能:将文件读写指针相对whence移动offset个字节。操做成功时,返回文件指针相对于文件头的位置。
whence可以使用下述值:
SEEK_SET:相对文件开头
SEEK_CUR:相对文件读写指针的当前位置
SEEK_END:相对文件末尾
offset可取负值,表示向前移动。例以下述调用可将文件指针相对当前位置向前移动5个字节:
lseek(fd, -5,SEEK_CUR)
因为lseek函数的返回值为文件指针相对于文件头的位置,所以下面调用的返回值就是文件的长度:
lseek(fd, 0,SEEK_END)
系统调用-访问判断
有时咱们须要判断文件是否能够进行某种操做(读,写
等),这时可使用access函数:
int access(constchar*pathname,int mode)
pathname:文件名称
mode:要判断的访问权限。能够取如下值或者是他们的组合。R_OK:文件可读,W_OK:文件可写,X_OK:文件可执行,F_OK文件存在。
返回值:当咱们测试成功时,函数返回0,不然若是一个条件不符时,返回-1。
C语言库函数
C库函数的文件操做是独立于具体的操做系统平台的,无论是在DOS、Windows、Linux仍是在VxWorks中都是这些函数。
库函数-建立和打开
FILE *fopen(constchar *filename, const char *mode)
filename:打开的文件名(包含路径,缺省为当前路径)
mode:打开模式
常见打开模式:
r, rb 只读方式打开
w, wb 只写方式打开,若是文件不存在,则建立该文件
a, ab 追加方式打开,若是文件不存 在,则建立该文件
r+, r+b, rb+读写方式打开
w+, w+b, wh+ 读写方式打开,若是文件不存在,则建立该文件
a+, a+b, ab+读和追加方式打开。若是文件不存在,则建立该文件
b用于区分二进制文件和文本文件,这一点在DOS、Windows系统中是有区分的,但Linux不区分二进制文件和文本文件。
库函数-读
size_t fread(void*ptr, size_t size, size_t n, FILE *stream)
功能:从stream指向的文件中读取n个字段,每一个字段为size字节,并将读取的数据放入ptr所指的字符数组中,返回实际已读取的字节数。
库函数-写
size_t fwrite (constvoid *ptr, size_t size, size_t n,FILE *stream)
功能:从缓冲区ptr所指的数组中把n个字段写到stream指向的文件中,每一个字段长为size个字节,返回实际写入的字段数。
库函数-读字符
int fgetc(FILE*stream)
库函数-写字符
int fputc(int c,FILE *stream)
库函数-格式化读
fscanf(FILE *stream,char *format[,argument...])
从一个流中进行格式化输入,fscanf(stdin, "%d", &i)
库函数-格式化写
int fprintf(FILE*stream, char* format[,argument,...])
格式化输出到一个流中,printf( stream, "%d\n", i );
库函数-定位
int fseek(FILE*stream, long offset, int whence)
whence :
SEEK_SET 从文件的开始处开始搜索
SEEK_CUR 从当前位置开始搜索
SEEK_END 从文件的结束处开始搜索
路径获取
在编写程序的时候,有时候须要获得当前路径。C库函数提供了getcwd来解决这个问题。
char *getcwd(char*buffer,size_t size)
咱们提供一个size大小的buffer,getcwd会把当前的路径名copy 到buffer中.若是buffer过小,函数会返回-1。
建立目录
#include<sys/stat.h>
int mkdir(char *dir, int mode)
功能:建立一个新目录。
返回值:0表示成功,-1表述出错。
linux时间编程
时间类型
CoordinatedUniversal Time(UTC):世界标准时间,也就是你们所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。
Calendar Time:日历时间,是用“从一个标准时间点(如:1970年1月1日0点)到此时通过的秒数”来表示的时间。
时间获取
#include<time.h>
time_t time(time_t*tloc)
功能:获取日历时间,即从1970年1月1日0点到如今所经历的秒数。
/* typedef longtime_t */
时间转化
struct tm*gmtime(const time_t *timep)
功能:将日历时间转化为格林威治标准时间,并保存至TM结构。
struct tm*localtime(const time_t *timep)
功能:将日历时间转化为本地时间,并保存至TM结构。
时间保存
struct tm {
int tm_sec; //秒值
int tm_min;
//分钟值
int tm_hour; //小时值
int tm_mday; //本月第几日
int tm_mon;
//本年第几月
int tm_year;//tm_year + 1900 = 哪一年
int tm_wday; //本周第几日
int tm_yday; //本年第几日
int tm_isdst; //日光节约时间
};
时间显示
char *asctime(conststruct tm *tm)
功能:将tm格式的时间转化为字符串,如: Sat Jul 30 08:43:03 2005
char *ctime(consttime_t *timep)
功能:将日历时间转化为本地时间的字符串形式。
获取时间
intgettimeofday(struct timeval *tv,struct timezone *tz)
功能:获取从今日凌晨到如今的时间差,经常使用于计算事件耗时。
struct timeval {
int tv_sec; //秒数
int tv_usec; //微妙数
};
延时执行
unsigned intsleep(unsigned int seconds)
功能:使程序睡眠seconds秒。
void usleep(unsignedlong usec)
功能:使程序睡眠usec微秒。
进程控制
进程控制理论
定义:
进程是一个具备必定独立功能的程序的一次运行活动。
特色:
动态性
并发性
独立性
异步性
状态
进程ID
进程ID(PID):标识进程的惟一数字
父进程的ID(PPID)
启动进程的用户ID(UID)
进程互斥
进程互斥是指当有若干进程都要使用某一共享资源时,任什么时候刻最多容许一个
进程使用,其余要使用该资源的进程必须等待,直到占用该资源者释放了该资源
为止。
临界资源
操做系统中将一次只容许一个进程访问的资源称为临界资源。
临界区
进程中访问临界资源的那段程序代码称为临界区。为实现对临界资源的互斥访
问,应保证诸进程互斥地进入各自的临界区。
进程同步
一组并发进程按必定的顺序执行的过程称为进程间的同步。具备同步关系
的一组并发进程称为合做进程,合做进程间互相发送的信号称为消息或事件。
进程调度
概念:
按必定算法,从一组待运行的进程中选出一个来占有CPU运行。
调度方式:
• 抢占式
• 非抢占式
调度算法:
先来先服务调度算法
短进程优先调度算法
高优先级优先调度算法
时间片轮转法
死锁
多个进程因竞争资源而造成一种僵局,若无外力做用,这些进程都将永
远不能再向前推动。
进程建立
获取ID
#include<sys/types.h>
#include<unistd.h>
pid_t getpid(void) 获取本进程ID。
pid_t getppid(void) 获取父进程ID。
进程建立-fork
#include<unistd.h>
pid_t fork(void)
功能:建立子进程
fork的奇妙之处在于它被调用一次,却返回两次,它可能有三种不一样的返回值:
1. 在父进程中,fork返回新建立的子进程的PID;
2. 在子进程中,fork返回0;
3. 若是出现错误,fork返回一个负值
在pid=fork()以前,只有一个进程在执行,但在这条语句执行以后,就变成两个
进程在执行了,这两个进程的共享代码段,将要执行的下一条语句都是if(pid==0)。
两个进程中,原来就存在的那个进程被称做“父进程”,新出现的那个进程被称做“子进程”,父子进程的区别在于进程标识符(PID)不一样。
子进程的数据空间、堆栈空间都会从父进程获得一个拷贝,而不是共享。在子
进程中对count进行加1的操做,并无影响到父进程中的count值,父进程中的
count值仍然为0。
进程建立-vfork
#include<sys/types.h>
#include<unistd.h>
pid_t vfork(void)
功能:建立子进程。
区别:
1. fork:子进程拷贝父进程的数据段
vfork:子进程与父进程共享数据段
2. fork:父、子进程的执行次序不肯定
vfork:子进程先运行,父进程后运行
exec函数族
exec用被执行的程序替换调用它的程序。
区别:
fork建立一个新的进程,产生一个新的PID。exec启动一个新程序,替换原有的进程,所以进程的PID不会改变。
#include<unistd.h>
intexecl(const char * path,const char * arg1, ....)
参数:
path:被执行程序名(含完整路径)。
arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。
例:execl.c
#include<unistd.h>
main()
{
execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char* )0);
}
#include<unistd.h>
intexeclp(const char * path,const char * arg1, ...)
参数:
path:被执行程序名(不含路径,将从path环境变量中查找该程序)。
arg1 – argn: 被执行程序所需的命令行参数,含程序名。以空指针(NULL)结束。
例:execlp.c
#include<unistd.h>
main()
{
execlp(”ls”,”ls”,”-al”,”/etc/passwd”,(char*)0);
}
#include<unistd.h>
int execv(const char * path, char * const argv[ ])
参数:
path:被执行程序名(含完整路径)。
argv[]: 被执行程序所需的命令行参数数组。
例:execv.c
#include<unistd.h>
main()
{
char * argv[]={“ls”,”-al”,”/etc/passwd”,(char*)0};
execv(“/bin/ls”,argv);
}
#include<stdlib.h>
intsystem( const char* string )
功能:
调用fork产生子进程,由子进程来调用/bin/sh -c string来执行参数string所表明
的命令。
例:system.c
#include<stdlib.h>
void main()
{
system(“ls -al/etc/passwd”);
}
进程等待
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait (int *status)
功能:阻塞该进程,直到其某个(任意)子进程退出。
进程通讯
概述
为何进程间须要通讯?
一、数据传输
一个进程须要将它的数据发送给另外一个进程。
二、资源共享
多个进程之间共享一样的资源。
三、通知事件
一个进程须要向另外一个或一组进程发送消息,通知它们发生了某种事件。
四、进程控制
有些进程但愿彻底控制另外一个进程的执行(如Debug进程),此时控制进程但愿可以拦截另外一个进程的全部操做,并可以及时知道它的状态改变。
Linux进程间通讯(IPC)由如下几部分发展而来:
一、UNIX进程间通讯
二、基于System V进程间通讯
三、POSIX进程间通讯
POSIX(PortableOperating System Interface)表示可移植操做系统接口。电气和电子工程师协会(Institute of Electrical and ElectronicsEngineers,IEEE)最初开发 POSIX 标准,是为了提升 UNIX 环境下应用程序的可移植性。然而,POSIX 并不局限于 UNIX,许多其它的操做系统,例如 DEC OpenVMS 和 Microsoft Windows,都支持 POSIX 标准。
System V,也被称为 AT&T System V,是Unix操做系统众多版本中的一支。
如今Linux使用的进程间通讯方式包括:
一、管道(pipe)和有名管道(FIFO)
二、信号(signal)
三、消息队列
四、共享内存
五、信号量
六、套接字(socket)
管道通讯
什么是管道?
管道是单向的、先进先出的,它把一个进程的输出和另外一个进程的输入链接在一块儿。一个进程(写进程)在管道的尾部写入数据,另外一个进程(读进程)从管道的头部读出数据。
数据被一个进程读出后,将被从管道中删除,其它读进程将不能再读到这些数据。管道提供了简单的流控制机制,进程试图读空管道时,进程将阻塞。一样,管道已经满时,进程再试图向管道写入数据,进程将阻塞。
管道建立
管道包括无名管道和有名管道两种,前者用于父进程和子进程间的通讯,后者可用于运行于同一系统中的任意两个进程间的通讯。
无名管道由pipe()函数建立:
int pipe(int filedis[2]);
当一个管道创建时,它会建立两个文件描述符:filedis[0] 用于读管道, filedis[1] 用于写管道。
关闭管道只需将这两个文件描述符关闭便可,可使用普通的close函数逐个关闭。
管道读写
管道用于不一样进程间通讯。一般先建立一个管道,再经过fork函数建立一个子进程,该子进程会继承父进程所建立的管道。
注意事项
必须在系统调用fork( )前调用pipe( ),不然子进程将不会继承文件描述符。
命名管道(FIFO)
命名管道和无名管道基本相同,但也有不一样点:无名管道只能由父子进程使用;可是经过命名管道,不相关的进程也能交换数据。
建立
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(constchar * pathname, mode_t mode)
pathname:FIFO文件名
mode:属性(见文件操做章节)
一旦建立了一个FIFO,就可用open打开它,通常的文件访问函数(close、read、write等)均可用于FIFO。
操做
当打开FIFO时,非阻塞标志(O_NONBLOCK)将对之后的读写产生以下影响:
一、没有使用O_NONBLOCK:访问要求没法知足时进程将阻塞。如试图读取空的FIFO,将致使进程阻塞。
二、使用O_NONBLOCK:访问要求没法知足时不阻塞,马上出错返回,errno是ENXIO。