学习shell与shell script
vim 程序编辑器
系统管理员的重要工作就是修改与设置某些重要的配置文件,因此至少得要学会一种以上的命令行界面的文本编辑器。在所有的Linux distributions上头都会有一套文本编辑器就是vi,而且很多软件默认也是使用vi作为它们编辑的界面,因此务必要学会使用vi这个强大的文本编辑器。此外,vim是高级版的vi,vim不但可以用不同的颜色显示文字内容,还能进行诸如shell脚本,C等程序编辑功能,你可以将vim视为一种程序编辑器。
vi与vim
在Linux的世界中,绝大部份的配置文件都是一ASCII的纯文本形式存在,因此利用简单的文字编辑软件就能够修改设置了。与微软的Windows系统不同的是,如果你用惯了Microsoft Word或Corel Wordperfect的话,那么除了X Window里面的图形界面编辑程序(如Emacs)用起来尚可应付外,在Linux的文本模式下,会觉得文本编辑程序都没有图形界面来的直观与方便。
那么Linux在命令行界面下的文本编辑器有哪些呢?其实有非常多。经常听到的就有Emacs,pico,nano,joe与vim等。既然有那么多命令行界面的文本编辑器,那么我们为什么要学vi?还有那个vim是做啥用的?下面就来谈一谈先。
为何要学vim
主要有下面几个点:
- 所有的UNIX Like系统都会内置vi 文本编辑器,其他的文本编辑器则不一定存在
- 很多软件的编辑接口都会主动调用vi(crontab,visudo,edquota等命令)
- vim具有程序编辑的能力,可以主动以字体颜色辨别语法的正确性,方便程序设计
- 程序简单,编辑速度相当快
vi的使用
基本上vi共分为3中模式,分别是一般模式、编辑模式和命令行模式。这3种模式的作用分别如下
一般模式
以vi打开一个文件就直接进入一般模式了(默认模式)。在这个模式种,你可以使用上下左右按键来移动光标,你可以删除字符或者删除整行,也可以复制、粘贴你的文件数据编辑模式
在一般模式中可以进行删除、复制、粘贴等操作,但是却无法编辑文件内容。要等到你按下“i,I,o,O,A,r,R”等任何一个字母之后才会进入编辑模式。通常在Linux中,按下这些按键时,在界面的左下方会出现INSERT或REPLACE的字样,此时才可以进行编辑。而如果要回到一般模式时,则必须要按下【Esc】这个按键即可退出编辑模式命令行模式
在一般模式中,输入“:、/、?”3个中的任何一个按钮,就可以将光标移动到最下面那一行。在这个模式中,可以提供你查找数据的操作,而读取、保存、大量替换字符、离开vi、显示行号等的操作则是在此模式中完成的。
简单执行范例
- 使用vi进入一般模式
vi 文件名(可以是久文件也可以是新文件)
按下i进入编辑模式开始编辑文字
在一般模式中,只要按下“i,o,a”等字符就可以进入编辑模式了。在编辑模式中,你可以发现左下角状态栏中会出现Insert字样,那就是可以输入任意字符的提示。这个时候键盘上除了Esc这个按键外,按下其他的按键都可以视为一般的输入了。按下【Esc】键回到一般模式
在一般模式下输入“:wq”保存后离开vi
按键说明
除了上面简易范例的I,【Esc】、:wq之外,其实vim还有非常多的按键可以使用。在介绍之前还是要再次强调,vim的三种模式只有一般模式可以与编辑、命令行模式切换,编辑模式与命令行模式之间并不能切换。下面来看看vim中常用的按键功能。
第一部分:一般模式可用的按键说明,光标移动、复制粘贴、查找替换等,如下
移动光标的方法
h或向左箭头(⬅️) | 光标向左移动一个字符 |
---|---|
j或向右箭头(➡️) | 光标向右移动一个字符 |
k或向上箭头(⬆️) | 光标向上移动一个字符 |
l或向下箭头(⬇️) | 光标向下移动一个字符 |
Ctrl + f | 屏幕向下移动一页 |
Ctrl + b | 屏幕向上移动一页 |
Ctrl + d | 屏幕向下移动半页 |
Ctrl + u | 屏幕向上移动半页 |
+ | 光标移动到非空格字符的下一行 |
- | 光标移动到非空格字符的上一行 |
0或功能键(Home) | 这是数字“0”,移动到这一行的最前面字符处 |
$ 或功能键(End) | 移动到这一行的最后面字符处 |
H | 光标移动到这个屏幕的最上方那一行的第一个字符 |
M | 光标移动到这个屏幕中央那一行的第一个字符 |
L | 光标移动到这个屏幕最下方那一行的第一个字符 |
G | 移动到这个文件的最后一行 |
nG | n为数字,移动到这个文件的第n行 |
gg | 移动到这个文件的第一行 |
N【Enter】 | n为数字。光标向下移动n行 |
J | 将光标所在行与下一行的数据结合成一行 |
c | 重复删除多个数据,如:10cj向下删除10行 |
u | 复原前一个操作 |
Ctrl+r | 重做上一个操作 |
. | 重复前一个操作 |
查找与替换
/word | 向下寻找一个名称为word的字符串 |
---|---|
?word | 向上寻找一个名称为word的字符串 |
n | 这个n是英文键。代表重复前一个查找的操作 |
N | 这个N是英文键。与n刚好相反,为“反向”进行前一个查找操作 |
:n1,n2s/word1/word2/g | n1与n2为数字。在第n1与n2行之间寻找word1这个字符,并将该字符替换为word2,例如:“:100,200s/vbird/VBIRD/g” 代表在100到200行之间查找vbird并替换为VBIRD |
:1,$s/word1/word2/g | 从第一行到最后一行查找word1,并将其替换为word2 |
:1,$s/word1/word2/gc | 从第一行到最后一行查找word1,并将其替换为word2.且在替换前给用户操作确认 |
删除、复制与粘贴
x,X | 在一行当中,x为向后删除一个字符(相当于Del),X为向前删除一个字符(相当于Backspace) |
---|---|
nx | n为数字,连续向后删除n个字符 |
dd | 删除光标所在的那一整行 |
ndd | n为数字。删除光标所在的向下n行 |
d1G | 删除光标所在到第一行的数据 |
dG | 删除光标所在到最后一行的数据 |
d$ | 删除从光标所在处到该行的最后一个字符 |
d0 | 数字0,删除从光标所在处到该行的最前面一个字符 |
yy | 复制光标所在的那一行 |
nyy | 复制光标所在的向下n行 |
y1G | 复制光标所在行到第一行的数据 |
yG | 复制光标所在行到最后一行的数据 |
y0 | 复制光标所在的那个字符到该行行首的所有数据 |
y$ | 复制光标所在的那个字符到该行行尾的所有数据 |
p,P | p为已复制的数据在光标下一行粘贴,P则为粘贴到上一行 |
第二部分:一般模式切换到编辑模式可用的按钮说明
i,I | i为从目前光标所在处插入,I为在目前所在行呢第一个非空格字符处开始插入 |
---|---|
a,A | a为从目前光标所在的下一个字符开始插入,A为从目前光标所在行的最后一个字符开始插入 |
o,O | o为在目前光标所在的下一行处插入新的一行;O为在目前光标所在处的上一行插入新的一行 |
r,R | r只会替换光标所在的那一个字符一次;R会一直替换光标所在的文字,直到按下Esc为止 |
Esc | 退出编辑模式 |
第三部分:一般模式切换到命令行模式可用的按钮说明
:w | 将编辑的数据写入硬盘文件中 |
---|---|
:w! | 若文件属性为-只读-,强制写入该文件。不过到底能不能写入还是跟你对该文件的文件权限有关 |
:q | 离开vi |
:q! | 若曾修改过文件,又不想存储。使用!为强制厉害不保存 |
:wq | 保存后并离开。“:wq!”则为强制保存并离开 |
ZZ | 若文件没有给改则不保存离开;若文件已经被更改则保存后离开 |
:w 【filename】 | 将编辑的数据保存为另一个文件 |
:r【filename】 | 在编辑的数据中,读入另一个文件的数据,即将“filename”这个文件内容加到光标所在行后面 |
:n1,n2 w【filename】 | 将n1到n2的内容保存到filename这个我文件 |
:!command | 暂时离开vi到命令行模式下执行command的显示结果 |
:set nu | 显示行号 |
:set nonu | 取消行号 |
vim的保存文件、恢复与打开时的警告信息
其实就是当我们使用vim编辑时,vim会在被编辑的文件的目录下新建一个名为.filename.swp 的文件。由于vim的工作被不正常的中断,导致暂存盘无法通过正常流程结束,所以暂存文件就不会消失,而继续保留下来。如果此时我们继续编辑那个文件,则会出现一些警告信息,出现这个问题的原因一般有两种:
可能其他人或者程序同时在编辑这个文件
你可以叫其他人中断vim的工作;或者你打开时选择 O 只读由于一些不明原因导致vim中断了(如 kill -9)
如果没有用可以直接按D删除;或者你也可以按R恢复,编辑完之后你要自行删除swp文件
vim的功能
块选择
其实就是以某种格式随心所欲的复制,删除一整块数据。常见命令如下
按键意义 | |
---|---|
V | 字符选择,会将光标经过的地方反白选择 |
v | 行选择,会将光标经过的行反白选择 |
ctrl+v | 块选择,可以用长方形的方式选择数据 |
y | 将反白的地方复制起来 |
d | 将反白的地方删除 |
多文件编辑
:n | 编辑下一个文件 |
:N | 编辑上一个文件 |
:files | 列出目前这个vim打开的所有文件 |
vim环境设置与记录:~/.vimrc,~/.viminfo
vim会主动将你曾经做过的行为记录下来,好让你下次可以轻松作业。那个记录操作的文件就是:~/viminfo.这个文件时自动产生的。但这些操作其实可以自行设置的,只要我们修改vim的环境配置即可,常见的配置有以下这些:
:set nu :set nonu | 设置与取消行号 |
---|---|
:set hlsearch :set nohlsearch | 高亮度查找。这个设置是否将查找的字符串反白 |
:set autoindent :set noautoindent | 表示是否自动缩排 |
:set backup | 表示是否自动保存备份文件,默认时nobackup,如果设置backup的话,那么当你该懂任何一个文件时,则原文件会被另存成一个文件名为filename~的文件 |
:set ruler | 显示或不显示右下角的状态栏说明 |
:set showmode | 这个则是是否要显示— INSERT—之类的字眼在左下角的状态栏 |
:set backspace(012) | 一般来说,我们按下i进入编辑模式后,可以利用退格键(backspace)来删除任意字符。但是,某些distribution则不许如此。此时,我们就可以通过backspace来设置。为2时代表可以删除任意值;0或1时仅可删除刚才输入的字符,而无法删除原本就已经存在的字符 |
:set all | 显示目前所有的环境参数设置值 |
总之,这些设置值很有用处的。但是我是否每次使用vim都要重新设置一次各个参数值?其实我们可以通过配置文件来这是规定我们的习惯。**整体vim的设置值一般是放置在/etc/vimrc这个文件中,不过不建议你修改它。你可以修改~/.vimrc这个文件**
其他vim使用注意事项
中文编码的问题
关于中文乱码的问题,可能跟下面几个方面有关:
1.你的Linux系统默认支持的语系数据:这与/etc/sysconfig/i18n有关
2.你的终端接口(bash)的语系:这与LANG这个变量有关
3.你的文件原本的编码
4.打开终端的软件,例如在GNOM下面的窗口界面
DOS与Linux的断行字符
DOS(Window)中使用的断行字符为^M)。由于断行字符的不同可能会出现未知的问题。这个时候可以用下面两个命令来转换:
dos2UNIX [-kn] file [new file]
UNIX2dos [-kn] file [new file]
-k:保留该文件原有的mtime时间格式
-n:保留原本的旧文件,将转换后的内容输出到新文件
语系编码转换
使用命令iconv来进行转换
iconv —list
iconv -f 原本编码 -t 新编码 filename 【-o newfile】
—list:列出iconv支持的语系数据
-f:from 后接原本的编码格式
-t:to 即后来的新编码要什么格式
-o file:如果要保留原本的文件,那么使用-o文件名,可以建立新编码文件
认识与学习Bash
在Linux环境下,如果你不懂bash是什么,那么其他的东西就不用学了。因为前面几章我们使用终端机执行命令的方式就是通过bash的环境来处理的。所以说它很重要。bash的东西非常多,包括变量的设置与使用、bash操作环境的构建、数据流重定向的功能,还有那好用的管道命令。
认识bash这个shell
在Linux中需要知道的是:管理这个计算机硬件的其实是操作系统的内核(kennel),这个内核是需要被保护的,所以我们一般用户就只能通过shell来跟内核通信,以让内核达到我们所想要达到的动作。
硬件、内核与bash
举个例子来说:当你要传输出来“音乐”的时候,你的计算机需要什么东西呢?
1.硬件:首先需要你的硬件有“声卡芯片”这个配备,不然怎么会有声音
2.内核管理:操作系统的内核可以支持这个芯片组,当然还需要提供芯片的驱动程序
3.应用程序:需要用户输入发生声音的命令
也就是说你必须要“输入”一个命令后,“硬件”才会通过你执行的命令来工作。那么硬件如何知道你执行的命令呢?那就是kernel的控制工作了。也就是说我们必须要通过“Shell”将我们输入的命令与内核通信,好让内核可以控制硬件来正确无误地工作。
**也就是说只要能够操作应用程序的接口都能够称为shell。狭义的shell指的是命令行方面的软件,包括本章要介绍的bash等。广义的shell则包括图形界面相关的软件,因为图形界面其实也能够操作各种应用程序来调用内核工作。**
为何要学习命令行界面的shell
- 命令行界面的shell:大家都一样
- 远程管理:命令行界面就是快
- Linux的任督二脉
bash shell的功能
命令记忆功能(history)
这个命令记录在你主文件夹的.bash_history中,需要注意的是该文件只会记录你前一次登录所执行过的命令,至于这一次登录所执行的命令都被暂存在临时内存中,当你成功注销后才会记录到.bash_history中
- 可以查询曾经做过的操作
命令与文件补全功能(tab键的好处)
tab接在一串命令的第一个字后面则为命令补全功能
- tab接在一串命令的第二个字以后时则为文件补齐
- 连续按两次tab键就能够显示所有的可执行命令
作业控制、前台、后台控制
这个后面再介绍程序脚本
- 在Linux下面使用shell script可以做很多事,这个也会在后面介绍
- 通配符
bash shell的内置命令:type
显示你的命令是内置的还是外部的
type 【-tpa】name
不加任何参数时,type会显示出name是外部命令还是bash内置命令
-t:type会将name以下面的这些字眼显示出它的意义:
file:表示为外部命令
alias:表示该命令为命令别名设置的名称
builtin:表示该命令为bash内置的命令功能
-p:如果后面接的name为外部命令时,才会显示完整文件名
-a:会由PATH变量定义的路径中,将所有含有name的命令都列出来,包含alias
命令的执行
当一条命令过长时需要换行,为来它的正确执行,可以使用反斜杠 \ 加回车实现
shell的变量功能
变量时bash环境中非常重要的玩意儿,我们知道Linux是多用户、多任务的环境。每个人登录系统都能取得一个bash,每个人都能够使用bash执行mail这个命令来收取“自己”的邮件,问题是bash是如何得知你的邮件邮箱是哪个呢?这就是变量的做用户了
什么是变量?
简单来说变量就是让某个特定字符代表不固定的内容罢了。在后续的使用shell script中,变量是一个非常好的帮手
变量的显示与设置:echo,unset
- 变量的显示:echo
echo $PATH
变量的设置规则
1.变量与变量内容一个等号“=”来连接如:“myname=Ligh”
“myname=Ligh cool”
- 双引号内的特殊字符如$,可以保有原本的特性
- 单引号内的特殊字符则仅为一般字符(纯文本)
命令
“PATH=“$PATH“:/home/bin ”
”export PATH“
环境变量的功能
- 用env查看环境变量与常见环境变量说明
env # 列出目前shell环境下所有环境变量与其说明
HOME
代表用户的主文件夹使用 cd ~ 命令SHELL
它告知我们目前这个环境使用的shell是哪个程序?Linux默认是/bin/bash;我的mac使用的是/bin/zshHISTSIZE
这个与历史命令有关,即是我们曾经执行过的命令可以被系统记录下来,而记录的条数由这个值设置MAIL
当我们使用mail这个命令在收信时系统会读取的邮箱信箱文件PATH
就是执行文件查找的路径,目录与目录中间以冒号(:)分割LANG
语系数据RANDOM
随机数生成器用set查看所有变量(含环境变量与自定义变量)
PS1(提示符的设置)
$
$本身也是一个变量。代表目前这个shell的线程代号,即所谓的PID。使用后echo $$?(关于上一个执行命令的回传码)
如果成功执行该命令,则会回传一个0export:自定义变量转成环境变量
环境变量与自定义变量的区别在于该变量是否会被子进程所引用。因为子进程仅会继承父进程的环境变量而不会继承父进程的自定义变量,这个时候export讲究很有作用了。使用export 变量名称即可
影响显示结果的语系变量(locale)
liguanghua@Lighs-MacBook-Pro ~ % locale
LANG=”zh_CN.UTF-8”
LC_COLLATE=”zh_CN.UTF-8”
LC_CTYPE=”zh_CN.UTF-8”
LC_MESSAGES=”zh_CN.UTF-8”
LC_MONETARY=”zh_CN.UTF-8”
LC_NUMERIC=”zh_CN.UTF-8”
LC_TIME=”zh_CN.UTF-8”
LC_ALL=
变量的有效范围
- 当启动一个shell,操作系统会分配一记忆块给shell使用,此内存的变量可让子进程取用;
- 若父进程利用export功能,可以让自定义变量的内容写到上述的记忆块中(环境变量)
- 当加载另一个shell时(即启动子进程而离开原本的辅警称了),子shell可以将父shell的环境变量所在的记忆块倒入自己的环境变量块当中
变量键盘读取、数组与声明:read,array,declare
- read
读取来自键盘的输入read 【-pt】variable
-p:后面可以接提示符
-t:后面可以等待的秒数
- declare/typeset
declare或typeset是一样的功能,就是声明变量的类型declare 【-aixr】variable
-a:将后面名为variable的变量定义为数组类型
-i:将后面名为variable的变量定位为整数数字类型
-x:用法与export一样,就是将后面的variable变成环境变量
-r:将变量设置为readonly类型,该变量不可被更改内容,也不能重设
- 数组(array)变量类型
与文件系统及程序的限制关系:ulimit
ulimit 【-SHacdfltu】 【配额】
-H:hard limit 严格的设置,必定不能超过这个设置的数值
-S:soft limit警告的设置,可以超过这个设置值,但是超过由警告信息
-a:后面不接任何参数,可列出所有有的限制额度
-c:当某些进程发生错误时,系统可能会将该进程在内存中的信息写成文件(排错用),这种文件就被称为
内核文件(core file)。此为限制每个内核文件的最大容量
-f:此shell可以创建的最大容量(KB)
-d:进程可使用的最大断裂内存(segment)容量
-l:可用于锁定的内存量
-t:可使用的最大cpu时间
-u:单一用户可以使用的最大进程数量
注意:想要复原ulimit的设置最简单的方法就是注销再登录,否则就是得要重新以ulimit设置才行
变量内容的删除、替代与替换
命令别名与历史命令
使用 alias lm = ‘ls -l|more’ 为命令设置别名
使用 unalias 取消别名
使用history 查看历史命令
history 【n】 查看最近n条命令
history 【-c】将目前shell中的所有history内容全部消除
history 【-raw】 histfiles
-a:将目前新增的history命令新增入hisfiles中,如没有加hisfiles则默认写入到~/.bash_history中
-r:将hisfiles的内容读到目前这个shell的history中
-w:将目前的history记忆内容写入到hisfiles中
其实中间还有一串内容,但是我觉得太杂了就没有介绍,直接看书的。
管道命令(pipe)
我的理解时以左边命令的标准输出作为右边命令的输入来执行;
使用| 这个界定符号来表示管道命令。
- 管道命令仅会处理standard output,对于standard error output会忽略
- 管道命令必须要能够接受来自前一个命令的数据称为standard input继续处理才行
选取命令:cut,grep
- cut
- grep
排序命令:sort,wc,uniq
- sort
- wc
- uniq
双向重定向:tee
字符转换命令:tr,col,join,paste,expand
- tr
- col
- join
- paste
- expand