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结构(进程不运行时也需要的管理信息)

    image-20210421145027470
  • 进程的基本状态
    运行状态和睡眠状态(阻塞、等待、挂起)

  • 进程的调度
    调度优先级

  • 系统调用

    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结构

      image-20210421155238928

      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信号

      • 管道通信

        1. 管道传输是一个无记录边界的字节流
        2. 父子进程需要双向通信时,应采用两个管道
        3. 有可能死锁,只限于同祖先进程间通信
      • 命名管道
        允许不相干的进程(没有共同祖先)访问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() // 短整型数据,网络字节顺序转主机字节顺序
    
posted @ 2021-04-21 22:36  等风的猫xx  阅读(88)  评论(0编辑  收藏  举报