Linux 控制台编程

最初学习C语言的时候,只能在控制台上输出一些东西,和windows相比感觉非常的不实用,虽然也看见过一些程序能在控制台上输出炫酷的颜色的动画,但是基本语法还掌握不牢的时候,这样的程序也只能是欣赏一下,不敢想象自己去写这样的程序,后来也没再有机会研究这方面的东西。

今天,觉得控制台上输出只能顺序输出,最多也就是通过 \b 回退,不过这个回退也不过回退到行首,还有,虽然可以通过 \v 直接跳到下一行,但是:如何回退上上一行呢?如何在屏幕上指定坐标输出呢?

且看下面这个shell:

可以在控制台的右上角显示系统时间;

可见tput这个东西可以定位光标位置,那么tput是个什么东西呢?

其实,常用的clear命令就属于ncurses包

把ncureses-devel开发包安装一下就可以开发了; 文档: http://download.csdn.net/detail/Kevinxtq/1063483。该库方便开发terminal程序,当然没有该库也能做简单的光标定位,如:

在0行78列输出一个醒目的Hello World;  但是我不知道如何让光标回到原来的位置。

 

python 的snack模块就可以用于开发控制台窗口应用: http://www.wanware.com/tsgdocs/snack.html  linux上认证方式配置程序: authconfig-tui 就是使用python借助snack来实现的

 

php 也有ncurses的封装: http://php.net/manual/en/book.ncurses.php

实例:

https://devzone.zend.com/173/using-ncurses-in-php/

https://github.com/PHPGangsta/PHP-NCurses-Example

安装: yum install php-pecl-ncurses

 

参考资料:

http://bbs.chinaunix.net/thread-4179287-1-1.html

http://www.cnblogs.com/Xiao_bird/archive/2009/07/21/1527947.html

http://blog.csdn.net/chenxiaohua/article/details/2099304

http://download.csdn.net/detail/Kevinxtq/1063483

c++之多态与虚函数

多态玩的就是虚

什么是多态?
函数的形参中定义基类的情况,当然,这里的基类不一定是爷爷类,父亲类也可以,当实际调用时传递的如果是子类,那么,运行时会检查要调用的类的方法在基类(因为形参是基类,所以要参考基类)中是否virtual的,如果不是virtual的,则直接执行基类中的定义(即使当前确实是子类的实例,也不会执行子类的该方法,换言之,就是不允许覆盖,这就是virtual存在的意义,某些语言是直接覆盖的,没法选择不覆盖),如果是virtual的,则根据继承链向下检查,直到查到该方法的最后一个实现,哪怕继承链中的某些子类没有明确写virtual关键字也没关系(换言之,virtual属性是自动、强制继承的,或者说,dog类中的run方法的virtual关键字是多余的);具体实现上可能不是一个一个查,但至少逻辑上是这样的; 如果animal类的run方法不是virtual的,并不意味着子孙类的run方法再也不能添加virtual了,比如:animal的run没有virtual,dog的run使用了virtual,则run(animal *a)函数只能执行animal类中的run,而dog_run(dog *d) 却可以多态, 即: dog_run(new jinmao()) 时打印金毛的跑法

虚函数

就是允许覆盖,多态的实现方式

纯虚函数

就是没有函数的定义,只有声明,子类想不覆盖都不行,除非子类自己不创建对象,期待孙类的继承;

语法上来讲,函数不定义是不行的,但是纯虚函数就是不定义,所以必须明确说明不定义,即: =0 ,如下: (没有 =0 是不行的)

抽象类与接口

c++中没有抽象类,也没有接口,更没有abstract、interface、implements等关键字,有的只有class和virtual

如果一个类中包含了纯虚函数,则该类自然为抽象类;

如果一个类中只包含纯虚函数,则该类相当于接口;

画图工具

50款JavaScript图表库分享:

http://my.oschina.net/u/935975/blog/220987

纯文本流程图: http://my.oschina.net/iamancoder/blog/652233

13个JavaScript图表(JS图表)图形绘制插件:

http://blog.jobbole.com/13671/

js版的visio: http://demo.qunee.com

js通过数据生成流程图: http://my.oschina.net/blogshi/blog/221749

d3: https://github.com/cpettitt/dagre-d3  功能上来看,基本是dotgraph的js实现

js写的国际象棋: http://www.jointjs.com/demos/chess

 

 

iTerm2 之文件上传下载

iTerm2 可以方便地上传下载文件,甚至直接在终端显示图片。

第一步: 登录自己经常访问的服务器

第二步: 点击iTerm2菜单,选择: Install shell integration
这一步会自动在你的终端里面执行一些命令,就是往服务器上安装一些东西

第三步: 退出,重新登录你的服务器

 

上传文件:

按住option从finder往iTerm2上拖文件,就可以上传到指定目录了(这时候会发现菜单栏多一个upload菜单)

下载文件:

按住Command键,点击要下载的文件,就下载到指定目录了(这时候会发现菜单栏多一个download菜单)

查看图片:

imgcat a.gif

 

参考: https://iterm2.com/documentation-shell-integration.html

systemtap 之 基础命令

示例1:

通过 -e 选项直接执行probe,如:

示例2:

跟踪指定进程,如:

示例3:

执行stp脚本,如;

 

 

 

systemtap 跟踪PHP

参考资料:

