大家好,欢迎来到IT知识分享网。
1&2 Unix操作系统
1-计算机主板及结构
PC机的主板与结构
组成: 北桥/南桥、CPU、RAM、USB插槽、PCI插槽、SATA接口
结构:
2-Unix的特点
- 可移植
- 多用户
- 多任务
- 分级系统
- 与设备独立的输入和输出操作
- 用户界面shell
- 一系列系统工具
3-Unix的发展历程
Linux是Unix的克隆,但不是Unix
3 Unix入门
1-登录与退出
登录:
login:username password:*//不会显示
修改密码:passwd
新旧口令要求至少3个字符不同
至少长6个字符且要有两个字母一个数字
口令不能与用户标识相同
退出:[Ctrl+d]或exit
2-常见命令格式
【$ 命令 -选项 参数】
命令名要求小写,可以是一个可执行程序、脚本程序、shell内置程序等
– 字符
— 单词
3-基本命令
日期和时间:date
用户信息:who
who am i //我登录的情况 who -q 或 --count //只显示用户名和用户数量 who -H 或 --heading //显示Header who -b //显示系统的启动日期和时间(boot)
日历:cal
cal //当前年月 cal 2020 cal 3 2020 /*cal 10: wrong*/
4-帮助
learn
help
man
(manual)
分卷、分节:
man 3 printf //3指明查找的卷号
4-shell种类
字符界面下,用户登录系统后,由shell负责与用户交互
- sh
- ksh
- csh
- bash
- dash
安装dash:
su
apt install dash
切换shell:
dash
chsh //改变登录的缺省shell(change shell)
用户的相关消息记录在/etc/passwd
cat /etc/passwd //查看
5-登录与退出过程
Unix系统启动后,int/systemd进程负责拉起用户进程
考察:
ps //打印系统当前进程 ps -ejH //按树形结构打印
init进程是1号进程,systemd=init,是所有进程的父进程
agetty=getty
A fork B,AB一样,但B是由A创建的
B exec login B执行login程序
6-其他
[ctrl-h]
删除一个字符
[ctrl-u]
删除整个命令行
[del]
或[ctrl-c]
中断运行
4 Vi编辑器入门
1-编辑器基础知识
编辑器是用于制作文档或文本的程序
eg.文档:word
文本:vscode sublime atom
- 图形化文本编辑器
- 字符界面文本编辑器
- 行编辑器
全屏编辑器 - vi/vim(全屏)
- emacs(行)
- nano
- 行编辑器
2-vi编辑器
启动:vi或view(只读) 可加参数(文档名)
工作模式:
- 命令模式
- 插入模式
- 命令行模式
- visual模式
状态行(第24行)
退出::q!
升级版vi:vim
安装:
su apt install vim
3-vi编辑器基本命令
- 切换模式
默认进入命令模式,按ZZ
从命令模式退出程序;
按:
进入命令行模式,回车退出到命令模式,按:q!/:wq/q
退出程序;
从命令模式进入文本模式:i
在光标前插入文本I
在光标所在行首插入文本a
在光标后加入文本A
在光标所在行尾插入文本o
在光标所在行下增加一行O
在光标所在行上增加一行
按
ESC
退出到命令模式; - 创建和编辑文件:vi+文档名
- 移动光标:命令模式下
h j k l
左下上右,不会正文回绕0/^
行首,不会正文回绕$
行尾,不会正文回绕w
向后移动一个word,会正文回绕b
向前到word开头,会正文回绕e
向后到word尾部,会正文回绕空格
向后一格回车
下一行行首,不会正文回绕退格
向前一格
文本输入模式
空格
插入一个空格回车
新建一行退格
回退一格
- 插入文本:即由命令模式输入i I a A o O字符进入输入模式
- 删除文本:命令模式下
x
删除光标所在字符 (5x
删除5个字符)dd
删除光标所在行 (3dd
删除3行)u
撤销最近修改U
撤销当前行所有修改r
替换光标所在字符R
替换从光标开始的字符,++进入输入模式++.
重复上次修改
- 搜索文本:命令模式下
/
向后搜索?
向前搜素n
按搜索方向搜索下一个匹配项
- 保存文本:
:wq
保存后退出:q
未修改退出:q!
不保存退出:w
保存不退出,后面加文件名可另存为一个新文件ZZ
保存后退出
- 帮助:命令行模式下(冒号进入命令行模式)
:help x
搜索命令模式下的x命令
:helpgrep
以grep方式搜索
help中按ctrl+[
可以跳转至对应章节
:q!
退出helpvimtutor:vi教程
$ vimtutor
进入
4-vi缓冲原理
5 文件系统介绍
1-磁盘与文件
磁盘上的数据以文件形式组织
文件是操作系统对io设备的一个抽象,进程/线程是对执行过程的抽象
文件分类:
- 普通文件:文本、脚本、程序
- 目录文件:目录以树的形式组织文件,本身是一个文件
- 特殊文件:io设备等
目录结构以层次形式组织,称为层次结构
2-目录与文件
- Unix重要的目录:
- / 根目录
- /usr 用户目录,可能是/home
- /usr/include 库头文件位置
- /usr/bin 用户可执行文件
- /usr/local 自行编译安装目录
- /root 管理员目录
- /boot 自举目录
- /bin 可执行文件
- /dev 设备文件
- /sbin 管理程序目录
- /etc 配置文件目录
- /home 用户目录
- /var 常变动文件,如数据库、日志
- 正在使用的目录:工作目录或当前目录
- 绝对路径:从是以/开头,从根目录开始,相对路径:从当前目录开始直到文件,开头不会是/
注:dos下用\ .
当前目录..
父目录- 文件命名规范:
- 避免使用:
<>,(),[],{},*,?,",',-,$,^
- 使用扩展名提升可读性
- 大小写敏感,目录和文件可以同名,不同目录下文件可同名
- 避免使用:
3-目录操作
pwd
打印当前工作目录的绝对路径cd
改变当前工作目录(缺参数默认回到主目录)cd -
返回上次工作目录cd ~
返回主目录
mkdir
创建目录mkdir -p xx/yy/zz
创建多层目录
rmdir
删除目录- 空目录无法删除
- 要在父目录或更高层的目录下才可删除子目录
ls
打印目录下的子目录与文件(缺参数默认打印当前目录)ls -a
打印含隐藏文件的所有文件ls -C
列排序ls -x
行排序ls -F
目录后加/,可执行文件后加*ls -p
目录后加/ls -l
详细信息ls -m
按页宽列出文件,逗号隔开ls -r
反字母顺序ls -R
循环列出子目录内容ls -s
按块为单位列出文件大小
- 注意:
(1) 多重选项 eg.ls -alr
ls -a -l -r
(2)ls-l
的结果分析:
文件类型:-普通文件、d目录、c字符设备(打印机)、b块设备(磁盘)、I符号连接
权限:r读、w写、x执行(文件)或访问(目录)、-无权限
人物:文件所有者、同组用户、其他用户
链接数、创建人、组名、文件大小、日期时间、文件名。
(3) 隐藏文件:以.开头的文件,排序是按去点后的字母顺序排序
4-文件操作
cat
显示文件(创建和连接)cat file1
显示当前目录中的file1cat file1 file2
相继显示当前目录中的file1、file2- 显示最后23行,其他内容上翻过去了。
停止上翻Crtl-s
,继续上翻Ctrl-q
。
touch
创建一个空文件lp
打印文件- 未指定文件名时打印键盘输入内容,
Ctrl-d
结束键盘输入 lp -d 打印机 文件名
指定打印机打印lp -m
打印完发送邮件lp -n
打印指定份数 eg.lp -n5
lp -s
取消反馈信息lp -t 字符串 文件名
在输出标题页上打印指定标题(第一页)lp -w
打印完成向终端发送消息lpr
Lunix命令
- 未指定文件名时打印键盘输入内容,
cancel
取消打印文件- 指定打印机(只取消正在打印的作业,其余仍进行)或打印作业Id名
lpstat
获取打印机消息lpstat -d
找出系统默认打印机
rm
删除文件rm -i
删除前给出确认消息(y
确认n
取消)rm -r
删除指定目录下所有子目录和文件rm -r *
删除从工作目录开始的所有目录和文件rm -f
忽略不存在文件且不给提示
6 VI高级用法
1-vi的启动选项
- vi是ex编辑器得一部分,
:Q
切换到ex编辑器;q
退出回到shell;vi
回到vi。 - 不提供文件名启动vi(新建文件)
vi :w myfile(文件名) :wq myfile(文件名)
注意:不可覆盖同名已存在文件,:w!
强制覆盖。
vi myfile :w yourfile(新文件名) //保存到新文件,编辑文件仍为myfile :wq yourfile(新文件名) //保存到新文件,原文件不变
- 启动选项:
-R
只读- 但可以通过
:wq!
强制保存用户自己的只读文件,系统文件不可强制更改。 view
模式
- 但可以通过
-c
允许用户将指定的vi命令作为命令行一部分
如:$ vi -c /most myfile
搜索most移动光标至第一个most处
2-多文件编辑
- vim内部每个buffer打开一个文件,多个buffer可以打开同一个文件
可以只有一个窗口,也可以有多个tab标签。每个tab对应一个buffer,一个buffer可以对应多个tab。 - 启动时给出多个文件名,编辑完一个后自动进入下一个
-
:n
打开下一个文件:n!
不保存当前文件打开下一个:ar
查看文件名列表:e
+文件名编辑另一个文件:r
引入另一个文件内容到当前文件光标后一行:5 100 w newfile
将当前文件的5~100行写入新文件中(w!可以覆盖同名已存在文件)
- 每个buffer开一个文件、多个buffer可以打开同一文件,编辑会同步展示。(缓冲区)
可以只有一个窗口,也可以有多个tab标签。每个tab对应一个buffer,一个buffer可以对应多个tab。(窗口) - 这里描述的vim使用方式,是希望能在vim中完成大多数工作,而不是频繁的退出vim。
:tabnew
创建一个标签:e
打开一个文件 //:o
也可以:tabnext
在窗口上打开下一个tab:tabprevious
在窗口上打开前一个tab:q
或者:tabclose
关闭tab
- 设置tab标签快捷键(自定义)
nnoremap<C-Left>:tabprevious<CR> nnoremap<C-Right>:tabnext<CR> nnoremap<Tab>:tab sball<CR>
3-寄存器
vim中设计了特别的暂存机制——寄存器,用于保存拷贝和删除的文本
在命令模式下:以 ” 双引号开头 引用这些寄存器
命令行模式:registers或:reg
显示寄存器
eg.:reg "1
:reg 1
:查看寄存器1的内容,:1p
也可以
- 有名寄存器:a-z,一共26个,供用户使用
"+小写字母+指令
:完成指令,并将对应区域文本存在寄存器中,不需要按回车。
- 编号寄存器:0-9,10个,vim自己使用,存放删除和拷贝的文本,保存内容无大小限制
- “0号寄存器是visual模式下拷贝的问题,如yy拷贝的行文本
- “1-“9号寄存器是dd删除的行文本
"+数字+p或P
:找回数字编号下缓冲区内容
- 缺省寄存器:
%
当前窗口对应的文件名#
当前窗口的其它文件名:
命令行模式最近输入的命令.
最近插入的文本"
最近删除或拷贝的文本,put时从这里出
4-Motion与range
- motion是指移动光标的命令(域)
命令=操作符+motion
$
域为光标至行尾0或^
域为光标至行首e或w
域为光标至当前字尾b
域为光标至当前字首
- 想将行作为命令的域,按两次操作符键
- range是指行数
寄存器+[range]+d/y+[motion]
:完成拷贝/删除动作->寄存器
eg.- “wdd 删除当前行到”w寄存器
- “z7yy 拷贝从当前光标开始算,一共7行,到”z寄存器
寄存器+p
:将寄存器内容拷贝到光标后的位置上,完成寄存器->缓冲动作
3dw
vi删除3个字和后面的空格
5-剪切与粘贴
- 命令模式下:
d
将删除指定位置文本,同时拷贝到””和”1寄存器,并且下压2-9号寄存器y
将拷贝指定位置文本,同时复制到””和”0寄存器p
将缺省寄存器””内容拷贝到光标位置之后P
将缺省寄存器””内容拷贝到光标位置之前c
删除文件并进入文本输入模式
- 命令模式下v进入visual模式:
- khjl或方向键 移动光标,从初始光标位置开始到移动终点部分文字被选中
y
将选择内容拷贝到””和”0寄存器,y表示yank
- 拷贝与删除命令可与motion组合
6-光标快速定位
命令行模式:
:n
定位到第n行的行首:0或:1
定位到第1行的行首:$
定位到最后一行的行首
注意:命令模式下按$定位到该行的行尾。
命令模式:
G或0G
定位到最后一行的行首nG
定位到第n行的行首Ctrl-g 或 :=
在命令行区域输出当前行Ctrl-End 或 G$
跳到最后一个字符Ctrl-d
下移光标12行downCtrl-u
上移光标12行upCtrl-f
下移光标24行forwardCtrl-b
上移光标24行
7-vim定制
- 让vim更舒服一些,修改.exrc或者.vimrc
- :set命令
:set all
显示所有选项:set
显示被修改的选项:set X?
显示选项X的值
- 选项的分类:布尔、数字式、串
- 布尔:
set X
set noX
- 数字:
set X=n(数字)
- 串:
set=XX
- 布尔:
- 常见的vi环境选项:(要求不高)
autoindent
新行与上一行首对齐ignorecase
搜索忽略大小写magic
允许搜索时用特殊字符number
显示行号report
通知用户上一个命令影响的行号scroll
设定CTRL+d翻动的页数shiftwidth
缩进空格数tabstep
tab的空格数
- 折叠{}代码块*(不考)*
set foldenable set foldmethod=indent zc 关闭折叠 zo 打开折叠
- 深度定制:缩写与宏*(不考,略)*
8-执行shell命令
:shell
切换到shell界面,exit
回到vim
:!
执行shell命令,切换到shell界面,但不会提示下一步输入
:r!
将shell命令输出粘贴到当前位置
7.1 Emacs编辑器
- Emacs内部集成lisp脚本语言,高度定制化 eg.spacemacs
Emacs是一种生活,打开emacs在其中可以完成一切工作 - apt install emacs-nox
7.2 正则表达式
- Unix系统偏好于以可读的文本处理
- vi、emacs、grep、sed、awk都支持正则表达式
- systemd
- 正则表达式RE(Regular Expression)是一种语言,这种语言表现为一种的表达式
RE可以完全的表示有限自动机DFA、NFA
RE主要用于定义词法 - Posix标准中RE分为BRE(基础)、ERE(拓展)
- RE字符集:
特别的:
- [[:alnum:]] 字符+数字
- [[:alpha:]] 字符
- [[:digit:]] 数字
- [[:lower:]] 小写字符
- [[:upper:]] 大写字符
- [[:space:]] 空白字符
- 注:若写为[[:alnum:]_!]等方式,表示除字符和数字外还可以取_或!。
- 详细内容与实例:
注意:行匹配,结尾\n结束一行。.
匹配单个字符r. //r后加任一字符 .x. //任何两个字符中间夹一个x,不要求两个字符相同
^
锚定行首,从行首开始匹配^后的内容。^George //匹配出现在行首的George ^\. //匹配出现在行首的. ^. //匹配出现在行首的任意一个字符
$
锚定行尾,从行尾开始匹配$前的内容。today$ //匹配出现在行尾的today \.$ //匹配出现在行尾的. .$ //匹配出现在行尾的任意一个字符 ^$ //匹配不含字符的行(无意义) ^ $ //匹配只有单个空格的行
[]
匹配括号内的某个字符。(或的关系)[tT]he //匹配the和The [0-9] //匹配数字0~9 [A-Z] //匹配大写的字母 [A-Za-z] //匹配大写或小写字母 [^A-Z] //匹配除大写字母以外的任何字符 [^A-Za-z] //匹配非字母的字符 [-0-9] //匹配一个连字符-或数字 []a-z] //匹配一个右方括弧或小写字母 注意:右方括号必须放在最前面的[(或^)后,连字符必须放在最前面的[(或^)后或者最后的]前
*
匹配任意个(包括0个)紧靠在*前的字符,表示匹配的次数X* //匹配 0、1、2……个X XX* //匹配 1、2、3……个X .* //表示0或若干个任何字符 注意:正则表达式总是寻求最大匹配,因此上式多匹配一行。 e.*e //匹配一行中第一个e和最后一个e间的所有内容 [A-Za-z][A-Za-z]* //匹配任何1个或多个字母
\{…\}
匹配精确数目的字符串
{min,max}X\{1,10\} //匹配 1~10 个连续的X 注意:正则表达式总是寻求最大匹配,即有11个连续的X视为匹配了两个项,一个10个X,一个1个X//? [A-Za-z]\{4,7\} //匹配 4~7 个字母序列 \{10\} //匹配的必须是10个字符长度 .\{10\} //匹配10个字符 [A-Za-z]\{10\} //匹配10个字母 +\{5,\} //匹配至少5个连续的+号
\(…\)
保存匹配的字符串,\n引用定义的位置,n的范围从1~9^\(.\) //将行首的第一个字符并保存 ^\(.\)\1 //匹配行首的第一个字符并保存到寄存器1,与第二个字符对比,相等则匹配 ^\(.\).*\1$ //匹配行首字母和行尾字母相同的行,中间夹着的字符数量不受限制 ^\(...\)\(...\) //将行中头三个字符存在1号寄存器中,接着3个字符存在2号寄存器中
应用实例:
c[aeiouy]t 匹配可以是cat、cet、cot等
[0] 可表示为`[0-9]
[.] 匹配或\或.
[].] 匹配]或或\或.
[-.] 匹配-或或\或.
[].-] 匹配]或或\或.或-
(ab)(cd)[def]\2\1 匹配abcdecdab或abcdfcdab或bcddcdab
(why).\1 匹配whyXXwhy
([[:alpha:]][[:alnum:]]*) = \1 一个语言赋值语句,如a_3 = b4c_c
^ABC 行首有ABC的行被匹配
Def$ 行尾有Def的行被匹配
7.3 vi的正则表达式搜索
首先检查magic变量:set magic?
,一般默认magic。
help magic
可查看下表了解vi中的正则表达式规则
应用:
- 搜索:
/或?
后跟一个RE表达式 - 替换:(模仿sed命令)
:range s/from/to/flags
from和to分别表示要被替换和替换的内容
range表示行范围,%是全局所有行(1,$表示从1行到尾行)
flags为g表示这一行中所有的匹配项都替换,不带g则只会替换符合条件的第一个。
:%s/from/to/g
最常用
作业
- 匹配c语言头文件.h的正则表达式,匹配.c文件的正则表达式
- 空行的正则表达式
^[[:space:]]*$
- 已知搜索结果格式为
用户名:……:主目录:登录使用的shell
搜索/etc/passwd文件中用户名的正则表达式
搜索/etc/passwd文件中用户shell的正则表达式
搜索/etc/passwd文件中用户主目录的正则表达式(涉及sed,不做) - 在vim中替换文件中所有Block字符串为Page的命令
8 文件系统高级操作
1-重定向
- C语言程序一般会打开三个缺省文件,stdin、stdout、stderr,文件描述符分别是0,1,2。
- 在Unix系统中,文件是io的基本抽象。标准输入、标准输出、错误输出可以替换为其它文件。
- 标准输出重定向
command > file //把命令执行结果存放到文件中,替换标准输出 command >> file //追加到文件末尾
- 标准输入重定向
command < file //不用标准输入来执行命令,用文件内容 command << EOF //标准输入,当碰到EOF字符串时,输入结束
- 标准错误输出重定向
command 2> file //将command命令的错误输出重定向到file文件里 command 2>> file //追加重定向
- 重定向标准输出+标准错误输出
command &> file //把标准输出和错误输出都放到一个文件里 command &>> file //追加重定向
- 特别文件
/dev/null (bit垃圾桶)
command > /dev/null //把输出放到垃圾桶里 command < /dev/null //从垃圾桶倒出全零,用于清空文件、引导记录
- 利用重定向创建文件
cat命令不带参数,以标准输入作为输入
cat > file,以标准输入作为输入,输出重定向的file,创建文件
cat >> file,以标准输入作为输入,在文件末尾追加文件内容
cat file1 > file2,以file1作为输入,输出重定向的file2,拷贝文件
cat file1 file2 > file3,以file1,file2作为输入,输出重定向到file3,合并两个文件
cat > file1 << EOF,标准输入到文件file1,以EOF作为输入结束标志
注:没有指定<<字符串时ctrl-d
可结束文件输入 - 重定向如何实现
2-管道
- shell将一个程序的标准输出作为另一个程序的标准输入,形成管道(pipeline)
command A | command B
注意:两条命令之间是以一个匿名文件传输ls –al | grep -e “^d” ls -al | less
- 原理:
3-文件操作
cp
拷贝源文件成目标文件,注意默认当前目录,要提供准确的文件路径名。cp source target //将源文件内容复制到目标文件下。若目标文件已存在则覆盖。 cp source1 (source2 …) 目录名 //将多个文件复制到一个目录下,目标文件与源文件同名。
-b
如果目标文件存在,创建备份~(防止覆盖)-i
如果目标文件存在,提示-r
递归拷贝,将目录复制到新的目录
mv
移动文件,提供准确的文件路径名。mv file1 file2 //将原文件名更名为目标文件名。 mv source1 (source2 …) 目录名 //将多个文件移动到一个目录下。
-b
如果目标文件存在,创建备份~(防止覆盖)-i
如果目标文件存在,提示-f
强制移动
wc
统计文本字数,第一列行数,第二列字数,第三列字符数。
注意:字定义为没有空格(空格或制表符)的字符序列wc //未指定文件名时从标准输入(键盘)获取输入 wc file1 file2 //指定多个文件时分行显示,最后一行显示总数。
-l
统计行数-w
统计单词数量-c
统计字符数量
eg. ls *.h | wc -l //统计头文件数量 eg. wc -l /etc/passwd //统计用户数量
head
显示文件头部,缺省显示头部10行,可以指定多个文件-n
显示头部n行-l
显示头部10行(默认)-c
显示头部10个字符-c n
显示头部n个字符,n为正整数
tail
显示文件尾部,缺省显示尾部10行,可以指定多个文件-n
显示尾部n行-l
显示尾部10行(默认)-c
显示尾部10个字符-c n
显示尾部n个字符
tail 11 file //显示尾部11行 tail -4 file //显示尾部4行 tail +50 file //跳过文件前50行,显示剩余部分
cut
纵向输出文件某列或某域,默认分隔符是制表符-f LIST
指定剪切的域-c LIST
指定剪切字符位置-d x
指定域的分隔符x,可以是空格或%或:等,注意有特殊意义的字符要用双引号括起来:“ ”。- LIST为如下形式:
n-m
表示[n,m]的域,n,m
表示n和m域
paste
横向连接两个文件,缺省分隔符是TAB制表符-d x
指定域的分隔符x
more
分页显示文件内容,后翻不可前翻[Return]
下翻一行[Spacebar]
下翻一页,两屏间两行重复显示[Q或q]
退出-lines
显示指定行数+lines
从指定行数开始显示+ /pattern
从包含pattern的上面两行开始显示-c
显示每页前清屏而不是翻动-d
显示提示=
看当前行h
查看可用选项列表(帮助)
less
同上但可前翻sort
按照行做字典序排列文件内容,注:按照字典序:空格等非文字数字字符前于数字前于大写字母前于小写字母(Unix使用ASCII排序,数字按照第一个数位排序而不是数值大小)-b
忽略行首空格-d
字典序比较,忽略标点和控制符号-t
指定域分隔符-f
忽略大小写-n
数字以数值大小排序-r
逆序排列-o
指定输出文件+num
排序前跳过num个字段(默认分隔符为制表符)
sort /etc/passwd //排序所有用户 sort -t: -n +2 /etc/passwd //按uid排列所有用户(:为分隔符、以数字大小排序、对第二个字段排序)
grep
打开文件,在文件中以RE方式搜索字符串,可以指定多个文件,样式内容是含有空格和元字符的字符串时要用双引号括起来。
如:grep "#include<private.h>"*.c
在c源文件中查找字符串”#include<private.h>”。
grep [OPTION] PATTERNS [FILE]
-c
只显示匹配的行数-l
只显示具有匹配行的文件名-i
忽略大小写匹配-G
BRE,grep缺省-E
ERE,egrep缺省-e PATTERNS
指定一个或多个RE-v
只显示不匹配的行-n
输出行号
练习
ls -al | grep -e '^d' //查找当前目录下的子目录 ls -al /dev | grep -e '^c' //查找/dev目录下的所有字符型设备 ls -al | grep -e '^d' | wc -l //统计当前目录下的子目录个数 ls -al /dev | grep -e '^c' -c 或 ls -al /dev | grep -e '^c' | wc -l //查找/dev目录下的所有字符型设备个数 more /var/log/dpkg.log 或 less /var/log/dpkg.log //翻看/var/log/dpkg.log grep -e ' installed ' /var/log/dpkg.log //搜索/var/log/dpkg.log中安装的package grep -e ' installed ' /var/log/dpkg.log | wc -l //根据/var/log/dpkg.log统计安装的package tail -20 /var/log/dpkg.log //查看/var/log/dpkg.log尾部20行 sort -t: -n +3 /etc/passwd //按照组id(第四个字段)排序/etc/passwd
4-文件系统原理
- Unix有三大抽象:(1)进程、线程对执行过程(2)文件对io(3)地址空间对内存
- Unix有四种io:文件系统、块设备、字符设备、socket。
- 块设备和字符设备出现在文件系统的名字空间
- Socket仅表现为文件,但不出现在文件系统
- 磁盘文件组织,需要从几个维度去考虑磁盘如何组织成文件:快速访问、方便修改、节省空间。
- 考虑磁盘的空间组织,主要有几种形式:
- 变长的堆,顺序放在磁盘(主要形式)
- 定长的记录(数据库)
- 索引(快速访问)
- Unix文件系统的选择:堆+索引
- 索引 key->value,key是文件名,要求变长结构。将文件名收集形成目录文件。
- 而关于文件的定位和状态放在inode结点,是定长结构。
- 典型Unix磁盘布局:
MBR主引导记录–分区表(DOS有4个分区)–
Boot block自举块–inodes–Files and directories存放文件(堆形式)–
7. 目录文件 -> i-node -> data
(ls –i显示节点)
- ln链接,在已存在文件和新文件名间创立链接。
ln [OPTION]... [-T] TARGET LINK_NAME
ln命令不会创建新的i-node,而是引用已有i-node,增加引用计数(硬连接)
ln –s符号链接,分配一个新的inode,内部记录指向原有文件(软连接),文件用ls -al查看时以l开头。
符号化链接指向初始文件,初始文件被删除该符号链接就不再起作用,链接得到的文件主人为链接操作者,文件链接数为1,文件大小为链接的地址包含的字符串大小;ls-Ll可获取符号化列表所指向的文件详细信息。删除符号化链接所指向的初始文件会使符号链接变得无效。
注意:有时文件被删但符号连接的指针仍在,会找不到文件。inodes资源有限,硬连接会挤占资源。软连接会创建新的inode,保存文件属性。
- 当改变任何一个链接文件的内容,无论使用哪个名字,这些文件都会改变。
- 如果指定已经存在的目录名作为新文件名,用户可以访问该目录下的文件而不用输入文件名。
- ls -l 输出的第二列显示链接数。每个文件的链接数至少为1,指的是目录和文件的链接。
实例
移动文件到不同目录,inode不会发生变化
touch一个文件,创建目录项?inode?分配数据块?
9 探索shell
1-shell工作原理
- /etc/passwd决定了用户登录后执行的shell程序
有些特殊的用户,可以不是shell程序 - shell解析用户命令
- 创建子进程执行用户命令
- shell等待命令子进程退出
- 命令子进程退出,发送SIGCHLD信号给shell
- shell在信号处理函数中处理子进程退出
- shell进程退出
- 发送SIGCHLD信号给login进程
- login进程处理SIGCHLD信号
- 退出,发送SIGCHLD信号给init进程
- init进程处理SIGCHLD信号,重新fork/exec一个getty进程
init–(fork)->getty–(exec)->login–(fork)->bash–(fork)->command
bash<—command回收子进程执行完成后的状态
注意:
(1)纵轴表示的是生存时间
(2)方框内表示一个类,加了:表示一个实例
(3)登陆后login始终wait bash退出
(4)退出bash后返回消息给login,login返回消息给init,之后init fork一个getty进程在终端等候
- 注意bash退出:
ctrl-d
exit(并不是一个程序)内置命令 builtin
所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。
http://c.biancheng.net/view/1136.html
- shell内置命令可以替换一些经常使用的命令,部分提升性能
- man bash
- 搜索:SHELL BUILTIN COMMANDS
- source、alias、echo、cd、eval、exec、export、let、pwd、history、printf、set、unset、test等
- Special building command -> function -> building command -> export command
- 内置命令区分出special原因是某些内置命令允许function重载
- echo命令输出字符串
echo "…"
不同的Unix系统对echo的命令做了选项扩展(不要求)
如果是格式化输出,使用printfprintf "%d" &x
2-shell语言
- shell是一种语言、负责与用户交互
- 变量
- 命令
- 循环与分支
- 命令的语法
命令+空格+[选项]+参数+(;|回车)
eg.echo hello; ls -al
多行单条命令,一行的尾部以\结束ls \ -al
完整的命令解析过程:
- tilde是~表达式展开
- 变量替换
- 命令展开是重音符的命令展开
- 单词划分利用$IFS变量分割
- 寻找命令
3-shell变量
- shell内置一个变量表(哈希表)
每个变量有环境变量或局部变量属性
变量名->字符串(无类型) - 环境变量
父进程会将环境变量传递给子进程(fork)
C语言getenv()函数 set
命令显示所有变量,export
命令显示所有环境变量- 添加修改变量
VAR=xxx
添加普通变量
注意:等号两侧不能由空格:=前加空格会走命令解析过程,会把var看成命令,=及后面内容看成参数;=后面加空格会把空格也算进字符串
export VAR=xxx
添加环境变量 - 引用环境变量
$VAR
或者${VAR}
- 标准变量
- HOME变量记录用户主目录
HOME=/usr //修改主目录 cd
- PATH变量给出外部程序的搜索路径
echo $PATH
:分割符dash //dash PATH= //清空PATH变量 which pwd //查找当前工作路径 exit
- IFS变量定义扩展命令参数时的分隔符(教材的例子是错的)
- HOME变量记录用户主目录
4-参数展开
- shell在解释命令时,有一个重要的步骤是展开变量得到命令参数
ls -al * //给shell,根据空格抽取各部分token
shell在解释这条命令时,ls是命令,special builtins(特别内置命令) -> functions(用户定义函数) -> builtins(内置命令) -> export command(在PATH中去查找),-al是一个参数,*需要展开(最先完成参数展开) - shell内部将对参数的展开
- -开头当成选项
- 双引号、单引号、重音符号开头作为字符串
- $开头作为变量
- <>作为重定向符号
- |作为管道符号
- 其余字符串如果包含*?[]需要做路径匹配展开
- shell路径元字符
注意:shell元字符并非正则表达式!- ?匹配路径名的单个字符(正则:
.
) - * 匹配路径名的任意长度字符串(正则:
.*
) - [list] 匹配list中任意一个字符
- [!list] 匹配不在list中的任意一个字符(正则求反:^)
- [abc] //匹配abc
- [a-z] //匹配a-z任一
- [!a-z] //匹配非a-z
- [a-z!] //匹配a-z及!任一
- ?匹配路径名的单个字符(正则:
- 反斜杠\转义,取消元字符语义
rm temp? //匹配temp1、temp2… rm temp\?//匹配temp?
echo <>”‘`$*?&|\
- 双引号,单引号字符串
shell不将双引号、单引号字符串看成路径名- 双引号字符串需要展开 V A R 变量,单引号,重音符号 e c h o “ VAR变量,单引号,重音符号 echo “ VAR变量,单引号,重音符号echo“HOME”
- 单引号字符串不会展开
echo ‘$HOME’ - 重音符号表示一个内嵌命令,要先执行,然后得到输出作为参数
双引号内的重音符号要先执行:echo “`ls -al`”
注意:如果输出有*可能会被解析,所以最好加双引号
5-find与xargs
- find命令在文件目录树中查找文件
find start-point tests action
- 从start-point开始查找(start-point是一个路径)
- tests做测试(找什么)
- 满足条件执行action(做什么)
- tests测试条件:
name “filename”
根据给定filename做匹配查找size +-n
查找大小为n的文件type filetype
查找指定类型filetype的文件atime n
查找access访问时间的问题mtime n
查找修改时间的文件- 其中:type
- type f 普通文件
- type d 目录文件
注意:
name “*.c”
,这个模式是shell的路径匹配模式,直接写成-name *.c
不行。首先++文件通配符++和++正则表达式++含义是不同的。最大的差别在于:
(1)"*"
在正则表达式中表示前面的字符重复任意次数,所以表示任意字符串".*"
, shell通配符中*
就表示任意字符串
(2)"."
在正则表达式中是任意个字符,在通配符中没有其他任何含义,在通配符中"?"
表示一个任意的字符
shell本身会对*进行解析,所以如果不希望shell解析“*”,就一定要把通配符用双引号括起来(单引号使用后就什么都替换不了)
ls -l ab*
这个*由shell来解析的,假如目录下面有ab1 abc ab2,那这个命令首先会被shel转化为ls -l ab1 abc ab2
。ls本身没有解析通配符的能力。ls -l "ab*"
,那就会什么都没有,因为没有一个文件的名字是ab*find . -name "abc*"
这个参数会原封不动的传给find,find命令本身具备解析通配符的能力,会在当前目录下面的各级目录下面寻找以abc开头的文件。find . -name abc*
那通配符会被shell解析,如果当前目录下没有以abc开头的文件,那传给find命令的就是空的,相当于:find . -name find: missing argument to' -name'
如果当前目录下游多个abc开头的文件,会出错,相当于:
find . -name abc1 abc2 find: paths must precede expression: abc2
就是说第二个name前面没有指定寻找的路径;
如果当前目录下面只有一个abc开头的文件,那就不会出错,但是相当于:find . -name abc1
最终最在所有的目录下面搜索abc1的文件,和我们的本意大相径庭。记住,-name选项搜索的是basename,不要再里面带””.
- action选项:(不要求)
print
打印输出exec command
执行命令ok command
在执行命令前要求确认
- xargs从标准输入上读,将标准输入文件按照空格/TAB拆解成参数,作为command执行参数。
xargs [command [initial-arguments]]
查找epoll_wait函数在那个文件: find /usr/include –name “*.h” -type f | xargs grep “epoll_wait”
xargs与管道区别的相关资料 https://www.cnblogs.com/wangqiguo/p/6464234.html
6-shell配置
- 用户登录,启动缺省shell
man bash,查找INVOCATION
/etc/profile -> ~/.bash_profile -> ~/.bash_login -> ~/.profile - 如果不是login启动的shell
/etc/bash.bashrc -> ~/.bashrc - 用户退出
~/.bashr_logout
7-进程控制命令
- ps命令显示进程(不要求)
-a
显示所有进程,但不包括会话leader,不包括无终端进程-f
显示进程完整信息-e
显示所有进程-H
按照树形显示-j
按照job形式输出-ejH
树形输出所有进程
- kill杀死进程
kill命令向进程发送信号
缺省发送SIGTERM信号,15-l
列出所有信号-1
除init进程以及自己以外的所有进程-s
发送s标志的信号77
对77号进程操作-7
发送7号信号
信号类似于硬件中断
Ctrl-c -> 发送SIGINT信号
Ctrl-d -> 发送EOF,意思是输入关闭
- trap设置进程捕获信号后如何处理
中断服务程序&信号服务程序
trap “command” signal numbers
trap ‘’ TERM 忽略SIGTERM信号
trap – TERM 恢复SIGTERM信号缺省处理
问题:trap设置的是当前进程——bash进程的信号处理函数,如何保证子进程依然是这个动作?
8-前台后台
- shell命令使用 & 表示 后台执行
ping www.baidu.com > /dev/null &
- jobs命令是一个(内置)builtin命令,可列举后台执行的作业
man bash搜索SHELL BUILTIN COMMANDS - fg命令把后台作业切至前台
fg jobspec 作业编号用jobs命令查询 - nohup “command”&
后台执行命令,并且该命令在用户退出登录后仍然执行
9-History和fc
- Bash在执行命令后,会在内存中记录所有使用的命令。
当用户退出登录,所有命令保存在~/.bash_history文件中
history命令则列出到目前为止,执行的所有命令。
~/.bash_history记录的是到上次退出前的所有命令。 - fc是一个(内置)builtin命令
man bash搜索SHELL BUILTIN COMMANDS
fc first last //命令先编辑从first到last的命令,然后执行
fc –s cmd //cmd是history的命令编号,执行该编号任务 - alias是一个(内置)builtin命令
alias ll=‘ls –al’
tee命令分离输出,同时输出到标准输出和文件
ls -al | tee dir.list-a
追击到文件-i
忽略中断信号
练习:
搜索/usr/include目录下名字为fuse.h
在/usr/include目录下搜索包含EPOLLIN的头文件
列出/etc/passwd文件的用户名+登录目录
统计一个项目中的.h/.c文件的行数,要求排除空行
man tr,然后利用tr命令将一个dos结尾的\r\n文本文件变换为Unix结尾的\n
阅读.bashrc和.profile文件
10 UNIX通信
- 接口与状态
ifconfig / ip addr netstat / ss ping
- ssh
安装openssh服务su apt install openssh-client apt install openssh-server
ssh客户端操作
ssh ip-address,交互式操作 scp src dst,scp://[user@]host[:port][/path] sftp
- curl安装
su apt install curl
- wget
- ftp
- systemd
system daemon,代替常用的System V与BSD风格init程序
init采用脚本来加载各种服务,各种服务的依赖难以维持,服务加载速度慢
systemd使用c编写的程序接管各种服务加载- Log
- Timer
- Service
- Swap
- Device
- Socket
- …
- Init:T1+T2+…+T7
Upstart:T1+T2+T3
Systemd:即时发现依赖 >T1
- Socket依赖
- Inetd
- Fork创建后描述符继承
D-bus依赖 - Networkmanager
文件依赖 - 内核automounter 模块、
unit声明依赖
- 利用Cgroup管理进程生命周期
Fork两次之后,父子进程关系链条断裂
10.Systemd的设计模仿了Windows和MacOS
与Linux内核严重耦合,其它开源系统无法使用
结构复杂,功能强大,违反了keep it stupid simple,kiss原则
要求管理员抛弃init脚本,重新学习
11.Systemd管理的对象抽象为单元(unit),man 5 systemd.unit- service 单元,封装后台服务进程
- socket 单元,封装有名管道
- target 单元,组合多个单元
- device 单元,封装设备文件,可用于基于设备的启动
- mount 单元,封装文件系统挂载点,/etc/fstab
- automount 单元,封装文件系统自动挂载点,仅在挂载点被访问时才进行挂载,取代传统的 autofs 服务
- timer 单元,封装基于时间触发的动作
- swap 单元,封装交换分区或者交换文件
- path 单元,根据文件系统上特定对象的变化来启动其他服务
- slice 单元,控制特定 CGroup 内(例如一组 service 与 scope 单元)所有进程的总体资源占用
- scope 单元,与 service 单元类似,但是由 systemd 根据 D-bus接口接收到的信息自动创建, 可用于管理外部创建的进程
- Unit文件目录,man 5 systemd.unit
- 系统unit文件目录
- 用户unit文件目录
- Systemctl
- Systemctl –a
- Systemctl status
11 GUN工具链
- GUN工具链
https://my.fsf.org/civicrm/contribute/transact?reset=1&id=57
Gnu toolchain是开发操作系统、应用程序的一套完整的程序和库,包括gcc、gdb、glibc:
- cpp
- m4
- gas
- gcc、g++
- ld
- glibc、libc++
- gdb
- makefile
- libtool
- binutils: ar、objdump、c++filt、nm、readelf等
- autoconf、automake
相当与工业制造中的母机
- gcc是一族编译器,包括c、c++、go、java等
前端+后端- .c为后缀的文件,C语言源代码文件;
- .a为后缀的文件,是由目标文件构成的档案库文件;
- .C、.cc或.cxx 为后缀的文件,是C++源代码文件;
- .h为后缀的文件,是程序所包含的头文件;
- .i 为后缀的文件,是已经预处理过的C源代码文件;
- .ii为后缀的文件,是已经预处理过的C++源代码文件;
- .m为后缀的文件,是Objective-C源代码文件;
- .o为后缀的文件,是编译后的目标文件;
- .s为后缀的文件,是汇编语言源代码文件;
- .S为后缀的文件,是经过预编译的汇编语言源代码文件。
C语言编译过程
gcc -E hello.c -o hello.i gcc -S hello.i -o hello.s gcc -c hello.s -o hello.o gcc -o hello hello.o
- gdb
#include <stdio.h> int main(int argc, char *argv[]) { for(int i=0, j=0; i < 10; ++i) { j += 5; printf("j=%d\n", j); } return 0; }
- makefile
Makefile用于工程组织和编译
与常见的命令式语言不同,它是一种依赖推导语言
Shell语言:变量定义+命令执行
Makefile:变量定义+依赖描述
例子:count_words: count_words.o lexer.o -lfl gcc count_words.o lexer.o -lfl -o count_words target: dependencies, … actions
显式规则与隐式规则
%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
推导规则- 检查目标和依赖文件的时间,如果依赖更新,则执行动作
- 显式规则 > 隐式规则
推导过程 - 动态规划
- 从target出发,枚举所有规则,直到依赖可达
- 反过来行不行?
Makefile的主要问题 - 推导结论没有显式导出,不便于理解
- 应该保存为中间结果,下次编译直接调用
- 中间结果保存为一棵树,同时编译
5.cmake
cross platform make跨平台自动化建置系统
Cmake vs Makefile - Makefile的依赖推导不直观
- Cmake的语法设计采用命令式
- 跨平台,可以导出为makefile、sln等
Cmake在不同平台上生成不同的本地化脚本 - Linux下的Gnu Makefile
- Visual Studio的sln
- Google等ninja
Cmake管理的代码编译主要有两步: - 利用cmake生成本地编译脚本
- 利用本地脚本编译程序
基本语法 - 定义工程
- 设置变量
- 添加可执行目标
- 添加递归目录
- 添加静态库、动态库
- 条件分支
- 定制命令和目标add_custom_command/add_custom_target
6.git
版本控制系统(Version Control System,简称VCS)是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 - 本地版本控制系统
- 集中化的版本控制系统
- 分布式版本控制系统
Git的分布式管理
Git的分支管理:围绕主干开发
主要命令
- git init
- git clone
- git status
- git add
- git commit
- git log
- git fetch [remote-name]
- git push [remote-name] [branch-name]
- git branch
12 Shell编程
1-脚本
- Shell是一种语言,可分类为bash(对shell有扩展)、csh…
- Unix的传统是提供基本的功能,由用户自行扩展,包括自己编写shell脚本
cat > won //定义一个won脚本文件 who | wc –l //统计登陆的用户数量 Ctrl-d //结束输入脚本
- 执行脚本:
sh won
- 自包含脚本文件:
#! /bin/sh
或#! /bin/bash
要修改为可执行文件(chmod将该文件从rw变为rwx可执行)
- 执行脚本:
- 自包含脚本工作原理:
(1)won为第一个token,解释为命令,到$PATH中寻找路径
(2)确认是否为可执行文件
(3)loader程序加载脚本,发现不是elf可执行文件,返回错误(非elf格式loader不接受)
(4)bash收到错误,然后打开文件头部#! /bin/sh,发现是脚本,指明了使用/bin/sh执行
(5)调用脚本执行 - 基于兼容性考虑
#! /bin/sh:bash–(fork)–/bin/sh–(分别fork新的子进程)执行echo和ls
Debian上的/bin/sh符号链接指向dash
dash对标准的兼容性更好 - 注意:#开始到行尾均为注释
2-调试技术
- echo命令输出参数
echo “hello, world” echo * echo含有\*的时候会进行shell匹配,有匹配结果输出结果,没有匹配结果直接显示*\
- set打开调试
- set -x命令打开执行命令输出,输出的是带参数展开后的命令
set -x
echo *(*会被结果替换)
set +x 关闭 - set –v命令输出参数替换前的命令
set -v
echo *
set +v 关闭
- set -x命令打开执行命令输出,输出的是带参数展开后的命令
3-变量
- 变量赋值
VAR=xxx
(注意不能加空格)、环境变量export VAR=xxx
/局部变量等知识在上一章介绍 - 变量引用要看成字符串$VAR
- 变量替换操作(不要求)
${VAR:-word}
如果变量不存在,返回word${VAR:=word}
如果变量不存在,设置VAR变量为word,返回word${VAR:?message}
如果变量不存在,打印message,退出,但交互shell不会退出${VAR:+word}
如果变量存在,返回word;否则返回null
- 删除变量:
unset VAR
- 位置参数是一种特殊的变量,用于表示命令行参数
- $1- 9 , 9, 9,{10}表示参数
- $0表示命令名
- $#表示参数个数
- ∗ 将所有参数使用 *将所有参数使用 ∗将所有参数使用IFS隔开,形成一个字符串
- $@是每个参数一行
例:用++set++命令改变命令行参数(set是bash内置命令)
set hello “I love bash” world
echo $0:-bash
echo $1:hello
echo $2:I love bash
echo $3:world
echo $*:hello I love bash world 合并所有为一个字符串
echo $@:hello I love bash world 可以枚举
- 特殊变量
- $?表示进程退出状态
ls -al hello echo $? errno num查询错误码看看是什么错误
- $$表示当前进程id
- $?表示进程退出状态
4-算术表达式
- Shell中变量都是字符串,计算算术的时候使用$(())作为算术表达式,不提倡用let
echo $((3+2)) $((3+2))
- 算术运算符:++、–、+、-、!、~(按位求反)、*、/、%等
i=3 echo $((i++)) $i //先输出i后将i+1赋值给i,输出3 4 echo $((++i)) $i //先输出i+1的结果后将i+1赋值给i,输出5 5
注意算术表达式中,true=1,false=0
echo $((3==3))
:1
5-逻辑连接
- 使用&&和||连接两条命令
- &&表示and
- ||表示or
- 逻辑短路
- Command1 && command2,当command1正确执行,才会执行command2
- Command1 || command2,当command1执行错误,才会执行command2;若command1执行正确,不会执行command2
6-命令分块
Shell中使用分号;将多条命令分开,然后利用()将多条命令组合成一块
- 单行
- ()表示当前shell执行
7-条件分支
if 条件; then command lines [elif 条件 command lines] [else command lines] fi 或 if 条件 then command lines [elif 条件 command lines] [else command lines] fi
- 条件是一段命令,测试的是$?是否是0
++为0满足条件(正确执行)
不为0,不满足条件++
因此test $((3>2)) = 1;或[ $((3>2)) = 1 ];才可以正确判断。 - test或者[ … ]是测试条件:
test EXPRESSION
- 测试字符串表达式:
=
“$STR1” = “STR2” //两个字符串是否相同!=
“$STR1” != “STR2” //两个字符串是否不同-n
-n “$STR” //字符串不是null-z
-z “$STR” //字符串是null- 注意:
在引用变量做字符串测试时,一定要加引号
操作符两侧必须有空格
[ … ]中括号内两侧必须有空格
- 文件测试:
-r
-r filename //filename文件是否可读-w
-w filename //filename文件是否可写-s
-s filename //filename文件是否存在并且长度非0-f
-f filename //filename文件是否是普通文件-d
-d filename //filename文件是否是目录文件
touch xx; [ -s xx ]; echo $? [ -f xx ]; echo $?
- 算术表达式测试:
利用$(())计算算算术表达式
利用字符串比较[ $((2+3)) = 5 ]; echo $?输出0 //字符串比较 i=3; [ $((i+7)) = 10 ]; echo $?输出0 中括号内接受算术表达式:[ $((3+2 > 1)) ]; echo $?输出0 $((3+2 > 1)); echo $?输出1
注意:在if中使用算术表达式,Bash中扩展(()),但dash中有错
- 空指令用冒号或true来表示。
case $1 in -f) … ;; -d | --directory) #竖线表示或,而[...]表示从中选取一个 … ;; *) … ;; esac
- 测试字符串表达式:
8-循环
- Shell提供三种循环:for、while、until
循环与分支类似,都带有一定的结构,是shell语言的支持- 基本格式如下
for variable in list-of-values; do … done
#! /bin/sh echo for count in 1 2 3; do #注意这里的变量没有$ echo “In the loop for $count times” done
#! /bin/sh read filename for FILE in $filename; do echo “filename is $FILE\n” done
注意:read是一个builtin命令,它从标准输入读入一行
- 表示枚举所有参数
for variable; do …
- While循环的格式如下
while [ condition ]; do … done
#! /bin/sh carryon=Y while [ $carryon = Y ]; do printf “I do the job as long as you type Y: ” read $carryon done
#! /bin/sh count=1 while [ $((count < 10)) = “1” ]; do echo $count count=$((count+1)) done
- Until循环的格式如下
until [ condition ]; do … done
Until表示条件为假时,执行循环体
#! /bin/sh count=1 until [ $((count < 10)) = “0” ]; do echo $count count=$((count+1)) done
9-函数
- 函数定义
[function] funname() #()不可以带参数
{
…
} - 函数引用,类似于普通命令
- 参数传递
- 但是函数执行,类似于内置命令,不会新fork一个shell
- return n表示函数返回值
. command
命令执行command,但不会去fork一个新进程,修改了.bashrc文件,需要执行- printf命令兼容所有shell,其命令方式与c类似
echo命令参数不兼容
count=3
printf “count=%d\n” $count - df显示可用空间
du统计文件或者目录的磁盘使用情况tar zcfv压缩成.tar.gz文件
tar zxfv解压.tar.gz文件
tar Jcfv压缩成.tar.xz文件
tar Jxfv解压.tar.xz文件
tar jcfv压缩成.tar.bz2文件
tar jxfv解压.tar.bz2文件 - chmod修改文件目录的访问权限
[ugoa]±=rwx
chown修改文件目录的owner
chgrp修改文件目录的group
/etc/profile
/etc/bash.bashrc
/etc/init.d/networking
作业
习题:6、7、8
阅读:/etc/rc5.d/S01ssh, /etc/rc5.d/S01cron
编程:利用curl、wget,编写一个脚本从cn.bing.com下载当日墙纸
13 编写shell脚本
- 信号命令
在unix系统中,信号被设计为“软中断”
进程类比于一个程序,信号从各个侧面完整的模拟了中断机制- 中断掩码 信号掩码
- 中断源 信号
- 不可屏蔽中断 不可屏蔽信号
- ISR 信号处理函数
信号列表64个 - kill –l
- kill –n pid
trap设置进程捕获函数:trap “命令” n
忽略信号:trap “ ” n
恢复缺省:trap n - 终端命令
stty设定终端模式- stty –echo禁止回显,输入口令时
- stty echo打开回显
tput控制终端输出缓冲 - tput clear清屏
- tput cup row column移动光标到row行column列
- 程序
补充命令
- sed
- tr
- shift
- eval
- 编写一个脚本,输入变量名,然后输出该变量的值
- eval echo $$1
- $()
- 等价于重音符号
- echo
date
- echo $(date)
- echo $(ls -al)
- break
continue - true
false
: - return 函数返回值
! command
求反
! ls -al
echo ? t e s t ! “ ? test ! “ ?test!“s” = “hello”
[ ! “$s” = “hello” ]- 条件与或
- [ -z $VAR ] && [ ${VAR2} = 3 ]
- [ -z $VAR ] || [ ${VAR2} = 3 ]
条件非
- [ ! ${VAR2} = 3 ]
- 要确定VAR是否已经定义,否则是语法错误
unset VAR [ $VAR = “hello” ] [ “$VAR” = “hello” ]
- case的匹配模式
- *)
- -v|–verbose)
- -v*)
- -v[hc])
- -v?)
- $@ vs $*
#! /bin/sh for i in "$@"; do case $i in -v) echo "verbose";; -k) echo "kite";; *) echo "default";; esac done
测试:
- @ − > “ @ -> “ @−>“@”
- ∗ − > “ * -> “ ∗−>“*”
- ./a.sh “-k -v”
- ./a.sh -k -v
结论:使用”$@”
作业:
搜索/exam目录下.txt文件,然后将以\r\n结尾的dos文本文件,修改为unix结尾的\n文件,同时将原dos文件保留为.txt.bak文件
求解斐波那契数列,例如./fab.sh 5输出
0 1 1 2 3 5
编写一个脚本,接受多个输入参数,输出最大值,./greatest 3 9 5,输出为:
The largest number is: 9
利用case语句编写脚本判断选项:
-d选项输出debug
-v选项输出verbose
其它选项输出usage $0 -d|-v
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/146767.html