码迷,mamicode.com
首页 > 其他好文 > 详细

命令行

时间:2018-02-25 17:18:36      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:任务   循环   tcp协议   wget   tom   data   有一个   url   概念   

// 本文源自以前在知乎上的一个回答,https://www.zhihu.com/question/19655399/answer/101900080
// 此处重新整理,待改写。

典型使用场景

  • 服务器远程登陆,只有命令行界面,此时不得不用命令行工具处理日常工作任务,所以就用,边用边查手册,用久了所以熟悉。
  • 自己的电脑上经常使用命令行处理日常编程/文件管理工作。
  • 自己编写命令行程序。

分类随记

文件上传、下载:


  • 一般来说就是sz,rz,wget,curl,scp等。
  • for循环wget,分分钟多进程下载。
  • wget -c 分分钟断点续传。

压缩、解压:


所以得会用tar,zip等命令。我一开始的时候,问一个老手tar cvzf,tar xvzf后面一排参数啥意思,老手说:”早就忘记了,天天都这么用“。所以我认为它和一个按钮一个菜单没什么区别,命令行参数的选项和参数一般是经常用就熟悉,久不用就容易忘记,此时复查是正常的事情。顺便吐槽下windows下7z的菜单里直接解压tar.gz要解压两次真是麻烦事,命令行当然可以一次搞定。

目录和文件的创建、移除、拷贝、移动:


基本命令是:mkdir,rm,mv等。这是最基本的常规操作了,一般来说需要注意的有:

  • 非空目录的移除,
  • 递归删除时拼接路径的安全隐患(递归删除根目录就一点都不好玩了)
  • 删除时文件被占用
  • 如果可能只是短时被占用,可以sleep几十毫秒再删,重试n次退出。
  • 考虑采用”删除xxx.old, 移动xxx到xxx.old, 拷贝yyy到xxx“的方式代替”直接删除xxx,移动yyy到xxx“的方案、
  • 理解硬盘驱动,冗余磁盘阵列,inode,文件和目录,缓存策略等。

文本显示、查找、替换、统计:


在命令行下分析程序的日志,必备的技能就是文本操作。基本的命令有cat,tail,less,head,grep,sed,awk,wc,xargs等,这组命令行基本要通过管道来配合使用。我个人觉的awk的设计有点古老,awk的脚本我是一点都不觉得写起来流畅和爽快,sed的稍微好点,但也一般。如果是在windows下,这种流式过滤的工作,我是宁可开个LinqPAD写Linq来做,其实很多时候写脚本我都实际上觉的用正式点的高级语言做会更好。很多shell脚本写的人天马行空,别人读起来就不好玩了,毕竟写shell的人不写注释,遍地意大利面条。吐槽归吐槽,现实上我们不得不妥协,该用还得用。毕竟一切数据都可以输出成文本,所以文本的流式分析是基本技能。

我认为这组命令的组合使用能让人体会到管道的好处。管道让多进程之间的流式操作流畅进行。顺便我认为shell的一个特点是,它天生是多进程程序,一个shell里随便一堆命令就是多进程操作,可能很多人写着的时候并没有意识到这点哦。进一步,多主机之间ssh授权后,shell里的ssh远程命令的组织又天生带有点分布式属性,也许这能带来一些启发,例如ssh 信任就是非对称加密。

  • A机留私钥; B机在.ssh目录放公钥,在.ssh/authorized_keys里填上公钥内容。
  • 则A机执行ssh user@B cmd 的时候,B机会用公钥和A机之间建立ssh连接,然后执行命令。
  • git 的客户端向git的仓库之间建立ssh授权也是这个过程,实际上任何依赖于ssh建立授权的都是这个过程。
  • 这实际上是一种“反连”协议,思考下私钥在哪里就知道了。

理解管道的另一个要素是,需要理解fork,vfork、clone,exec;需要理解标准输入输出。fork之后,在exec子进程之前重定向父进程的标准输出,重定向子进程的标准输入,这样它们就被流式串在一起。

文本编辑:


vi基本技能。shell下编辑文本只能用这个了,我认为vi或者vim里最重要的技能就三个:导航、查找、替换,带着这个思维去记忆那些命令会明确很多。我觉的任何一个程序的核心功能就几个,每个核心功能的核心命令也就几个,其他的就按需查用即可。

