操作系统定义:计算机系统的基本软件,负责控制、管理计算机的所有软件、硬件资源,是唯一直接和硬件系统打交道的软件,是整个软件系统的基础部分,同时还为用户提供良好的界面,总之它是协调计算机系统各组成部分之间、人机之间关系的重要软件系统。

Linux应用基础及常用命令

Linux系统的组成:

  • Kernel 内核
  • Shell 命令行如bash
  • Applications

Kernel是Linux操作系统的核心程序。必须完成以下内容

  • 管理程序的运行
  • 管理对文件系统的读写
  • 管理存储器
  • 管理输入、输出
  • 管理网络

Shell是一个命令解释器,是内核和用户之间的接口。
Shell也是一个编程语言,我们可以执行Shell脚本
Linux系统的启动过程:init->login->passwd->shell

用户通过命令行输入命令,经由Shell解释,与内核进行交互

Linux应用程序:包括文本编辑器、Xwindow、办公套件、Internet工具和数据库等

Linux简单命令:

# 是系统管理员的命令提示符,$是普通用户的命令提示符

登录和退出Linux

$login userName
回车后出现password:,在之后输入正确密码登录成功
可以使用ctrl+d,exit,logout退出

显示日期

$date ,显示日期和时间
设置日期和时间为:
#date -s 20041229/12:23:23/“2006-10-10 12:12:23”

显示日历

$cal [month] [year]

$cal,默认显示当前年份当前月份的日历

若只有一个数字,则被认为是年,并显示相应年的12个月的日历。

cal 0 提示 a number between 1 and 9999

clear和echo

$clear用于清屏
$echo 在标准输出上显示字符串
可以使用反斜杠作为换行符继续输入,内容会连着,但是在没有引号的情况下

who

$who 显示登陆到系统的所有用户的详细信息
$whoami 显示当前用户有效帐号

mail

发送Email
mail username
然后根据要求输入
在下一个空行按ctrl+d终止,非空行按ctrl+d没反应
只输入mail,接受E-mail
打印的信息中
U 代表未读的邮件
N 代表收到的新邮件
?或&为系统提示符,在之后等待用户输入命令
d:删除信息
R:回复邮件
q:退出mail平台,保存之前的操作
t:显示信息
enter:下一个
数字n:查看第n各邮件
一旦邮件被打开,其将被放在$HOME/mbox目录中,若想再看这些信息则用:
mail -f

wall

wall:将在系统中的所有在线用户的终端上显示信息,主要用于广播系统管理信息
wall the system will be shutdown from 10 pm today
则“the system will be shutdown from 10 pm today”被广播

write

若一个用户在线,可用write命令发送消息
如:write joe
然后就可以输入消息给对方了
按Ctrl+D结束会话,接收端收到EOF消息,说明另一个人结束会话,这一方也需要按Ctrl+D来结束会话。

mesg

mesg命令决定用户是否接收来自write和wall命令发送的消息,但对root用户的发送消息不起作用
mesg n:拒绝消息
mesg y:允许接收消息

常用按键

backspace 删除
ctrl-c 中断当前的命令并返回Shell
ctrl-d 中断当前的通信或从文件中退出
ctrl-u 删除整行

命令模式

CommandName options arguments
命令是大小写敏感的

命令、选项和参数之间必须用空格隔开

若命令在一行内写不完,可在行尾加\,再接着写

man

-a:显示所有手册页
-k [keyword]:在手册页标题数据库中搜索keyword关键字并显示包含匹配标题的列表
一个帮助命令,可以通过这个命令显示需要命令的信息
man who
向后翻一页:空格或f
向前翻一页:b
向后移动一行:回车Enter
退出:ctrl-c或q
手册信息主要包括:
NAME:标题名称
SYNOPSIS:命令的语法描述
DESCRIPTION:命令的可用选项描述
[]内的内容为可选项
a|b:要么为a,要么为b
{}:强制选项

help

help命令同样是帮助命令

文件系统

什么是文件?

文件 是Linux用来存储信息的 基本结构。它是被命名的、存储在某种媒介上的一组信息的集合。

Linux文件名的最大长度为256个字符
通常用字母、数字、点号、下划线、减号组成,文件名中不能包含“/”符号。
避免使用具有特别意义的字符:
? * @ # $ & () [] <>…
文件名中可以存在空格或制表符,引用文件时必须引号括出
隐藏文件一般是以点号开头
避免使用+和-作为文件名的第一个字符
大小写敏感

也可以把扩展名作为文件名的一部分。通过圆点区分

文件类型

三种基本的文件类型:

  • 普通文件:二进制文件、文本文件
  • 目录文件:一个包含文件的容器,用于存放目录中文件列表信息。
  • 设备文件:Linux中,设备被当成文件处理

普通文件

二进制文件和文本文件本质上都是以二进制的形式存储在磁盘中

