自制的unix shell

总体设计框架

目的

I/O 重定向使得程序可以自由地指定数据的流向,不一定从键盘读取数据或输出结果到屏幕上。

管道使得一条命令的输出可以作为另一条命令的输入,多条命令可以配合完成一项任务。

1
2
3
4
5
6
7
$ pwd
$ ls > y
$ ls | sort | uniq | wc
$ cat < y | sort | uniq | wc > y1
$ cat y1
$ rm y1
$ rm y

我们需要实现 $< > |$的基本功能。

实验原理

所有的系统调用都通过文件描述符对文件进行 I/O 操作,每个进程都维护自己的一组文件描述符。

程序的使用三个标准的文件描述符 0、1、2,分别对应着标准输入、标准输出和标准错误。shell 会一直保持这三个描述符是打开的。

程序从标准输入读取数据,输出到标准输出。shell 默认从键盘读取数据,然后运行,输出到屏幕上。

因此我们要进行重定向 I/O 和管道操作,就需要操作文件描述符。

代码思路

我们得到输入的指令,首先处理 cd 的指令,执行了以后。

fork 一个子进程运行用户输入的命令。子进程首先检查命令中是否包含 <,>或| 符号,以确定命令的类型,然后用做相应的处理。

程序将指令分为三类,即直接执行的指令 execcmd,包含 < > 的重定向指令 redircmd,以及 | 的管道指令 pipecmd

在运行指令的时候,当我们遇到类型为 execcmd的时候,直接执行,如下所示。

1
execvp(ecmd->argv[0], ecmd->argv)

如果是 redircmdpipecmd 那么需要操作文件描述符,更改输入和输出。

实验过程

指令的解析——bonus

我们需要提供一定的容错性,也就是说当用户输入的时候,前后多加了空格,这种也需要识别出来。

原来直接处理的 cd 指令,是根据字符的位置进行解析,当 cd 命令前面有空格的时候,就错误了,因此我们需要针对 cd重新解析一遍。

首先如果指令中存在 cd 字符,去除所有的空格,拿到指令再处理。

加入了新的操作,如果直接 cd ,或者 **cd~**,那么就回到 home 目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (strstr(buf, "cd"))
{
parse(buf, arg); //parse arguments

if (arg[1] == NULL || strcmp("~", arg[1]) == 0)
{
chdir(getenv("HOME")); //cd home if no argument
}
else if (arg[1] != NULL)
{
if (chdir(arg[1]) != 0) //cd dir
{
fprintf(stderr, "cannot cd %s\n", arg[1]);
}
}
continue;
}

I/O 重定向 < >

分析

输入重定向 <

程序从标准输入读取数据,如果将文件描述符 0 定位到一个文件上,那么此文件就成了标准输入的源。实现上述功能要用到 dup2 函数:

1
int dup2(int oldfd, int newfd);

输出重定向 >
输出重定向同理,如果将文件描述符 1 定位到一个文件上,那么此文件就成了标准输出。

我们解析的指令中已经封装了需要定位的文件 file 和 mode ,以及文件描述符 fd,下一个指令 cmd 。指令首先匹配 <

输入和输出的操作过程除了文件描述符不一样以外,其余的一模一样,因此直接操作封装好的变量。如下所示。

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
case '>':
case '<':
rcmd = (struct redircmd *)cmd;
fd = open(rcmd->file, rcmd->mode);// 打开文件,描述符fd对应文件
if (fd < 0)
{
perror("error opening file or files does not exist\n");
_exit(-1);
}
dup2(fd, rcmd->fd);// 将fd复制到0或1,此时0或1和fd都指向文件
close(fd);// 关闭fd,此时只有0或1指向文件

runcmd(rcmd->cmd);

管道

分析

管道(pipe)是进程间通信的重要手段之一。调用 pipe 函数创建一个管道,并将其两端连接到两个文件描述符,其中 p[0]为读数据端的文件描述符,p[1]为写数据端的文件描述符:

1
int pipe(int p[2])