理解模式的概念,同样的键盘按钮,在不同vim模式下,操作代表不同的语义。想象一下相机是如何由有限的几个按钮做到多组不同功能的支持。

我认为快捷键并不是vim/emacs之类的最大特点,任何一个支持快捷键的编辑器,你都可以通过熟练掌握常见的快捷键使得操作快捷高效,比如notepad、visual studio、word等,理解这点有助于我们看清事实,驾驭工具。

资源监控:


输出的信息都可以配合grep等使用,比如ps aux|grep processname.

  • 任务管理器型:vmstat, top, htop,
  • 进程:ps
  • cpu的虚拟化。
  • 理解OS对process的调度:Scheduling (computing)
    -FIFO,SJF,STCF,RR,MLFQ
    • 理解os调度process的话,再去看协程,用户态协程需要自己做调度:)
    • IO密集和CPU密集?
  • 磁盘:du, iotop, iostat
  • 文件句柄:lsof,比如查看一个进程打开的文件描述符,反向查看哪些进程打开了某个文件。
  • 内存:物理内存的虚拟化(进程的内存分布,内部浪费和外部浪费),分页,页错误。

调试和Hook:


开发的话会需要调试程序和Hook程序等。

通过ulimit -c unlimited让程序崩溃时产生coredump,然后用gdb调试,看崩溃堆栈,变量、单步等,这是gdb的常规操作。linux下开发必备技能了。ulimit 还可以限制其他资源,比如-n限制文件句柄个数,-s限制堆栈大小等,具体查文档。

Debugging with GDB
每个线程的堆栈,判断出多线程问题、内存问题,这两个基本占大头,所以gdb里主要就是:

  • 查看线程->切换线程->查看堆栈->切换函数帧和代码行->查看变量信息,再结合源码合理怀疑临界区问题、状态机问题、内存问题等。
  • 定位就是:查看->切换->怀疑->[重现]->确定->修复,疑难问题可能只能靠肉眼codereview确定。

系统调用、堆栈等的Hook:strace,dtrace、pstack等,这组算是lowlevel的神器,在很多时候能起到一针见血的效果。http://jvns.ca/blog/2016/09/07/new-zine-linux-debugging-tools-youll-love/

顺便,可以理解下系统调用的原理,中断的实现原理,这样你在使用strace监控一个程序的系统调用的时候,脑子里会有更清晰的思路。系统调用并不是一个简单的函数调用这件事么..

Things UNIX can do atomically 多进程之间可以对文件和文件夹加锁

网络:


tcpdump抓包是一定要掌握的,抓tcp、udp包是必备的技能。输出pcap格式文件也是要的。如果是有图形界面的话,wireshake在windows和linux下都能用,如果是windows上还可以用microsoft networkmonitor。说实话,我觉的microsoft networkmonitor做的比wireshake好用。

一个tcp连接,三次握手、四次挥手;建立在tcp连接之上的http连接,http request包在什么时候发,seq号是怎样变动的;诸如此类,都可以在这个地方查看。

为什么要三次握手。syn、ack、ackack,它们是原子不可分的么,在更复杂的协议里,一个syn,一个ack、一个ackack本身可能就是一组子协议。三者中任何一个环节被打破(Break),都会导致握手失败。

为什么要四次挥手。自己设计流式协议的话,如果你不需要这种Feature,就可以暴力Close了。知其然,知其所以然。

  • P2P打洞的原理:NAT,限ip,限port,限ip和port,随机ip和port
  • DNS的原理,host,DNS污染

Http协议说到底是一个Tcp协议,这点很重要。SPDY->HTTP2->QUIC

拥塞控制算法,根据历史数据记录估算未来数据,这是一种学习(统计):Reno,Cubic,Ledbat,BBR。

Deep Learning,NN:问题是,它和大数据一样,广告词的成分居多,只有少数人在做和它相关的事情,从工程上来说,它应该是被搭建出来的算法模块,而非广告词,然而满大街的AI广告词让人讨厌,正经的程序员和工程师要对那些满口广告词的文章带有警惕性。

