Linux 导入
大纲
- 发展历史
- 系统目录结构
- Shell 之 Bash
- 常用命令分享
发展历史
Unix 和 Linux
Unix操作系统在20世纪60年代构思完成并实现,并在1970年首次发布。由我们的C语言之父,丹尼斯·里奇和肯·汤普逊 自行开发。它因容易获取与可移植性高而广泛被学术机构和工商企业采用、复制和修改。它的设计对其他系统的作者影响很大。
早期的Unix以低廉甚至免费的许可将Unix源码授权给学术机构做研究或教学之用,但是后来AT&T公司意识到了Unix的商业价值,不再将Unix源码授权给学术机构,并对之前的Unix及其变种声明了著作权权利。BSD在Unix的历史发展中具有相当大的影响力,被很多商业厂家采用,成为很多商用Unix的基础。其不断增大的影响力终于引起了AT&T的关注,于是开始了一场持久的著作权官司,这场官司一直打到AT&T将自己的Unix系统实验室卖掉。
- 1983:Richard Stallman(理查德·斯托曼)发起以创建一个自由的操作系统为目标的GNU计划。发起了自由软件运动,理查德·斯托曼作为主要开发者的他开发了一些被广泛使用的GNU软件,其中包括GCC、GDB、GNU Emacs。
- 1989:Richard Stallman(理查德·斯托曼)撰写第一版的GNU GPL。
- 1991:Linux内核在8月25日由21岁的芬兰学生Linus Benedict Torvalds公开发布。开发是在Minix上,用至今仍为首选的编译器GCC来完成的(林纳斯·托瓦兹不喜欢他的386电脑上的MS-DOS操作系统,而安装了Minix,并以它为样本开发了原始的Linux核心)
- 1992:在GNU GPL下Linux内核被重新授权使用,产生第一个“Linux发行版本”。
开源 + Linux内核 + GPL许可下的软件 促进了Linux 的发展
SHELL
Shell 在计算机科学中指“为用户提供用户界面”的软件,通常指的是命令行界面的解析器。一般来说,这个词是指操作系统中提供访问内核所提供之服务的程序。Shell也用于泛指所有为用户提供操作界面的程序,也就是程序和用户交互的层面。因此与之相对的是内核(Kernel),内核不提供和用户的交互功能。
- 第一个Unix shell是由肯·汤普逊,仿效Multics上的shell所实现出来,称为sh
- 在第一次发布的Linux内核版本0.01中包含了GNU的Bash的二进制版本
- 现在 Linux 默认使用的Shell是 bash
系统目录结构
Shell 之 Bash
Shell 的类型有很多,常用的有 Bash zsh fish ,这里我们简单介绍系统默认 Shell 之 Bash.
Builtin (内置命令)
提问?: `cd`命令有没有具体的二进制?
bash 提供了很多基本的内置命令,可以满足系统的基本使用
常见的有:
- cd
- alias
- echo
- kill
- printf
- pwd
可以使用 enable
来打开或者禁用
特殊参数
shell 中参数输出是使用 $ 表示。
shell 对一些参数做特殊处理。这些参数只能被引用而不能被赋值。
* 位置参数,从 1开始。如果扩展发生在双引号中,它扩展为一个词,值是各个参数,以特殊变量 IFS 的第一个字符分隔。也就是说,"$*" 等价于 "$1c$2c...",这里 c 是变量 IFS 的第一个字符。如果没有设置 IFS, 那么参数将用空格分隔。
@ 位置参数,从 1开始。如果扩展发生在双引号中,每个参数都将扩展为一个词。也就是说, "$@" 等价于 "$1" "$2" ... 如果位置参数不存在,"$@" 和 $@ 扩展为空 (即,它们被删除了)。
# 位置参数的个数,以十进制表示。
? 最近执行的前一个命令的状态。
$ shell 的进程 ID。在一个 () 子 shell 中,它扩展为当前 shell 的 进程 ID 而不是子 shell 的。
! 最近一次执行的后台 (异步) 命令的进程号。
0 shell 或者 shell 脚本的名称。这个变量是在 shell 初始化时设置的。如果 bash 是执行脚本文件时启动的, $0 将设置为那个文件的名称。如果 bash 启动时的参数包含 -c, 那么 $0 被设置为启动命令行被执行后的第一个参数,如果有的话。否则,它被设置为用来启动 bash 的文件名,就是参数 0。
function test1(){ echo $*; echo $@; echo $#; echo $$; echo $0 $1 $2; }
特殊文件描述符
- /dev/stdin 文件描述符 0
- /dev/stdout 文件描述符 1
- /dev/stderr 文件描述符 2
ll /proc/$$/fd
输入/输出重定向
- command > file 将输出重定向到 file。 可以用于快速清空文件。
echo 1 > file
- command < file 将输入重定向到 file。
cat < file cat 0<file
- command >> file 将输出以追加的方式重定向到 file。
echo 1 >> file
- n > file 将文件描述符为 n 的文件重定向到 file。
echo 1 1> file echo 1 2> file
- n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
echo 1 1>> file echo 1 2> file
- n >& m 将输出文件 m 和 n 合并。
lw 1>file 2>&1
- << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
- &> 标准输出与标准错误输出重定向
ls &>file lw &>file
来一个好玩的
nc -l -k 8888
bash &> /dev/tcp/127.0.0.1/8888 0>&1
管道
管道是一个或者多个命令的序列,使用字符 | 分割, 管道符左边命令的输出就会作为管道符右边命令的输入。
ls -1 | wc -l
ps aux | grep top
常用命令分享
Linux 下一切皆文件, 怎么理解这句话呢?
lsof
lsof(list open files)是一个查看当前系统文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,该文件描述符提供了大量关于这个应用程序本身的信息。
lsof打开的文件可以是:
- 普通文件
- 目录
- 网络文件系统的文件
4 字符或设备文件 - (函数)共享库
- 管道,命名管道
- 符号链接
- 网络文件(例如:NFS file、网络socket,unix域名socket)
- 还有其它类型的文件,等等
命令参数
- -a 列出打开文件存在的进程
- -c<进程名> 列出指定进程所打开的文件
- -g 列出GID号进程详情
- -d<文件号> 列出占用该文件号的进程
- +d<目录> 列出目录下被打开的文件
- +D<目录> 递归列出目录下被打开的文件
- -n<目录> 列出使用NFS的文件
- -i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip )
- -p<进程号> 列出指定进程号所打开的文件
- -u 列出UID号进程详情
- -h 显示帮助信息
- -v 显示版本信息
可以帮助解决的问题
- 列出所有打开的文件
lsof
- 查找某个文件相关的进程
lsof /bin/bash
- 列出某个用户打开的文件信息
lsof soul
- 列出某个程序进程所打开的文件信息
lsof -c xxx
- 通过某个进程号显示该进程打开的文件
lsof -p 11968
- 列出所有的网络连接
lsof -i
- 列出所有tcp 网络连接信息
lsof -i tcp
- 列出谁在使用某个端口
lsof -i :3306
top
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。
$top
top - 09:14:56 up 264 days, 20:56, 1 user, load average: 0.02, 0.04, 0.00
Tasks: 87 total, 1 running, 86 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.2%st
Mem: 377672k total, 322332k used, 55340k free, 32592k buffers
Swap: 397308k total, 67192k used, 330116k free, 71900k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 2856 656 388 S 0.0 0.2 0:49.40 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 7:15.20 ksoftirqd/0
4 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
-
第一行
- 09:14:56 : 系统当前时间
- 264 days, 20:56 : 系统开机到现在经过了多少时间
- 1 users : 当前2用户在线
- load average: 0.02, 0.04, 0.00: 系统1分钟、5分钟、15分钟的CPU负载信息
-
第二行
- Tasks:任务;
- 87 total:很好理解,就是当前有87个任务,也就是87个进程。
- 1 running:1个进程正在运行
- 86 sleeping:86个进程睡眠
- 0 stopped:停止的进程数
- 0 zombie:僵死的进程数
-
第三行
- Cpu(s):表示这一行显示CPU总体信息
- 0.0%us:用户态进程占用CPU时间百分比,不包含renice值为负的任务占用的CPU的时间。
- 0.7%sy:内核占用CPU时间百分比
- 0.0%ni:改变过优先级的进程占用CPU的百分比
- 99.3%id:空闲CPU时间百分比
- 0.0%wa:等待I/O的CPU时间百分比
- 0.0%hi:CPU硬中断时间百分比
- 0.0%si:CPU软中断时间百分比
- 注:这里显示数据是所有cpu的平均值,如果想看每一个cpu的处理情况,按1即可;折叠,再次按1;
-
第四行
- Men:内存的意思
- 8175320kk total:物理内存总量
- 8058868k used:使用的物理内存量
- 116452k free:空闲的物理内存量
- 283084k buffers:用作内核缓存的物理内存量
-
第五行
- Swap:交换空间
- 6881272k total:交换区总量
- 4010444k used:使用的交换区量
- 2870828k free:空闲的交换区量
- 4336992k cached:缓冲交换区总量
-
进程信息
- 再下面就是进程信息:
- PID:进程的ID
- USER:进程所有者
- PR:进程的优先级别,越小越优先被执行
- NInice:值
- VIRT:进程占用的虚拟内存
- RES:进程占用的物理内存
- SHR:进程使用的共享内存
- S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
- %CPU:进程占用CPU的使用率
- %MEM:进程使用的物理内存和总内存的百分比
- TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
- COMMAND:进程启动命令名称
验证
使用 strace
命令找到程序打开的文件,strace
是一个可以跟踪系统调用的执行的命令
- 可以使用
strace + binary
输出系统调用的名字 - 可以通过pid attach到运行中的进程中
- top命令的输出那么多,我要找到它对应的数据来源
strace -f top -p 1 -n 1 2>&1 | grep open # 执行一次top命令并过滤出 open 的系统调用
- 一个网络链接,查看数据写入到客户端
#终端1 启动一个监听端口 9999 服务端
nc -l -k 9999
#终端2
strace -f -p $(pidof nc)
#终端3 客户端
nc 127.0.0.1 9999
- 分析上面的bash反弹shell的命令
nc -l -k 8888
bash &> /dev/tcp/127.0.0.1/8888 0>&1