当进程创建一个管道之后,该进程就有了连向管道两端的连接(即为两个文件描述符)。当该进程 fork 一个子进程时,子进程也继承了这两个连向管道的连接,如下面左图所示。父进程和子进程都可以将数据写到管道的写数据端口,并从读数据端口将数据读出。两个进程都可以读写管道,但当一个进程读,另一个进程写时,管道的使用效率是最高的,因此,每个进程最好关闭管道的一端,如下面右图所示。

管道1

Shell 要实现管道功能,需将前一条命令的输出作为后一条命令的输入。那么以上面右图为基础,还需将前一进程的标准输出重定向到管道的写数据端,将后一进程的标准输入重定向到管道的读数据端,如下图所示:

管道2

我们将运行整条命令的子进程称为进程 A,本文 shell 的实现中,进程 A 并不执行命令,而是再 fork 两个进程,称之为进程 left 和 right,分别执行两条命令。两个进程都从进程 A 继承了管道两端的连接,可通过该管道通信。进程 A 不再需要管道连接,于是关闭两个文件描述符,然后等待进程 left 和 right 执行完毕。

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 创建管道
if (pipe(p) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}

//创建left进程
if (fork1() == 0)
{
// 关闭管道的读数据端
if (close(p[0]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}

if (p[1] != STDOUT_FILENO)
{ // 防御性编程
// 将标准输出重定向到管道的写数据端
if (dup2(p[1], STDOUT_FILENO) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
}
runcmd(pcmd->left);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//创建right进程
if (fork1() == 0)
{
// 关闭管道的写数据端
if (close(p[1]) == -1)
{
perror("close");
exit(EXIT_FAILURE);
}

if (p[0] != STDIN_FILENO)
{ // 防御性编程
// 将标准输出重定向到管道的读数据端
if (dup2(p[0], STDIN_FILENO) == -1)
{
perror("dup2");
exit(EXIT_FAILURE);
}
}
runcmd(pcmd->right);
}

shiyan

实验感悟

对于重定向和管道的操作,都是对于文件描述的操作。

直面灾难

野外生存和高原反应

野外生存,高原反应的定义

  • 什么叫野外生存?
    人在非生活环境下,最大限度的维持生存。非为主动和被动:(探险活动促进发展,战争的促进,自然灾害,科学考察促进野外生存的发展)

  • 意义?
    磨砺意志,人生最好的课堂,生存训练和自我拓展,发掘潜能,提高环境意识。

  • 主动野外——带刀子很有用;饮用水;火

生存技巧——搭建营地

  • 选择营地最首先的就是要考虑安全。并且提前准备搭建营地。

  • 六大要素:近水,背风,避险,日照,放兽,平整

注意事项:

生存技巧——水源

寻找水源

  • 根据地形寻找水源:水往低处流,山谷山脚,植物茂密的地方
  • 利用动物:动物多的地方
  • 根据植物,生长茂密的地方
  • 通过声音来找水
  • 根据地面情况来找水

制造收集水

  • 收集降水
  • 利用冰雪化水
  • 收集地表蒸发水:
    挖坑,在坑底放容器,上面是薄膜
  • 植物蒸腾水
  • 植物的汁液

净化水的方法

  • 煮沸法
  • 沉淀法
  • 过滤法:
    纱布,小卵石,纱布,石英砂,纱布,活性炭,纱布,膨松棉
  • 吸附法
  • 药物法

生存技巧——采捕食物

  • 两种方法:采集野生食物,猎捕野生动物

  • 野生植物:(野果,野菜,藻类,地衣,蘑菇)
    野果:山葡萄,野栗子,椰子,木瓜是应急的上好食物。
    野菜:鱼腥草;有毒印度毒莓。现有 38000 已知蘑菇种类,其中 5%有毒。

  • 猎捕野生动物:(补充蛋白质)
    可食用的环节动物:蚯蚓,沙蚕
    贝类:河蚌,蛤蜊
    甲壳类:水蚤,虾类
    昆虫类:金龟子,蟋蟀,蚂蚁,蝉,蟑螂,蝗虫子,蚱蜢,蜘蛛,螳螂
    鱼类,可使用的爬行类

生存技巧——野外定向方法

  • 迷路与迷向:分不清东南西北;不知走哪条路——回到原出发地是最可靠的方法

  • 自救:观察地形,记住突出的目标

徒手定位法:

  • 太阳:找一个棍子

  • 星星:北极星,北斗星

生存技巧——野外生火方法

人工取火的方法

  • 敲击法:钻木取火
  • 聚焦法:凸透镜的聚焦
  • 锯木取火法
  • 钻木取火
  • 镁棒取火法(有准备)

生存技巧——求救方法

求救信号:

  • 火光信号
  • 烟雾信号:海上很重要,
  • 图形信号:SOS;
  • 呼救:SOS——三短三长三短
  • 灯光信号

生存技巧——经验分享

认真选择食物;自制吊床;不断做路标,确定前进方向;沿着小溪走;保存火种,用来煮食物、取暖、照明、驱兽

成功的四大要素——保护措施,救援,水和食物

大部分热量通过地面流失的

用篝火中的木炭做一个滤水器,塞入草,自己衣服的布,可以直接从河里面喝水

千万不要喝海水,可以挖一个坑,对海水进行蒸发

可以喝新鲜的大象的粪便

骆驼的瘤胃里面有水,消化食物的胃里面也有水

可以将铁丝在头发上进行摩擦,把他进行磁化,然后在水面放上一片叶子,将小铁丝放在上面,然后铁丝指向北极

动物的心脏是最棒的求生食物之一

牦牛的肝脏可以生吃

高原反应中的策略

  • 概念:人体急进暴露于低压低氧环境后产生的各种病理性反应,由平原快速进入海拔 3000 名义上高原(青海,莫高窟)(拉萨 4、5000 米),或者由高原进入海拔更高地区,在数小时或者 1~3 天内发病

主要症状:

  • 头痛头晕;胸闷,呼吸急促,咳嗽;食欲下降,呕吐;体虚乏力,平衡感下降;焦虑烦躁,失眠,睡眠质量下降;高山肺水肿;高山脑水肿

求生方法:

  • 轻微症状,停止继续上攀,可以下降
  • 严重的情况唯一方法也许就是下降,如果下降 1000 米,情况会好转
  • 发现不良反应,在初期预防性口服药物

气象灾害(台风)事故救灾

威胁人类生存的 10 大类自然灾害:台风,破坏力大

气象灾害(台风)基础知识

什么是台风:

中心附近最大平均【风力 12 级】及以上,即风速超过 32.6 米/秒的【强热带气旋】

怎么形成的?

  • 发源于【热带海面】赤道附近,温度高,形成了一个低气压中心
  • 随气压变化和地球自转,逆时针旋转的空气漩涡,这就是热带气旋
  • 只要气温不降,热带气旋越来越大,最后形成了台风

组成

台风在水平方向上一般可分为台风外围、台风本体和台风中心三部分。

台风外围是螺旋云带;台风本体是涡旋区,也叫云墙区;台风中心到台风眼区。

特点

  • 季节性。发生在夏秋之间,最早发生在五月初,最迟发生在十一月
  • 中心登录地点难准确预报。台风的风向时有变化,常出人预料
  • 旋转性。风向一般先北后南。
  • 常伴有大暴雨、大海潮、大海啸
  • 强台风发生时,人力不可抗拒,易造成人员伤亡.破坏力强,危害性大

台风的分级

  • 热带低压:6-7
  • 热带风暴:8-9
  • 强热带风暴:10-11
  • 台风 12-13
  • 强台风 14-15
  • 超强台风 16 级或以上

台风警报

  • 蓝色预警信号:在 24 小时内,可能或者将要受到热带气旋影响,平均风力 6 级以上,或者阵风 8 级以上并可能持续(户外活动取消)
  • 黄色预警:平均风力 8 级以上,或者阵风 10 级以上(须保护老人小孩)
  • 橙色预警:平均风力 10 级以上,或者阵风 12 级以上(须躲避)
  • 红色预警:平均风力 12 级以上,或者阵风 14 级以上(须转移)

处置程序与措施

救援前准备

  • 了解现场的道路交通情况
  • 红色的救援衣

设置警戒;救援排险

台风来临前

  • 关心台风信息
  • 不旅游或者到海滩上
  • 清理阳台、晾衣杆等
  • 准备食品,饮用水,药品,日用品
  • 加固一道设置

来临后

  • 驾车保持低速慢行,看路
  • 穿雨衣,不要打伞
  • 远离高大树木,棚子,架子,架空电线
  • 立即弃车而逃

台风的好处

带来降水,缓解旱情;降温消暑

社会维特和运行的机制?

  • 仲裁机制:谁说了算

中等症状的出血休克

第三个死亡高峰:医院

现场救护原则

优先原则:分拣——红色,黄色,绿色,黑色
判断意识心跳呼吸

保持气道通畅的重要性;迅速止血、止痛;先包扎头部,胸部,骨头;先固定颈部,再固定肢体;如果昏迷,不要随意仰卧;
如果昏迷或者恶心呕吐的时候不要随意给液体;检查轻柔;动作迅速,安抚伤员;尽可能佩戴个人保护用品,比如手套塑料布,毛巾

  • 通气困难与气道问题混淆
  • 胸腔问题,靠视觉、触觉、叩、听
  • 复苏不忘保暖
  • 反复评估

基本技术

  • 现场心脏复苏
  • 通气
  • 止血
  • 包扎

止血

压迫止血法——
加压——动脉,仅能减少出血量,不大可能完全止血
填充止血
绷带止血——损伤最大,容易致残,注意位置,注重时间;上臂在中上 1/3 处,以免神经坏死;前臂和小腿一般不适用止血带;绝对不能用飞弹行的绳索

包扎

绷带,三角巾

软件过程学习笔记_Scrum

Scrum

Scrum 框架

Scrum框架

Scrum 过程

发布计划(owner->product backlog,做出 release burn-up,->Sprint backlog,做出 sprint burn-down)

Scrum 角色

product owner:产品的愿景;产品路线;创建带有优先级的产品功能列表(product backlog);持续演化 product backlog;负责决定发布计划;沟通并且验收产品的功能。

scrum master:发现、记录并移除障碍促进内外沟通;保护团队;指导团队;不是团队经理或者项目经理。

team:交付用户故事;跨职能;自组织,决定能够完成交付;帮助 owner 完成持续演化;估算任务,更新 sprint backlog。

Scrum 主要制品

product backlog:优先级的功能清单;包含描述、优先级和规模估算;承载用户故事;高优先级的故事变成规模合适的故事;低优先级的(Epic 史诗)可以较大的粒度。

deep——(Detailed Appropriately 适度细节)(Estimated 估算的)(Emergent 涌现的)(Prioritized 排序的)

sprint backlog:在 sprint 中要实现的 功能,每天会被更新,以小时为单位。

release burn-up:横轴是 sprint,纵轴是完成功能的规模。掌握团队是领先还是落后进度。

sprint burn-down:横轴是天,纵轴是剩余小时。掌握团队在本 sprint 是领先还是落后。

Scrum 的三大支柱

Scrum的三大支柱
透明,调查,检查

用户故事

  • 用户故事模板
    正面:(作为。。‘角色’,我需要。。‘功能’,以便。。‘用户价值’;下面还有规模和优先级)
    背面:验收条件;约束

  • 用户故事分类(使用计划扑克)
    1、2、3、5、8、13、20、40

  • 用户故事的 INVEST 原则
    用户故事的INVEST原则

  • 用户故事的 3C 特征
    card:使用卡片描述用户故事,一个 token,用于备忘和计划

    conversation:实质—变文档为交流

    confirmation:确认完成,Definition of Done,SMART 验收条件。
    (DOD 定义:在宣布工作潜在可发布之前,要求团队成功完成的各项工作检查,从设计到代码,到测试,到接收,到已经上线)

  • 排序
    高风险高价值;低风险高价值;低风险低价值

发布计划(想法)==》(product backlog)

产品愿景

-   《《《电梯陈述》》》:for(用户);who(需求和机会的陈述);the(产品)is a(类型);the(关键benefits-购买的原因);unlike(主要替代品或者竞争对手产品);our product(主要区别陈述)。
-   精益画布:成本分析;有收入,盈利模式;有独特的卖点;用户体验很重要。
-   用户旅程地图:进行用户体验

故事

用户故事工作坊;用户故事地图

计划

确定MVP(最小可行产品)

冲刺计划 (product backlog)==》(sprint backlog)

团队速度:团队每个迭代能够交付的故事点数
团队产能:能够用以开发的小时数
《《《时间,任务单位小时,任务大小 4-16 小时》》》

  • 输出:团队任务板(Sprint Backlog)和初始燃尽图

冲刺执行

  • 每日站会:每天同一地点,同一时间,15 分钟;每人回答 3 个问题,我完成了什么,准备做什么,遇到什么阻碍;po 可选择;其他人可以出席,但是不能发言——(同步状态,协调工作,每日承诺,报告障碍)

  • 每日站会:回顾,规划,推进

  • 输出:潜在可交付产品增量

冲刺回顾

  • 敏捷方法以迭代的方式完成工作
  • Sprint(冲刺)是 Scrum 的迭代,保持 Scrum 的基本节奏
  • 完成产品增量的交付;1-4 周的 Time-Box;每个发布的时间盒保持固定

冲刺评审会议

目标:持续改进产品;对产品本身

验收用户故事

冲刺反思会议

目标:持续改进工作方法;对产品构建过程的检查和调整

投票选择高优先级改进项

会议原则:专注于行动

Scrum 为何有效果

基本实践:Sprint 冲刺/用户故事/master/owner/发布计划‘迭代计划/每日站会/跨功能团队/release burnup/sprint burndown/迭代反思和评审/带优先级的 product backlog/电梯陈述/用户故事工作坊/

看板方法

是一种增量的、演进的改变技术开发和组织运作的方法。通过限制 WIP(work in progress:也就是在每一个环节限制工作数量)的数量,形成了一个以拉动系统为核心的机制,暴露系统中的问题,激发协作来改善系统。

看板的四个原则:1)从既有流程开始;2)持续增量、渐进的变化;3)尊重当前的流程、角色、职责和头衔;4)鼓励在各个层级上发挥领导行为

