Shell简介及自己动手实现一个Shell
引入
一个运行在操作系统之上的应用程序必须通过操作系统提供的统一接口,而这部分接口大多使用C/C++定义,应用程序通过固定编码调用操作系统统一封装的接口实现对内核、系统库或三方库的调用。在日常使用中编码势必带来诸多不便,因此Shell运势而生。 Shell:文本命令解析器,通过交互式解析用户输入的字符串命令或则文件提供的命令集,实现对应用程序、系统程序或内核的调用。
一、常见Shell
操作系统 | 常用Shell |
---|---|
Windows | Cmd、PowerShell |
Mac/Linux | bash、zsh、sh等 |
二、bash
本文以Linux下最为常用的bash为例,对bash的一些特性做简单讲解
2.1 bash特性
| 快捷操作 | TAB:TAB两次显示所有相关命令,TAB单次补全命令
Ctrl+C:终止当前命令运行 | |
---|---|
历史记录 | 运行命令自动记录,可通过history查看历史 |
别名 | 通过alias和unalias命令设置和取消别名 |
一些shell还针对命令有特殊解析,比如zsh将无法识别的命令作为路径进行cd
2.2 bash命令优先级
优先级 | 解释 | 举例 |
---|---|---|
alias | 设置的别名 | alias ll=‘ls -al’ |
built_in | bash内建定义的命令解析 | echo、export、alias、unalias |
hash | 使用过的命令将其路径缓存 | |
PATH | 外部环境变量命令,在硬盘中有路径存储的命令 | $PATH |
其中alias、内建命令和hash是bash提供的高级功能,PATH是系统提供的变量
常见bash内建命令
命令 | 解释 | 举例 |
---|---|---|
alias | 为命令设置别名 | alias ll=‘ls -al’ |
unalias | 取消设置别名 | unalias ll |
export | 设置环境变量 | export name=zhangsan |
echo | 输出打印,支持环境变量等 | echo $name |
help | 命令的帮助文档 | help echo |
type | 查看命令的类型 | type echo |
三、自己动手写Shell
3.1 效果演示
通过简单实现一个命令解析器goshell,能交互式解析和解析命令集合,并实现一个自定义的打印命令。
|
|
|
|
|
|
3.2 goshell的逻辑伪代码
|
|
注:这种实现方式在实现逻辑上就缺少bash中alias、hash的支持,也不如bash实现的内建命令多,但基本能满足一个命令解释器的该有的功能。
四、一些有用的命令
4.1 命令系统调用跟踪-strace
通过使用命令strace
命令查看跟踪命令执行过程中所有的系统调用
|
|
4.2 命令CPU执行时间跟踪-time
|
|
响应结果:
- real:完整执行时长
- user:用户CPU占用时长
- sys:系统CPU占用时长
4.3 java
java命令用于解释class文件、并在java虚拟机上执行,因java使用的广泛性,现针对java多版本管理工具做简单介绍。 sdkman sdkman是类Unix上的开发工具sdk管理工具(仅支持Linux、MacOS),可以方便的管理开发工具sdk的安装、卸载、版本切换等。支持包括gradle、maven项目管理工具、java、kotlin编程语言、springboot、vertx框架等。
|
|
jEnv jEnv是一款 Java 多版本管理工具,它为安装,切换,删除和列出候选提供了一个方便的命令行界面。支持Linux、Mac和Windows(参考FelixSelter/JEnv-for-Windows)
|
|