http://neuralnetworksanddeeplearning.com 这个6章的教程主要讲神经网络最基本的一个算法(误差逆传播算法,也就是所谓的bp算法)的基本原理(一部分在推导bp过程如何被用来算bp误差函数的微分,这里主要用到了微分的链式法则,求微分的目的是加速递归下降法的收敛速度),作者也对AI的未来有一番自己的见解,你会发现bp本质上就是用来做连续函数的逼近(利用递归下降法,让逼近函数的权重参数“快速”收敛)。后面的CNN只是一种用来减少bp权重参数的分层策略,本质上还是bp,不过RNN只是简单提了一下。

一台机子有多个网卡(ifconfig),或者单网卡,多ip,绑定到0.0.0.0的时候,收发包是怎样的情况?

拆开ip包头,tcp和udp包头,以及做checksum校验的拟包头,理解协议包是如何被Stack的。话说最早我想当然认为tcp包头里面才是ip包包头,然而事实上这个鸡蛋黄是上层的包头在下层协议包的包体里。不知道是否有同类人有过这种直觉的错觉。

数据库操作:


  • 命令行下,操作mysql和sqlite是常见的事情,这个基本就是常规的sql操作语句。
  • 将数据库dump出SQL文本格式,到别的机子上导入什么的。。
  • 以前有个人打开了这么一份文本,惊讶说:“哇,谁写的SQL创建代码,这么整洁,连注释啥的都很规整...”
  • 理解关系型数据库的范式,事务,一致性。
  • 理解B+树、Block。
  • 基于行存储Block的数据库,基于列存储Block的数据库,各自的优缺点
  • 局部性原理,行Block存储是行记录读写偏好,列的则是部分字段读写偏好
  • trad off,没有最好,只有最合适

版本管理等:


  • svn、git,这个本来就要会的,只是很多人用图形界面的工具多了后,可能命令行使用并不熟悉,但是在Linux shell下,这也算基本技能。
  • 理解“围绕数据结构设计接口”,git是关于commit的链表的数据结构的一组api。
  • 元数据分布式同步,ZooKeeper

视角和启发

如果你觉的这么多东西真啰嗦,很简单,不理会此处的所有链接,只看个大概,我要强调的只是如何看待命令行的一种视角,命令则应该每个人自己使用中自己累积,正如一个人对自己写的代码,无论多复杂都能了然于胸,而对别人写的代码,则要花非常多心思才能做到同样熟悉,所以具体的操作应该是自己使用出来的。因为命令行作为操作系统的shell,每个命令行侧重的是操作系统的某一方面的知识,我提供的只是把命令行作为一个索引,去归类某些知识,这是我的目的。

在Mac下用了一年多fish,感觉很好用,大部分命令敲过一遍之后,输入前面几个单词,fish就会自动灰色显示备选历史命令,方向键选择下就好了,很方便。个人电脑的终端上装fish这种带自动补全功能的工具是很方便的。我们使用命令行,首先是为了效率。

以及,命令行的option,其实就像一级菜单/二级菜单一样的概念,只不过在命令行下你不能方便的使用鼠标就看清楚这些菜单是什么,就只能靠大脑去记忆,所以显得能记住命令的好像多高级,你想想如果给你VisualStudio,你会去记住那些一级菜单/二级菜单都是什么吗?不会,你只会每次都用鼠标一个个点出来而已,习惯了就记住了。命令行的option,也大概是这样的,通过查文档/常用示例,经常用的就记住了,没怎么用的估计就用一次忘记一次了。从这个角度来说,命令行的option设计上,应该满足:最少但是足够完备 的方式,最少使得你仅仅只需要记住这些必要的option就能使用,足够完备使得需要的大部分功能都有。

类比GUI,还有一种常见的GUI是应付选项特别多的情况:向导。例如IDE创建Project一般就是会有一个step by step的向导,让你一步一步选择和填写必要的设置。同理,在命令行下,也有类似的方式:交互式命令行。通过交互式命令,一步一步的提问让你选择选项和填写必要的配置,最后一次性执行。或者不执行,只是生成合并后的命令,让你自己拷贝到脚本里执行等,相当于一种交互式的文档,读文档你还是要自己根据文档写命令,交互式的方式直接通过分支裁剪你的需求生成你要的命令。这样,命令行可以通过交互式的方式提供一种更友好的「文档」,类似于游戏里的新手练习区。

命令行

标签:任务   循环   tcp协议   wget   tom   data   有一个   url   概念   

原文地址:https://www.cnblogs.com/math/p/cli.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!