文本文件只是二进制文件中的一种特例。如果一个文件专门用于存储文本字符的数据,没有包含字符以外的其他数据,我们就称之为文本文件

目录文件

目录文件存储一组相关文件的位置、大小等与文件有关的信息,但它不包含具体的文件内容。
目录文件中的每一项(entry)主要表示的是一个文件名/子目录名以及文件的索引节点号(i-node)

一个文件的索引节点能够指向该文件内容所在的数据块位置,除此之外还记录该文件的属性。

访问文件或子目录时,首先访问它所在的目录,找到该文件的i-node值,然后查找i-node表中,该值对应的i-node项,找到相应的数据。

为什么在目录文件中只存放 i-node 值,而不是 i-node的具体内容?
让目录文件只关注文件名的存储与i-node的映射,而i-node专注于存储文件的实际元数据和数据块位置,更加灵活和可扩展。文件被重命名时,实际上只需要修改目录中的文件名

设备文件

Linux系统把I/O设备都看成是文件。用户使用I/O设备像使用一般文件一样,不需要了解其中细节。
有两种设备文件:

  • 块设备:
    一般以块为单位进行随机存储
    常见块设备:软盘、光盘、硬盘
  • 字符设备:
    以单个字符为单位进行顺序存取
    常见的字符设备:打印机、终端、键盘、鼠标

文件系统结构

文件系统指文件存在的物理空间

Linux文件系统由一组普通文件、目录文件、设备文件和链接组成
链接分为符号链接(软链接)、硬链接

Linux中支持多种不同的文件系统

Linux将分属不同分区的、单独的文件系统整理形成一个系统的,总的目录层次结构。总之,就是一个树状、层次结构

组织、检索和管理信息便捷、高效

Linux下的所有文件都依附在根目录/下

Linux通过 mount(挂接),将新的文件系统加到自己的文件系统树中。所有的文件系统,无论类型,都挂接在文件系统树的一个目录上。这个目录称为挂接目录或挂接点,原来的内容会被掩盖。当文件系统被卸掉之后,挂接目录原来的文件才可见。

用户主目录

用户主目录,又称为用户的登录目录或起始目录
用户每次登录后自动位于其主目录下
用户主目录由系统管理员在创建账号时建立,每个合法的用户在文件系统中都有一个唯一的起始目录。
默认的主目录位于/home目录下,以该用户名命名
例如用户joe,其用户主目录为:/home/joe
注意root用户,其主目录为:/root
cd 命令可以从任何位置返回主目录