http://php.net/manual/zh/features.dtrace.php

通过mark的方式,了解php都提供了哪些探针:

php探针完全版: all_probes.stp

 

systemtap 进阶

执行hello word命令出错:

从错误来看,只是比较时间上有差异,而且差别不大,如果能不比较该时间,或许问题就解决了(其实我们前面犯过一个不大不小的错误)

通过stap -v 选项 (可以多些几个v的,v越多信息越详细),如下:

然后打开文件: /tmp/stapjbY7L4/stap_19453_src.c ,错误位置如下:

从上图来看:

如果不去定义 常量 STAPCONF_GENERATED_COMPILE 就不会走到该逻辑,问题或许可以解决,那么 STAPCONF_GENERATED_COMPILE 是在哪里定义的呢?

其实就在旁边的一个 .h 中定义的,而该 .h 和该 .c 一样都是该目录下的Makefile 动态生成的,Makefile里面有如下逻辑:

不幸的是 Makefile本身也是动态生成的:

  1. 要么通过修改上述if逻辑中相关的某个文件,让返回值为“假”
    我用到的是文件: /usr/share/systemtap/runtime/linux/autoconf-generated-compile.c 内容很简单:

    问题就来了, <generated/compile.h>  是哪个目录下的?
  2. 要么找到生成Makefile的地方,去掉该逻辑
    我简单找了一下,没找到

 

还有别的办法没?

 

因为systemtap依赖不多,其中一个rpm包就是kernel-devel,怀疑问题出现在kernel-devel ,那么去kernel-devel的文件中搜索 UTS_VERSION 这个常量试试,果然,发现文件: /usr/src/kernels/3.10.0-229.14.1.el7.x86_64/include/generated/compile.h (这不就是上面提到的 <generated/compile.h>嘛?)内容如下:

终于找到了 UTS_VERSION ,直接修改下这里的UTS_VERSION ,问题解决。

 

据说,这个常量信息是编译内核的时候自动生成的(从文件第一行也能看出来),所以,每次编译时间都会不一样,如果自己编译的内核,而去使用别人提供的kernel-devel,必然会遇到我这里出现的问题

上面提到说,我犯过一次错误,是这样的:

我的kernel-devel 是从 http://rpm.pbone.net/ 下载的,这里的rpm包有一个distribution的属性,由于rpm包大小相同,我就随便下载了一个,其实是有区别的,至少上面的时间是不同的,重新选择centos7的下载,重新安装,问题解决

新下载的rpm包中文件/usr/src/kernels/3.10.0-229.14.1.el7.x86_64/include/generated/compile.h 如下:

总结: systemtap 之所以入门较难,和苛刻 的内核版本号 以及yum安装的时候只安装最新的rpm包有极大关系,yum源中可能找不到自己内核版本的kernel-devel

 

参考资料:

http://blog.yufeng.info/archives/1098

http://blog.csdn.net/zhangskd/article/details/25708441

 

安装正确的debuginfo版本是非常重要的,对于fedora系统来将,yum中找不到的,可以直接去build系统中找,如,我的fedora的kernel相关rpm包: https://koji.fedoraproject.org/koji/buildinfo?buildID=1426588 其它版本的也能找到,在这里 如果搜索不到的话,可以按照字母顺序找找,可能搜索不好使

 

 

vagrant 配置windows虚拟机

相比较在vagrant中配置centos来讲,配置windows会比较麻烦而且特殊一些,下面记录一些自己的经历。

第一步:创建虚拟机

由于windows的vbox不多,能找到一个适合自己的也不太容易,倒不如自己在virtualbox中直接用iso文件安装一个,安装完成后直接: vagrant package –base the_virtualbox_vm_name –output my_windows.box

由于windows不比centos可以使用ssh登录,而是有自己的管理方式,叫做wrm,这个必须在安装windows的时候都设置好,参考资料:

下面是我遇到过的一些问题:

  1. 为了避免忘记密码,干脆没给用户设置密码;然而,wrm要求管理员用户必须设置密码,否则,无法配置wrm;就因为这个浪费了不少时间
  2. 网络连接类型不能是公共网络,否则wrm不允许使用
  3. 为了不必要的麻烦,干脆把防火墙给关掉了

重要配置:

曾经因为没有设置@{AllowUnencrypted=”true” }  和 @{Basic=”true”} 浪费了很多时间

关闭UAC: http://jingyan.baidu.com/article/09ea3ede241689c0afde3972.html

第二步: 配置vagrantfile

vagrant默认使用ssh,而windows要使用wrm,那么,总得有个方式说明一下吧?vagrant官网文档查看了一大片,没找到,最后还是在 http://huestones.co.uk/node/305  找到的,如下:

windows中很可能会出现未识别的网络或者是“公用网络”,在这种情况下,winrm是不能正常使用的,所以,保险起见,vagrantfile中添加如下设置:

确保不会出现公用网络,曾经因为这个浪费了不少时间

 

附:一个windows的vagrantfile

 

附:

如何给设置的ip指定掩码(默认24位)? 如下指定22位掩码:

windows的“未识别网络”是什么意思?

当本地连接设置为“自动获取IP地址”,同时网络中又没有dhcp服务器,则该本地连接会被标识为“未识别网络”;如果在所在网络提供一个dhcp服务器,就会避免此种问题的出现