看板六大实践:1)可视化工作流;2)限制在制品数量;3)管理流动;4)让规则明确;5)落实反馈循环;6)协作改善和实验改进

软件过程概述

  • 敏捷和精益方法
  • 软件过程:是指软件整个生命周期,从需求获取,需求分析,设计,实现,测试,发布和维护的过程模型。
  • 项目管理四要素:三角形(工作“功能”,成本“人力资源”,时间“进度”,中间质量)
  • 成功的项目管理(软件过程):在给定的时间内,利用给定的资源,交付高质量的工作(功能)。——PMP 定义
  • 失败原因,过程管理的问题
  • 新形势下,业务对软件开发的要求:更快的推向市场;卓越的用户体验;可预测性;降低成本

敏捷 vs 瀑布

瀑布模型

  • 瀑布核心思想:按工序将问题化简,将功能的实现与设计分开,便于分工协作,即采用结构化的分析与设计方法将逻辑实现与物理实现分开。
  • 瀑布的缺点:依靠文档进行传递,信息的缺失和丢失;无法预估的进度;造成团队间的对立和博弈;延迟了反馈,后期成本变高

敏捷和精益方法

什么是敏捷?

敏捷是用于描述一组方法的统称;一种思想,一组开发框架,一组价值观和原则(敏捷宣言:个体和互动,工作的软件,客户合作,响应变化)

  • 敏捷和精益方法今早交付价值和暴露风险
  • 价值:快速响应变化;生产力的提高;增加透明;更高的士气;更好的预测;更快的推向市场

所有的敏捷方法都遵循迭代和增量

增量开发,就是一块接一块地构建一个系统。一部分功能被开发出来,然后另一部分功能被开发出来,集成进前一部分功能里。

迭代开发认为,系统是在不断演化中完善的,因此,一开始构建整个系统,但并不是那么完美,利用后续的反馈,来一步步改进系统。

敏捷的核心理念

探索性过程;迭代增量开发;范围可变(也就是功能可变,其他不变);尽早交付价值和暴露风险;组织文化

敏捷宣言

敏捷宣言

敏捷实践

每日站会;带有优先级的产品待办事项列表 product backlog;短的迭代周期;反思会议;迭代计划