文章插图
现在 , 让我们用上面的tiny shell来实现式子
文章插图
的计算 , 我需要写表示四则混合运算符的Unix程序 , 首先看加号运算符程序 , 将上文中plus.c改成从标准输入读取加数即可:
// plus.c// gcc plus.c -o plus#include <stdio.h>#include <stdlib.h>int main(int argc, char **argv){ float a, b; a = atof(argv[1]); scanf("%f", &b); b = b + a; printf("%fn", b);}再看减法运算符程序代码:
// sub.c// gcc sub.c -o sub#include <stdio.h>#include <stdio.h>int main(int argc, char **argv){ float a, b; a = atof(argv[1]); scanf("%f", &b); b = b - a; printf("%fn", b);}接下来是乘法和除法的代码:
// times.c// gcc times.c -o times#include <stdio.h>#include <stdio.h>int main(int argc, char **argv){ float a, b; a = atof(argv[1]); scanf("%f", &b); b = b*a; printf("%fn", b);}// div.c// gcc div.c -o div#include <stdio.h>#include <stdio.h>int main(int argc, char **argv){ int a, b; a = atof(argv[1]); scanf("%d", &b); b = b/a; printf("%dn", b);}可以看到 , 这些都是非常简单的程序 , 但是任意组合它们便可以实现任意四则运算 , 我们看看
文章插图
这个如何组合 。
首先在标准的Linux bash中我们试一下:
[root@10 test]# ./plus 5|./times 7|./sub 20|./div 636.000000[root@10 test]#计算结果显然是正确的 。现在我在自己实现的tinysh中去做类似的事情:
[root@10 test]# ./tinyshtiny sh>>./plus 5|./times 7|./sub 20|./div 636.000000tiny sh>>q[root@10 test]#可以看到 , tinysh的行为和标准Linux bash的行为是一致的 。
简单吧 , 简单!无聊吧 , 无聊!Pipe连接了若干小程序 , 每一个小程序只做一件事 。
如果我们的系统中没有任何shell程序 , 比如我们没有bash , 我们只有tinysh , 加上以上这4个程序 , 一共5个程序 , 就可以完成任意算式的四则混合运算 。
现在我们用以上的组合Unix程序的方法试试计算下面的式子:
文章插图
根号怎么办?
按照非Unix的编程风格 , 就要在程序里写函数计算开根号 , 但是用Unix的风格 , 则只需要再加个开根号的程序即可:
// sqrt.c// gcc sqrt.c -lm -o sqrt#include <stdio.h>#include <stdlib.h>#include <math.h>int main(int argc, char *argv[]){ float b; scanf("%f", &b); b = sqrt(b); printf("%fn", b);}有了这个开根号的程序 , 结合已经有的四则运算程序 , 让我们的tinysh用pipe将它们串起来 , 就成了 。好了 , 现在让我们计算上面的式子:
./tinyshtiny sh>>./sqrt |./plus 3|./div 293.000000tiny sh>>q本文该结束了 , 后面要写的应该就是关于经典Unix IPC的内容了 , 是的 , 自从Pipe之后 , Unix便开启了IPC , System V开始称为标准并持续引领着未来 , 但这是另一篇文章的话题了 。
最后 , 来自Unix初创者之一Dennis M. Ritchie关于Unix的满满回忆 , 非常感人:
文章插图
原文来自 The Evolution of the Unix Time-sharing System :http://www.read.seas.harvard.edu/~kohler/class/aosref/ritchie84evolution.pdf
【60行C代码实现一个shell】
推荐阅读
- 不需要软件,如何简单实现内外网自由切换?
- 基于windows服务器下的文件备份实现方案
- python使用SocketServer实现网络服务器
- 并使用java实现 一文彻底看懂Base64编码解码原理
- Redis中的发布订阅模式用代码实现就是这么简单
- 使用原生的js实现简易的图片延时加载
- 使用python实现UDP编程
- Go语言实现LeetCode算法:958 检查二叉树的完整性
- PHP实现站内信
- SSH工作过程