使用echo HOME可以查看自己的主目录(HOME可以查看自己的主目录(HOME环境变量存储当前用户的主目录)

当前目录

当前目录即用户当前所处的工作目录
使用命令pwd可以显示当前工作目录

路径

Linux系统中每个文件都有一个唯一的路径名,表明了文件的位置。
路径名又分为绝对路径,相对路径。
绝对路径:指出从根目录到此文件的路径
相对路径:指明从当前目录到此文件的路径
相对路径名以下列方式开始:
“.”:代表当前目录
“…”:代表当前目录的父目录

文件及目录的阅读与浏览

cat命令

cat命令将文件的文本内容一次全部显示在屏幕上
-n:打印行号
-b:打印行号,空号不编号
-b会覆盖-n

此外cat命令还经常被用来进行文件的合并、建立、覆盖和添加内容等操作

cat filename1 filename2 > filename3
cat filename1 >> filename2

>:输出重定向到文件中,覆盖现有内容
>>:输出重定向到文件中,追加到现有内容的末尾

more命令

more命令可以分屏显示文件内容。可以在文本上下移动
$more my_file

当more命令调用一个文件时,显示第一屏的文本
进入下一页:f或空格
前一页:b
向下移动一行:回车
退出:q或ctrl+c

wc命令

该命令能够统计文件中的字符数、单词数和行数
-c:显示字符数
-l:显示行数
-w:显示单词数
单词指由空格或tabs分开的最大字串
如果不加任何选项,则会全部列出,顺序为行数、单词数、字符数、文件名
若不给出文件名,则从标准输入中读取

ls命令

显示该目录或路径下所包含的文件及目录列表,以及文件的相关信息

ls [-options] [-filelist]

filelist为路径名,可以绝对,也可以相对
不带任何选项的ls命令只列出文件名

-a:用于列出目录中的所有文件,包括隐藏文件
-l:列出文件的详细信息:首先显示该目录中所有文件和子目录的总占用块数。然后依次列出每个文件的文件类型、操作权限、链接数、属主名、属组名、字节数、最近修改时间
-d 显示目录名而不显示其中的文件
-R 递归列出子目录
-r 逆序显示文件名列表
-x 显示时以字母顺序
–color 用不同颜色区分文件类型
正常的显示顺序为按ASCII排序
绿色-可执行文件
蓝色-目录
红色-压缩文件
浅蓝色-连结文件
灰色-一般文件
/etc/DIR_COLORS自定义颜色

对于ls -l显示文件类型的地方
d:目录
-:普通文件
l:符号链接文件
b:块设备文件
c:字符设备文件

操作权限由九个字符表明:
rwxrwxrwx,三位一组,每组分别代表文件属主、同组用户和其他用户的读、写、执行权限

文件大小以字节为单位

cd命令

改变当前工作目录
cd [directory]
直接cd,代表回到用户主目录
cd ~等同cd
cd …返回上级目录

文件和目录的操作与搜索

touch命令

以当前时间创建文件或更新已有文件的时间戳
若所指定文件不存在,则自动创建指定文件,大小为零
touch -t [YY][MMDDhhmm] filename
示例:
touch file1:file1存在,则将时间记录改为目前时间,若不存在,则创建file1
touch –t 199801151110 file1
将file1的时间记录改为1998年1月15日11点10分。
touch –t 01151110 file1
将file1的时间记录改为1月15日11点10分。

cp命令

cp [-options] src_file dst_file
src_file:源文件或目录
dst_file:目标文件或目录
如果dst_file是一个目录,则将源文件拷贝到目的目录下
-i 在覆盖文件之前提示用户,由用户确认
-R或-r: 递归复制目录,即复制相应的目录及其所有子目录(拷贝目录到目录必须加-R)

会覆盖文件原内容

一次拷贝多个文件:
正则式
cp file1 file2 directory1
将file1和file2拷贝到directory1目录中

将当前目录下所有的.c文件和.o文件拷贝到指定目录下
cp *.[oc] /home/test/progs

mv命令

mv命令用于对文件进行更名或路径迁移
mv [-options] src_file dst_file

-f强制执行,直接覆盖已存在的目的文件
-i交互执行,当已存在同名的目标文件时,覆盖前给出提示

dst_file是目录则移动到目录,若名字则改名,也可以即移动目录也改名
mv aaa bbb (aaa改名为bbb)
mv aaa /home/paul 移动aaa到/home/paul目录下
mv aaa /home/paul/bbb(如果bbb不存在,或bbb不是目录,则aaa改名为bbb,并且覆盖)

rm命令

rm [-options] files
-f:强制执行
-i:交互执行,删除前提示
-r或-R:递归的删除目录
files可以是一个文件,也可以是多个文件。当要删除多个文件时,多个文件名用空格隔开

mkdir

mkdir命令创建子目录,每个新创建的目录都包含两个标准项:.和…
创建新目录,必须对其父目录有写权限
mkdir [-options] directory
-p 自动建立所需路径中不存在的上层目录
-m 建立指定权限的目录

rmdir

删除目录,使用rmdir命令,同样对父目录要有写权限,同时只能删除空目录
-p 多层次空目录删除,逐层删除空目录,碰到非空目录则停止

whereis

whereis显示指令的二进制码、原始码与在线手册说明文件的存放目录
whereis [-options] [file]
-b只查找二进制文件
-m只查找在线手册manual路径
-s只查找原始码文件

locate命令

locate file

locate命令比whereis速度更快,是在一个文件名数据库进行检索
可以使用updatedb手工更新数据库,数据库更新每星期执行一次

链接文件

目录中每一对文件名称和索引节点号称为一个链接

硬链接:
原文件名和链接文件名都指向相同的物理位置。如果删除硬链接文件的源文件,硬链接文件仍然存在,而且保留原有内容
不允许普通用户对目录建立硬链接,硬链接不能跨越文件系统(即不同分区)

符号链接(软链接):
它的内容是它所链接的文件的路径名
每个链接文件有各自的索引节点号
如果删除源文件,链接文件找不到原有内容
可用于链接目录,并且可以跨越文件系统

ln命令

对于一个物理文件,有多个文件名
ln对于已经存在的文件创建一个新的链接,而不复制内容
ln后的链接文件名与物理文件具有相同的权限
ln [-s] target [link name]
-s代表是否为符号链接,不加为硬链接
target:源文件
Link name:链接文件名,符号链接可以是目录名

不同文件系统

比如ext2,ext3,ext4
ReiserFS
FAT12/16/32
jfs
xfs
zfs

权限控制

Linux作为多用户、多任务的操作系统,常常会有多人同时使用这部主机工作。
所以如何保证每个人的隐私权,以及资源共享,团队开发的需要
就有文件所有者、文件所属用户组的概念

Linux中的每个用户都至少属于一个用户组,以保证对一个用户组中的所有用户进行集中管理。

用户类型

三种不同类型的用户

  • 文件所有者:能够设定同组用户和其他用户对该文件的访问权限。一般而言是文件的创建者
  • 同组用户:具有相同性质的所有用户,被系统管理员分在同一组。文件所有者或系统管理员可将文件的权限赋予组内的其他用户。
  • 其他用户:除同组用户外系统中的其他用户。文件所有者或系统管理员还可以将文件的访问权赋予系统中所有其他的用户。

文件和目录的权限表示

设定文件权限时,用字符表示用户类型:
u 文件的所有者
g 同组用户
o 其他用户
all 所有用户
对文件和目录的三种权限:
r 读
w 写
x 执行

方法1:符号化表示

常见的表示方法
共九位,三位一组共三组
每组依次代表文件所有者、同组用户和其他用户对该文件的权限

每组的三位依次代表读、写、执行
例如:rwxr-xr–

r:读权限、w:写权限、x:执行权限、-:禁止

方法2:十进制表示

用三个十进制数字表示文件权限
xyz:x、y、z分别代表文件所有者、同组用户和其他用户的文件权限值
文件权限值为该类型用户对文件的读、写、执行权限值的累加:
读:4,写:2,执行:1,禁止:0
本质上是符号化的延续,相当于二进制计数
000-111,二进制从左往右代表4 2 1,与读、写、执行对应

对于目录而言,执行权限代表是否可以进入目录

文件权限对命令执行的限制

移动文件时不需要被移动文件的权限,但需要对其所在目录和目标目录具有写权限和执行权限(mv,又写了内容,又要进入目录)
在目录下增删文件、子目录时要有目录的写权限(touch, rm,mkdir, rmdir)

用ls列目录要有目录的读权限

进入目录或将该目录作路径分量时(cd)要有目录的执行权限。
而要使用任何一个文件,必须有该文件及找到该文件的路径上所有目录分量的执行权限。

chmod命令

chmod命令用来改变文件或目录的权限

chmod [-options] xyz [filelist]
例如:
chmod 711 my_file (711:rwx–x–x)
或者
chmod ugoa(±=)rwx my_file
可以用,隔开
-c 只有在文件权限确实改变时才进行详细说明
-f 不打印“权限不能改变”之类的错误信息
-R 递归改变目录及其内容的权限
-v 详细说明权限的变化(无论是否改变)

chown命令

chown命令仅root用户有权执行
chown命令可以改变文件的所有者及其用户组

chown [-options] user[: group] my_file

suid sgid

suid和sgid是文件权限中的特殊的权限位
设置在执行该文件时,执行该文件的用户将临时拥有文件所有者/文件所属组的权限,而不是自己的权限。
如passwd命令需要修改/etc/passwd文件,而这个文件只对于root用户可写,想要让普通用户运行passwd顺利修改文件,suid,sgid就应运而生了。

进程

概念:进程是程序的执行的过程,是执行的程序

操作系统通过进程来控制对CPU和其他系统资源的访问,并且使用进程来决定在CPU上运行哪个程序、运行多久

Linux系统的一个重要特点在于是多进程,即可以同时启动多个进程

程序和进程的不同:
程序是静态的,是保存在磁盘上的可执行代码和数据的集合
进程是动态的,是Linux系统的基本调度单位

父进程和子进程:
一个进程创建新进程称为创建了子进程,创建子进程的进程称为父进程

进程号:
PID:Process Identity number。唯一地标识一个进程的编号
PPID:进程的父进程号

Init进程:Linux操作系统启动后,即内核启动后的第一个进程,PID=1
扮演终结父进程的角色,所有进程追溯祖先都会落在init进程上

init进程永远不会被终止。因此设计上,如果某个进程在它的子进程结束之前被终止,那些失去了父进程的子进程会以init作为它们的父进程。

查看进程命令ps

ps可以列出当前进程清单,显示的进程列表是一个静态列表,即启动这个命令时正在运行的进程的快照。
ps [-options]
ps默认查看系统中属于自己的进程
显示信息为PID、TTY、TIME、CMD
TTY为终端类型,表示进程所属的终端,pts/数字或tty数字,?表示进程与任何终端无关联
TIME为进程使用的总CPU时间
CMD为启动该进程的命令及参数
-e 显示所有进程
-f 全格式
-l 长格式
-w 宽输出
-a 显示所有用户进程
-u 打印用户格式,显示用户名和进程起止时间
-x 显示与终端无关的所有进程

组合
-ef (-e和-f,查看系统中所有的进程)
aux (显示系统中所有用户进程及其所有者,并显示详细的进程信息)(为ps aux而非ps -aux)
-f相较原来增加UID、PPID、C、STIME
aux依次显示USER、PID、%CPU、%MEM、VSZ、RSS、TTY、STAT、START、TIME、COMMAND
USER为进程所有者,%CPU为对CPU的占用率,%MEM为对内存的占用率,VSZ为占用的虚拟内存大小,RSS为占用的物理内存大小,STAT为进程状态(RST,运行,中断,停止)、START为进程开始时间
-l相较原来有F、S、UID、PPID、C、PRI、NI、ADDR、SZ、WCHAN

top命令

交互式查看进程,显示的是可根据真实情况,定时更新的运行进程列表。除了
top [-] [d delay] [n]
d delay:指定更新的时间间隔
n:指定更新的次数,到达指定次数后会退出top
交互时的命令(即启动top后):
空格:立即刷新显示
d:设置刷新进程的时间间隔
q:退出top
k:杀死某进程。会被提示输入进程以及要发送的信号
h:显示帮助屏幕
n 显示的进程数
u 选择用户
M 按内存用量排序
P 按CPU用量排序

进程的启动方式

执行一个程序->启动一个进程
启动进程的两个主要途径:

  • 手工启动:
    当时设置当时启动。
  • 调度启动:
    用户可事先进行设置安排,指定任务运行的时间或场合,到时候由系统自动启动进程来完成此任务

手工启动又分为前台启动和后台启动
前台启动:启动一个进程后,如果不中断或挂起该进程,用户会一直被禁止与Shell交互,直到该进程执行结束。经常用于一般Linux命令的执行和一些不太耗时的进程。
后台启动:启动进程后,用户仍可以与Shell进行交互,可用于一些耗时长的作业运行。
前台进程可以用ctrl+c停止,用ctrl+z挂起
在命令后加&使进程后台运行:
command &

终止和挂起后台进程可以使用kill命令
kill 进程号,默认发送SIGTERM,请求进程正常退出。一般用户只能终止属于自己的进程
或者kill -9 进程号,发送SIGKILL立即终止进程
kill -STOP 进程号,挂起进程
kill -CONT 进程号,恢复进程
还可以使用%jobsId

jobs命令

显示后台任务的执行情况,包括正在执行的和被挂起的任务序列
jobs [-options]
-l:显示后台任务的进程号与信息
-p:只显示后台任务的PID
-n:显示上次通知后,执行状态有更动的后台任务状态
-r:显示执行中的后台任务
-s:显示暂停执行的后台任务

进程恢复可以用
fg %jobID恢复到前台
bg %jobID恢复到后台

nohup命令运行后台进程,使得在用户退出后仍然能继续执行,nohup.out文件中会存放运行后的所有错误和输出信息

其他命令

pgrep查找正在运行的进程
例如:
pgrep p_name
返回所有正在运行名为p_name的进程的PID
pgrep -l p_name
会返回进程的PID和进程名称
pgrep -u username p_name
查找特定用户运行的进程

fuser 查找正在使用某文件的进程
fuser file/directory
-v:详细显示进程信息
-k:终止正在使用指定文件的进程

setsid命令用于启动一个新的会话,并且将当前进程脱离原有会话

disown使后台进程与当前Shell分离

screen

Vi

vi类型编辑器
Emacs和Vi都属于一类文本编辑器

vi类型编辑器的优点:

  • 遵循简单工具、多样组合的理念
  • 小,符合Unix哲学——只做一件事,并做好它,避免了功能蔓延
  • 比Emacs快
  • 可运行于任何实现了C标准库的系统之上
  • 让QWERTY键盘用户将手指保持在默认键位上
  • 更普及

Emacs的优点:

  • 提供了比vi更多的功能
  • 移植最广泛的计算机程序之一。
  • 可扩展和可定制

Vi编辑器

Visual interface的简称
是Linux系统的第一个全屏幕交互式编辑程序
功能:可以执行输入、删除、查找、替换等众多文本操作,但它只是一个文本编辑程序
另有Vim提供更多功能

vi是一个较大的Linux命令,在启动时候也有它自己的选项和参数

vi [-options] [+n] [file]
常用选项:
-r:恢复系统突然崩溃时正在编辑的文件
-R:以只读方式打开文件
+[n]:指明进入vi后直接位于文件的第n行,如果只有+,则光标位于文件的最后一行
如果该文件不存在,会自动建立新文件

Vi的三种工作模式

  • 命令模式:
    在该模式下,用户可以输入合法的Vi命令,用于管理自己的文档
    该模式下从键盘输入的任何字符都被当作编辑命令解释
    进入方法:
    vi filename或在vi的任何模式下按ESC
  • 输入模式:
    在该模式下,用户输入的任何字符都被Vi当做文件内容保存起来,并将其显示在屏幕上。
    进入方法:
    命令模式下按
    i:当前光标位置插入
    a:光标后一个位置插入
    o:光标下一行插入新的行
  • 底行模式:
    多数文件管理命令都是在此模式下进行,如文件保存,退出vi等
    进入方法:
    在命令模式下,按:
    执行完命令后,自动回到命令模式,或按ESC返回

移动光标

命令模式下,最简单的方式是按键盘的上下左右键
nG:跳到第n行
G:跳到最后一行
0:跳到行首
$:跳到行尾
ctrl+b 前移一页
ctrl+f 后移一页
底行模式输入:
n:将光标移到第n行
.:光标所在行行号
$:正文最后一行的行号

字符串搜索

在命令模式下:
输入/字符串,正向搜索字符串
输入?字符串,反向搜索字符串
搜索得到结果后,再按n沿着相同方向搜索,按N沿着相反方向搜索
即如果是正向搜索,n继续正向,N反向;如果是反向搜索,n继续反向,N变为正向

字符串替换

底行模式下:
[n1, n2]s/str1/str2/[g][c]
在第n1行到n2行的范围内将字符串str1用str2代替:
c:每次替换由用户确认
g: 对行中搜索字符串的每次出现进行替换
不加g,则只对行中搜索字符串首次替换
不输入n1,n2,则默认光标所在行
s/str1/str2/
用字符串 str2 替换该行中首次出现的字符串 str1
s/str1/str2/g
用字符串 str2 替换该行中所有出现的字符串 str1
.,$s/str1/str2/g
用字符串 str2 替换正文当前行到末尾所有出现的字符串 str1

撤销和显示当前状态

命令模式下撤销上一命令的结果:u
ctrl+g 命令显示当前编辑文本的状态,包括文本共有多少行、文件名以及目前光标停在多少行

保存和退出

底行模式下
保存:
w:编辑的内容写入原始文件,用来保存编辑的中间结果
w file:将编辑的内容写入file文件
退出vi:
q:在未作修改的情况下退出(修改了未w,按q退出不了,提示写入)
q!:放弃所有修改,强制退出
wq:将编辑的内容写入原始文件并退出编辑程序

在vi内使用Shell

用户不用退出vi就可以运行任何Shell命令
底行模式下:
! command,执行完后,再按一下回车回到命令方式

Vim和gvim

Vim代表Vi IMproved,Vi提高版,还提供有多级恢复、命令行历史以及命令及文件名补全等功能
gvim是vi的X Window版本,该版本支持鼠标选中,一些高级光标移动功能,并且带有菜单和工具功能

Shell

内核与Shell的概念

内核(Kernel)是Linux层次结构设计中最核心的部分,它负责运行和调度进程、分配内存、管理存储系统、执行所有的输入输出。

而Shell提供内核的保护层:

  • 对用户屏蔽内核的复杂性
  • 保护内核以免用户误操作造成损害

即Shell是用户与内核沟通的桥梁,而内核可以控制硬件工作,硬件则是实体工作者。

那么现在的问题是,什么是Shell?

Shell的定义

Shell是一个命令行解释器,是内核与用户的接口,互动式的解释和执行用户输入的命令,并将其传给系统。
同时Shell也是一种程序设计语言,即可以编写Shell脚本
Shell在用户登陆后启动,其与用户对话的基本单位是Linux命令。

Shell脚本

可以把一组Shell命令或Shell程序语句组合在一起,放在一个文件中。当要执行这组命令或程序语句时,可以直接执行这个文件
一般称这个文件为命令文件/Shell程序/脚本(Shell脚本)

Shell种类

Bsh:UNIX的缺省Shell,Shell编程能力强,交互弱
Csh:能提供Bsh所不能处理的用户交互特征,语法类似C
Ksh:融合了Bsh和Csh的优点,并和Bsh完全兼容
Bash:Linux的缺省Shell,Bsh的扩展
还有TC Shell(Csh扩展),PdkShell(K Shell的延伸)

输入子ShellName启动一个指定类型的子Shell:
例如:
image1
输入bash,启动了类型为bash的子Shell,同时可通过exit命令或Ctrl+D退出该Shell。

Shell变量

显然,为使Shell编程更有效,系统提供了Shell变量:

  • 保存路径名、文件名、数字等信息
  • 用户定制用户自己的工作环境
  • 保存有用信息,使系统获知用户相关设置
  • 保存暂时信息
    (感觉就是任何一个程序设计语言,变量存在的意义)

Shell变量的定义、显示、清除

变量定义:
输入 变量名=值,即可在该Shell中定义该变量,并初始化其值
注意这之间不能有空格

显示变量:
通过输入echo $变量名或echo ${变量名}即可显示该变量取值,注意变量前需有$符号标识
$外的大括号是可选的,加上主要是为了帮助解释器识别变量的边界

清除变量:
通过输入unset命令,即可在该Shell中清除该变量。

综上,例子如下,通过给变量aaa赋值为1,并利用echo命令显示,并通过unset清除:
image2

常用命令set

可以通过set命令显示所有Shell变量,输入set即可。
查看输出时可以看出Shell已经设置了一些用户变量以便工作环境更加容易使用。

Shell变量的种类

本地变量:只能在当前Shell中使用的变量,不传递给该Shell创建的任何子进程。
全局变量:可以用于所有进程的变量

可以显式地给变量赋空值:
variable=
variable=“”
variable=‘’

变量设置规则

  • 变量名只能是字母、数字、下划线的组合,但是不能以数字为开头
  • 等号两边不能直接接单独的空格符
  • 如果变量所取的值中包含空格,必须使用引号将变量取值括起来
    必要时需要用‘\’来将特殊符号(如Enter,$,\,空格,引号)变成一般符号
    变量名字母为大小写均可,但通常大写字母为系统预设的变量,小写字母用于用户自定义的变量

本地变量-读入变量值read

格式:read variables
variables可以是多个变量,它们之间用空格隔开。输入完read后,输入一行依次给变量赋值,读入的内容也相应通过空格隔开
显然要考虑读入的内容个数少于变量个数和多于变量个数的情况。
读入的内容个数少于变量个数,则多出的变量将设为空值:
读入的内容个数多于变量个数,则将多出的部分都赋给最后一个变量:

变量名替换

$variable或${variable}

应用举例:
可以保存系统命令参数
source=/etc/passwd
dest=/root/passwd_bak
cp ${source} ${dest}

全局变量

传统上,所有全局变量均为大写
设置途径:
/etc/profile:存放系统管理员设置的变量
~/.bash_profile:用于增加新变量或覆盖/etc/profile的设置,每次登录这些设置值都会被初始化

变量设置export导出
与本地变量赋值方式相同,但赋值后需将变量值导出
variable-name=value
export variable-name

嵌入Shell变量:Shell中预留的变量名,各有用途,不作他用

HOME:保存用户主目录的完全路径名
LOGNAME:保存登录用户名
PSI变量:保存主提示符,基本提示符包含Shell提示符,默认对超级用户为#,其他为$
PATH变量:保存进行命令或脚本查找的目录顺序,不同的目录路径名之间用冒号分隔开。

Shell特殊字符

单引号:单引号括起来的所有字符都作为普通字符出现,特殊字符用单引号括起来后,也会失去原有意义,只作为普通字符解释

双引号:由双引号括起来的字符,则特殊字符$和\,引号起作用,其余字符作为普通字符

反引号:反引号括起来的内容被Shell解释为命令行。执行时,Shell首先执行该命令行,并用它的标准输出结果取代整个反引号,可以与其他引号结合使用
反引号可以嵌套使用,但内层反引号需要用转义字符转移

反斜线:转义字符

通配符

Shell提供了一套完整的字符串模式匹配规则,或者称为元字符
用户可以在作为命令参数的文件名中包含这些通配符,构成一个模式串
这样可以按照所要求的模式匹配文件名、路径名、字符串
常用通配符:
* ? […]

*通配符

*可以匹配文件名中的任何字符串
如ls app*
列出当前目录下所有以app开头的文件

有时使用cd命令切换路径,使用星号还可以免去输入整个路径名的麻烦

?通配符

?可以匹配文件名中的任何单个字符
如ls ??R*
任意两个字符开头,第三个字符为R,后面跟任何字符的文件

[…]和[!..]

匹配方括号中指定范围内的字符
可以用横杠来连接两个字母或数字,以表示范围
如[a-z]

!..代表匹配不在指定范围内的任何字符

如ls [io]*,代表列出以i或o开头的文件名

注释符号#

以字符#开头的正文行表示注释行

编写Shell脚本和运行

打开文本编辑器,新建一个文件test.sh,扩展名为sh(sh代表Shell),扩展名并不影响脚本执行

输入内容如下:
#!/bin/bash
echo “Hello World !”
#!是一个约定的标记,告诉系统这个脚本需要什么解释器来执行,示例内容即使用bash解释器执行

chmod +x ./test.sh
./test.sh
切换到脚本所在目录,注意要使脚本具有执行权限,并且一定要./打头,这样告诉系统在当前目录找

readonly variable将变量定义为只读变量

使用unset命令可以删除变量

使用单引号或双引号定义字符串
str=‘this is a string’

单引号字符串的限制:单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的(无法通过$引用)
单引号字符串中不能出现单独一个单引号(转义符也不行,因为单引号里不支持转义符)

双引号字符串:
str=“this is a string”
双引号内可以有变量,也可以出现转义字符
但是解析转义字符含义,例如\n,需要用echo -e

字符串拼接
双引号进行拼接
单引号进行拼接
主要在于解析转义字符

Shell支持数组,允许在一个变量中存储多个值
数组可以是整数索引数组或关联数组
整数索引数组:my_array=(1 2 3 4 5)
my_array[“name”] = “John”

关联数组需要用declare -A声明
declare -A my_array

my_array[“google”]=“this is goole”

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如expr

expr命令可以用于进行整数计算
格式:
expr 表达式
表达式由操作数和运算符组成。操作数一般是整数,也可以是字符串
表达式的各部分,即操作数和运算符之间必须以空格分割

+
-
\*
/
%
多个算术表达式可以组合在一起
可以使用反引号改变计算次序
expr `expr 5 + 7` / 3

expr命令一般用于整数值,此外用于字符串测试
(一个等号)
expr $s1 = “hello”

Shell的算术扩展
如$(()),算术扩展中包含的只有变量、运算符和常数
$((2*i+1))
不需要$i

可以用于显示输出和变量赋值
echo $((expression))
value=$((expression))

test命令测试结果,条件为真退出状态为0;条件为假,退出状态非零

中括号
整数比较符
相等 不等 大于 小于 大于等于 小于等于
-eq -ne -gt -lt -ge -le
!非运算
-o 或运算
-a 与运算

$0为执行的文件名
$1, $2…$9表示引用传递给脚本的参数
第九个以后的参数都不会被访问

$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 代表脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*大体相同,区别在于双引号中体现,for循环中,@相当于三个,@相当于三个,*相当于一个字符串,里面有传递的三个参数。
$-是显示当前Shell环境启用的选项
$?显示最后命令的退出状态。0表示没有错误

[[ expression ]]中使用&&或||代表逻辑与或

字符串运算符:
=: 检测两个字符串是否相等
!=: 检测两个字符串是否不相等
-z:检测字符串长度是否为0,为零则true
-n:检测字符串长度是否不为零
$:检测字符串是否不为空,不为空返回true

文件操作符:
-e file 文件file是否存在
-d file 文件file是一个目录
-f file 文件file是一个普通文件
-s file 文件file大小不为0
-r file 可读
-w file 可写
-x file 可执行

Shell流程控制:
if else
if condition
then
command1
elif condition2
then
command2
else
commandN
fi

for

for var in item1 item2 … itemN
do
command1
command2
done

while condition
do
command
done

进程间变量的关系

变量是进程运行环境的一个组成部分
本地变量在各进程间不能相互访问和修改
并且子进程不会自动地继承父进程中本地的变量

export只能将变量传递给子进程

Shell脚本运行方式

sh方式:bash set_dir(用sh方式运行set_dir脚本),相当于启动了一个子Shell
.方式:在当前Shell下执行Shell脚本。如. set_dir(.和脚本名用空格隔开)
赋予执行权限方式:对要执行脚本的用户开放执行权限

直接set_dir,这种执行方式会在PATH变量中提供的路径中查找相应的程序,这种方式也是在子Shell中执行

标准文件和文件描述符

在Shell中执行命令时,每个进程都和三个打开的文件相关联,并使用文件描述符引用这些文件
输入文件-标准输入stdin,文件描述符:0
输出文件-标准输出stdout,文件描述符:1
错误输出文件-标准错误输出stderr,文件描述符:2

通常输入默认来自键盘,两个输出默认输出至屏幕(终端)

要想指定命令的标准输入、输出或错误输出,而不是默认值,就需要使用文件重定向机制

重定向

>是覆盖>>是追加到末尾
command operation file
输入重定向<
(标准)输出重定向>
ls > directory.out

错误重定向

2>,可以自定义某个文件,也可以 2> /dev/null,它总是一个空文件(为了不显示错误信息)

把stdout和stderr同时重定向到outfile &1代表引用文件描述符1
Command > outfile 2>&1

管道

把一个命令在屏幕上的输出传递给另一个命令作为输入
命令1 | 命令2

正则表达式

当从一个文件或命令输出中抽取或过滤文本时,可以使用正则表达式(RE)。
以行为单位,来进行字符串的处理行为
符号:
^:只匹配行首,用在字符串前面
$:只匹配行尾,用在字符串后面
X*:0个或多个字符X
.:只匹配任意单字符
[字符表]:字符表中任意字符
[^字符表]:任意不在字符表中字符
\:转义
\{n\}:指定前导的正则表达式恰好重复n次
\{min,max\}:指定前导的正则表达式重复min~max次

grep命令

允许对文本文件的内容进行模式查找,如果找到匹配模式,显示包含该模式的所有行
grep [-option] pattern files
pattern代表匹配模式(正则式,匹配规则),files指针对查找的文件,若指定了多个文件名,结果中会在每一行的前面显示文件名

pattern中若包含字符串参数,用引号括起避免歧义

-c:只输出匹配行的计数
-n:显示匹配行及行号
-v:显示不包含匹配文本的所有行

find命令

find经常被用于在磁盘驱动器上查找文件
可以遍历当前目录甚至整个文件系统搜寻符合指定条件的文件
只要具有相应权限,即使在NFS系统中一样有效
由于非常消耗资源,通常后台运行

find path expression [-exec -ok] [command {} \;]

path:所查找的目录路径,对目录的搜索是递归的
-exec command,对匹配的文件执行该参数所给出的Shell命令Command
-ok 在执行每一个命令之前给出提示判断是否执行该command

expression:
-name file:寻找名为file的文件,要找的文件名用双引号包括,可以使用通配符
-user name:按照文件属主来查找文件
-group name:按照文件所属组来查找文件
-type type:查找某一类型文件,d:目录文件,f:普通文件
-size n[c]:查找文件长度为n块的文件,带c则为字节,+代表超过(通常一个block512字节)
-mtime n(-n,+n):-n为最后更改时间在n天以内,n和+n为距现在n天以上

sort命令

默认按字母顺序
sort -n 则为数值大小排序,从小到大