Linux开发环境学习
Linux开发环境学习
基本命令
man
date "+%Y,%m,%d %H:%M:%S Day %j"
cal [[month] year]
bc // calculator
scale=x // set precision
who // user
tty // terminal
who am i
uptime // running time since start
top
vmstat // system load
ps // process status
free // system memory usage
file // view file data type
iconv -f encoding -t encoding file1 -o file2 // convert file encoding
文本文件处理
标准输入stdin
标准输出stdout
输出重定向: ls -l > test
输入重定向: sort < test
管道机制: ls -l | sort
- Read file
more/less: display files screen by screen
cat
od: (-c) // 逐字符打印,遇到不可打印则打印编码
(-t x1) // 十六进制打印
head/tail
tee // stdin -> stdout && file
eg: ./myap | tee myap.log
wc: (-l) // row count
sort
tr string1 string2
eg: cat file1 | tr % '\012'
uniq: (-u/-d/-c)
- Regular expression(text processing)
\ 转义
. 任意单字符
[- ^] 定义集合(区间定义 补集)
* 0次或任意多次
\$ ^ 锚点
扩展:
() 分组
| 或
+ ? 1次或多次 0次或1次
[[]] 预定义集合
- 文本行筛选
grep [regular expression] [filenames]
egrep [ERE] [filenames]
fgrep [string] [filenames]
- 流编辑
sed 'command' [filenames]
sed -e 'command1' -e 'command2' [filenames]
sed -f [command file] [filenames]
eg:"04-1997"->"1997.04"
command:s#\([0-9][0-9]\)-\([0-9][0-9]*\)#\2.\1#g
- 复杂筛选及加工,逐行扫描进行处理
awk 'program' [filenames]
awk -f [program] [filenames]
program: condition {action}
condition: /regexpr/
- 文件比对
cmp
md5sum/sha1sum
diff (-u)
- vi编辑器
文件系统管理
- 目录结构
/etc: 系统管理命令和配置文件
/tmp: 临时文件
/var: 经常变化的文件,如日志文件或数据库等
/bin: 系统常用命令
/usr/bin: 常用命令
/sbin, /usr/sbin: 系统管理员专用命令
/dev: 设备文件
/usr/include: C语言头文件
/lib, /usr/lib: C链接库文件
ls
cp: (-r/-u)(递归、增量)
cp file1 file2
cp file1 file2 ... dir
mv
mv file1 file2
mv file1 file2 ... dir
mv dir1 dir2
rm: (-r/-f/-i)(递归、强制、无确认)
pwd
cd
mkdir
rmdir: (empty dir)
find [range] [condition] [action]
condition: -name "wildcard"
-regex pattern
-type
-size +-n单位
-mtime +-ndays
-newer file
action: -print
-exec
-ok
- 打包与压缩
tar cvf /dev/rct0 . // 当前目录树备份到
tar tvf /dev/rct0 // 查看
tar xvf /dev/rct0 // 恢复
- 命令获取信息的方法
配置文件: bash(/etc/profile, ~/.bash_profile)
环境变量: env getenv()
命令行参数: param=value
交互式输入:
- 文件系统
创建文件系统: mkfs /dev/sdb
安装子文件系统: mount /dev/sdb /mnt
卸载子文件系统: umount /dev/sdb
df (-h): file system free space
- 文件系统存储结构
引导块+专用块+i节点区+文件存储区
i节点:索引指针+属性信息
文件存储区:用来存放文件数据的区域,包括目录表
目录项:文件名+i节点号
两级结构:i节点+目录项
stat:read i-node information
- 文件和目录的权限
权限的三个级别:文件主,同组用户,其他用户
普通文件的权限:读,写,可执行
目录的读写权限:针对目录表
创建删除重命名文件,会修改目录文件
修改文件不需要修改目录文件,仅是修改i节点
目录的执行权限:分析路径名过程中可检索该目录
STICKY权限(粘着位"t"):目录有写权限并且带STICKY属性,此目录下的文件仅文件主可以删除,其他用户删除操作会失败。
SUID权限:有限访问
chmod: modify permissions
chmod [ugoa][+-=][rwxst] [filenames]
chmod [Octal Number] [filenames]
umask:
umask 022(000 010 010): 取消新文件、目录的组w 权限和其他用户w权限
bash及脚本程序设计
shell是面向命令处理的语言
!!, !str, alias
新建子进程,执行脚本:bash<lsdir / bash lsdir / ./lsdir
在当前shell进程中执行脚本:. lsdir / source lsdir
- 重定向与管道
stdin输入:< filename
<< word (从shell脚本获取数据直到遇到定界符 word,允许替换)
<< 'word' (不允许替换)
<<< word (从命令行获取信息作为标准输入)
stdout输出:> filename (覆盖)
>> filename (追加)
stderr输出:> filename
2>&1
eg. ./stda 1> try.out 2> /dev/null
./stda >rpt 2>&1
- 变量
赋值:city="beijing"(不允许=两边有空格)
引用:$addr / ${addr}
echo (-e)
printf
read
export: 局部变量转换为环境变量
(shell子进程继承环境变量,不继承局部变量)
set/env
- 替换,先替换再执行(文件名生成,变量替换,命令替换)
命令替换:``, $() (以命令的stdout替换)
eg. now=`date` / now=$(date)
位置参数:
eg. $0, $1, $2, $#, "$*", "$@", shift
- shell元字符与转义
eg. ><| ; & $ `` * [] ? \ ()
\: 取消其后元字符的特殊作用
"": 除$和``外的特殊字符的特殊含义被取消
'': 对所括任何字符,不做特殊解释
- 条件
$?: 上一命令的返回码
&& ||: 短路计算
test / []: 文件特性检测, 字符串/整数比较
-f, -d, -r, -w, -x, -s
-eq, -ne, -gt, -ge, -lt, -le
- 命令组合
{ }: 在当前shell执行一组命令
(): 在子shell执行一组命令
- 条件分支
if condition
then list
elif condition
then list
else
list
fi
// if condition; then
- 多条件分支
case word in
pattern1) list1;; // 文件名匹配规则,|
pattern2) list2;;
...
esac
注释:#
expr:表达式运算
expr string : pattern
- while循环
while condition
do list
done
// for循环
for name in word1 word2 ...
do list
done
break / continue / exit
- 函数
name() { list;}
进程控制与进程间通信
进程和程序的关系:程序用来初始化进程的指令段和用户数据段,初始化后,进程和初始化他的程序之间无联系
-
进程的组成部分
指令段:程序编译后的CPU指令代码,以及调用的库函数代码
用户数据段:全局变量,静态变量,字符串常数
用户堆栈段:函数调用,参数
系统数据段:内核内的数据,每个进程对应一套,包括页表和进程控制块PCB、进程的属性。
PCB被分为user结构(进程运行时才需要的数据)和proc结构(进程不运行时也需要的管理信息) -
进程的基本状态
运行状态和睡眠状态(阻塞、等待、挂起) -
进程的调度
调度优先级 -
系统调用
times() \ getrusage()
time() \ gettimeofday() \ localtime() \ mktime() \ ctime() \ asctime()-
fork(创建新进程)
- 完全复制:新进程的指令,用户数据,堆栈段;部分复制:系统数据段
- 返回值:父进程(返回值>0,是子进程的PID),子进程(返回值=0),失败返回-1
- 内核实现:创建新的proc结构,复制父进程环境(包括user结构和内存资源)给子进程;父子进程可以共享程序和数据(copy-on-write),对程序员透明
-
ps(process status)
将内核中proc[]、user[]数组中内容有选择的打印)
进程属性:
C(CPU占用指数)
SZ(进程逻辑内存大小)
TIME(累计执行时间)
S(状态,S,R,Z(zombine:僵尸进程)) -
exec
用一个指定的程序文件初始化一个进程
不创建新进程,重新初始化一个进程(初始化指令段,用户数据段,堆栈段以及CPU的PC指针)
eg. int execvp(char *file, char ** argv)
6种格式exec系统调用:不同的参数方式初始化堆栈底部
l、v: 指定命令行的两种方式,l以表的形式,v要事先组织成一个指针数组
e: 需要指定envp来初始化进程
p: 使用环境变量PATH查找可执行文件 -
wait ( waitpid(), wait3() )
等待进程的子进程终止,销毁”僵尸“子进程 -
C语言库函数strtok
-
system: 运行一个命令
-
-
进程与文件描述符
磁盘文件目录分两级
活动文件目录分三级
-
文件描述符表FDT:每进程一张,PCB的user结构中
- user结构中整型数组u_ofile记录进程打开的文件
- 文件描述符fd是u_ofile数组的下标
-
系统文件表SFT:整个核心一张
struct file { char f_flag; // 读写操作要求 char f_count; // 引用计数 char f_offset; // 文件读写位置指针 char f_inode; // 内核inode数组的下标 }
-
活动i节点表:整个核心一张,inode结构
fork创建的子进程继承父进程的文件描述符表,父进程在fork前打开的文件,父子进程有相同的文件偏移
-
close-on-exec标志(文件描述符fd设置标志,执行exec系统调用,自动关闭文件)
int fcntl(fd, cmd, arg);
-
文件描述符的复制
int dup2(int fd1, int df2);
-
管道操作
- 创建一个管道,pfd[1],pfd[2]分别为管道两端的文件描述字(to read, to write)
int pipe(int pfd[2]);
- 管道写读
ret = write(pfd[1], buf, n) ret = read(pfd[0], buf, n)
-
关闭管道
关闭写端 读端read调用返回0;
关闭读端 写端write导致进程收到SIGPIPE信号 -
管道通信
- 管道传输是一个无记录边界的字节流
- 父子进程需要双向通信时,应采用两个管道
- 有可能死锁,只限于同祖先进程间通信
-
命名管道
允许不相干的进程(没有共同祖先)访问FIFO管道
-
-
信号
信号是送到进程的软件中断,通知进程出现了非正常事件。
进程对信号的处理:
-
信号被忽略
signal(SIGINT, SIG_IGN); // 忽略SIGINT信号
-
设置为缺省处理方式
signal(SIGINT, SIG_DFL);
-
信号被捕捉
signal(SIGINT, sig_hangle); // 信号被捕捉并由一个用户函数来处理
僵尸进程:
僵尸进程不占用内存资源但占用内核proc表项,僵尸进程太多会导致proc表耗尽而无法再创建新进程。
子进程终止,僵尸进程出现,系统像父进程发送信号SIGCLD,父进程使用wait系统调用收尸
命令kill:kill -signal PID-list
eg. PID=0时,向与本进程同组的所有进程发送信号
发送信号:
系统调用kill
int kill(int pid, int sig);// 0 / -1
进程睡眠
睡眠进程收到信号后处理
系统调用pause:等待信号,收到信号前一直睡眠
系统调用alarm:
#include <sys/signal.h> int alarm(int secs); // 进程报警时钟存贮在它内核系统数据中,报警时钟到时,进程收到SIGALRM信号。子进程继承父进程的报警时钟值,报警时钟在exec执行后保持这一设置。进程收到SIGALRM后默认终止进程。
-
-
进程间通信(IPC进制)
semaphore
策略与机制分离
P操作与V操作
int semget(int key, int nsems, int flags); int semctl(int sem_id, int snum, int cmd, char* arg); int semop(int sem_id, struct sembuf *ops, int nops);
共享内存
int shmget(int key, int nbytes, int flags);
void *shmat(int shm_id, void *shmaddr, int shmflg);
int shmctl(int shm_id, int cmd, char *arg);
生产者消费者问题
-
内存映射文件
系统调用mmap
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); // 执行成功,返回一个指针,否则返回-1,errno记录失败原因
-
文件记录锁定机制
系统调用fcntl(文件锁操作)
int fcntl(int fd, int cmd, struct flock* lock);
网络程序设计
-
Socket
协议栈实现:传输层和传输层以下协议在内核中实现
-
字节顺序
大端模式:是指数据的高字节保存在内存的低地址,数据的低字节保存在内存的高地址中,与我们的阅读习惯一致。
小端模式:数据的高字节保存在内存的高地址中,将数据位高低和数据位权有效结合,X86用的就是这个。
网络字节顺序:网络数据在传输中,从高到低顺序存储,低字节存储在高地址,高字节存储在低地址,即”大端模式“。
htonl() // 长整型数据,主机字节顺序转网络字节顺序 ntohl() // 长整型数据,网络字节顺序转主机字节顺序 htons() // 短整型数据,主机字节顺序转网络字节顺序 ntohs() // 短整型数据,网络字节顺序转主机字节顺序