Linux 命令行与shell脚本编程大全
基础命令参考
初识
内核的介绍
内核主要负责以下四种功能:
系统内存管理
软件程序管理
硬件设备管理
文件系统管理
内核创建了第一个进程(称为init进程)来启动系统上所有其他进程。当内核启动时,它会
将init进程加载到虚拟内存中。内核在启动任何其他进程时,都会在虚拟内存中给新进程分配一
块专有区域来存储该进程用到的数据和代码。
一些Linux发行版使用一个表来管理在系统开机时要自动启动的进程。在Linux系统上,这个
表通常位于专门文件/etc/inittab中。
Linux 操 作 系 统 的 init 系 统 采 用 了 运 行 级 。 运 行 级 决 定 了 init 进 程 运 行 /etc/inittab 文 件 或
/etc/rcX.d目录中定义好的某些特定类型的进程。Linux操作系统有5个启动运行级。
运行级为1时,只启动基本的系统进程以及一个控制台终端进程。我们称之为单用户模式。
单用户模式通常用来在系统有问题时进行紧急的文件系统维护。显然,在这种模式下,仅有一个
人(通常是系统管理员)能登录到系统上操作数据。
标准的启动运行级是3。在这个运行级上,大多数应用软件,比如网络支持程序,都会启动。
另一个Linux中常见的运行级是5。在这个运行级上系统会启动图形化的X Window系统,允许用
户通过图形化桌面窗口登录系统。
在Linux内核中有两种方法用于插入设备驱动代码:
编译进内核的设备驱动代码
可插入内核的设备驱动模块
Linux系统将硬件设备当成特殊的文件,称为设备文件。设备文件有3种分类:
字符型设备文件
块设备文件
网络设备文件
Linux为系统上的每个设备都创建一种称为节点的特殊文件。与设备的所有通信都通过设
备节点完成。每个节点都有唯一的数值对供Linux内核标识它。数值对包括一个主设备号和一
个次设备号。类似的设备被划分到同样的主设备号下。次设备号用于标识主设备组下的某个特
定设备。
Linux内核采用虚拟文件系统(Virtual File System,VFS)作为和每个文件系统交互的接口。
这为Linux内核同任何类型文件系统通信提供了一个标准接口。当每个文件系统都被挂载和使用
时,VFS将信息都缓存在内存中。
GUN工具
GNU项目的主旨在于为Unix系统管理员设计出一套类似于Unix的环境。这个目标促使该项目
移植了很多常见的Unix系统命令行工具。供Linux系统使用的这组核心工具被称为coreutils(core
utilities)软件包。
GNU coreutils软件包由三部分构成:
用以处理文件的工具
用以操作文本的工具
用以管理进程的工具
走进shell
tty 代表电传打字机(teletypewriter)。这是一个古老的名词,指
的是一台用于发送消息的机器
流行的图形化终端仿真器软件包
Eterm http://www.eterm.org
Final Term http://finalterm.org
GNOME Terminal https://help.gnome.org/users/gnome-terminal/stable
Guake https://github.com/Guake/guake
Konsole Terminal http://konsole.kde.org
LillyTerm http://lilyterm.luna.com.tw/index.html
LXTerminal http://wiki.lxde.org/en/LXTerminal
mrxvt https://code.google.com/p/mrxvt
ROXTerm http://roxterm.sourceforge.net
rxvt http://sourceforge.net/projects/rxvt
rxvt-unicode http://software.schmorp.de/pkg/rxvt-unicode
Sakura https://launchpad.net/sakura
st http://st.suckless.org
Terminator https://launchpad.net/terminator
Terminology http://www.enlightenment.org/p.php?p=about/terminology
tilda http://tilda.sourceforge.net/tildaabout.php
UXterm http://manpages.ubuntu.com/manpages/gutsy/man1/uxterm.1.html
Wterm http://sourceforge.net/projects/wterm
xterm http://invisible-island.net/xterm
Xfce4 Terminal http://docs.xfce.org/apps/terminal/start
Yakuake http://extragear.kde.org/apps/yakuake
文件系统
常见fhs
/ 虚拟目录的根目录。通常不会在这里存储文件
/bin 二进制目录,存放许多用户级的GNU工具
/boot 启动目录,存放启动文件
/dev 设备目录,Linux在这里创建设备节点
/etc 系统配置文件目录
/home 主目录,Linux在这里创建用户目录
/lib 库目录,存放系统和应用程序的库文件
/media 媒体目录,可移动媒体设备的常用挂载点
/mnt 挂载目录,另一个可移动媒体设备的常用挂载点
/opt 可选目录,常用于存放第三方软件包和数据文件
/proc 进程目录,存放现有硬件及当前进程的相关信息
/root root用户的主目录
/sbin 系统二进制目录,存放许多GNU管理员级工具
/run 运行目录,存放系统运作时的运行时数据
/srv 服务目录,存放本地服务的相关文件
/sys 系统目录,存放系统硬件信息的相关文件
/tmp 临时目录,可以在该目录中创建和删除临时工作文件
/usr 用户二进制目录,大量用户级的GNU工具和数据文件都存储在这里
/var 可变目录,用以存放经常变化的文件,比如日志文件
ls常见指令
bash
-F 在显示的目录后边添加正斜线表示这是一个目录
-R 列出当前文件子目录中的文件
-a
-R
cp 常见
bash
-R 递归复制文件夹里的文件
ln
zsh
-s 创建软链接
不加任何参数 创建硬链接
tar
| 参数 | 参数描述 |
|---|---|
| -c | 创建新的档案文件 |
| -C | 指定到要解压到的目录。注意:该目录必须存在 |
| -f | 指定打包的文件名。在f之后要立即接打包文件名!不要再加参数! |
| -x | 解压 |
| -O | 将文件解压到标准输出 |
| -p | 使用原文件的原来属性 |
| -P | 创建归档文件,使用绝对路径 |
| -t | 列出档案文件中的内容 |
| -r | 向压缩归档文件末尾追加文件 |
| -u | 更新原压缩包中的文件 |
| -v | 显示详细过程 |
| -z | 使用gzip压缩,一般格式为xx.tar.gz或xx. tgz |
| -Z | 有compress |
| -j | 使用bzip2压缩,一般格式为xxx.tar.bz2 |
| –exclude | 在压缩过程中,排除某个文件(exclude在排除时,需要先写出) |
| –remove-files | 在完成打包后,删除原文件夹 |
检测程序
ps
ps 有好几种风格,我选择Unix风格的
bash
# 常见的
ps 查看当前bash的进程
ps -ef 列出全部的
ps -el列出更为详细的进程信息
bash
# 参考
-A 显示所有进程
-N 显示与指定参数不符的所有进程
-a 显示除控制进程(session leader )和无终端进程外的所有进程
-d 显示除控制进程外的所有进程
-e 显示所有进程
-C cmdlist 显示包含在 cmdlist 列表中的进程
-G grplist 显示组ID在 grplist 列表中的进程
-U userlist 显示属主的用户ID在 userlist 列表中的进程
-g grplist 显示会话或组ID在 grplist 列表中的进程
-p pidlist 显示PID在 pidlist 列表中的进程
-s sesslist
-t ttylist 显示终端ID在 ttylist 列表中的进程
-u userlist 显示有效用户ID在 userlist 列表中的进程
-F 显示更多额外输出(相对 -f 参数而言)
-O format 显示默认的输出列以及 format 列表指定的特定列
-M 显示进程的安全信息
-c 显示进程的额外调度器信息
-f 显示完整格式的输出
-j 显示任务信息
-l 显示长列表
-o format 仅显示由 format 指定的列
-y 不要显示进程标记(process flag,表明进程状态的标记)
-Z 显示安全标签(security context) 1 信息
-H 用层级格式来显示进程(树状,用来显示父进程)
-n namelist 定义了 WCHAN 列显示的值
-w 采用宽输出模式,不限宽度显示
-L 显示进程中的线程
-V 显示 ps 命令的版本号
但是仍然还有很多没有列出来
相关输出的含义:

image-20200718141755982
bash
F :内核分配给进程的系统标记。
S :进程的状态(O代表正在运行;S代表在休眠;R代表可运行,正等待运行;Z代表僵化,进程已结但父进程已不存在;T代表停止)。
PRI :进程的优先级(越大的数字代表越低的优先级)
NI :谦让度值用来参与决定优先级。
ADDR :进程的内存地址。
SZ :假如进程被换出,所需交换空间的大致大小。
WCHAN :进程休眠的内核函数的地址。

image-20200718141931437
bash
C: 进程生命周期中的CPU利用率
TIME:进程需要的累计CPU时间
CMD:启动的程序的名称
top
动态监测进程的一个命令

image-20200718143035046
VIRT:进程占用的虚拟内存总量。
RES:进程占用的物理内存总量。
SHR:进程和其他进程共享的内存总量。
S:进程的状态(D代表可中断的休眠状态,R代表在运行状态,S代表休眠状态,T代表
跟踪状态或停止状态,Z代表僵化状态)
df
查看某个设备还有多少空间
配合lsblk可以更全面了解设备空间占用的情况
du
查看某个文件(夹)的大小
-c 显示总大小
sort
排序
bash
-b --ignore-leading-blanks 排序时忽略起始的空白
-C --check=quiet 不排序,如果数据无序也不要报告
-c --check 不排序,但检查输入数据是不是已排序;未排序的话,报告
-d --dictionary-order 仅考虑空白和字母,不考虑特殊字符
-f --ignore-case 默认情况下,会将大写字母排在前面;这个参数会忽略大小写
-g --general-number-sort 按通用数值来排序(跟 -n 不同,把值当浮点数来排序,支持科学
计数法表示的值)
-i --ignore-nonprinting 在排序时忽略不可打印字符
-k --key=POS1[,POS2] 排序从POS1位置开始;如果指定了POS2的话,到POS2位置结
束
-M --month-sort 用三字符月份名按月份排序
-m --merge 将两个已排序数据文件合并
-n --numeric-sort 按字符串数值来排序(并不转换为浮点数)
-o --output=file 将排序结果写出到指定的文件中
-R --random-sort 按随机生成的散列表的键值排序
--random-source=FILE 指定 -R 参数用到的随机字节的源文件
-r --reverse 反序排序(升序变成降序)
-S --buffer-size=SIZE 指定使用的内存大小
-s --stable 禁用最后重排序比较
-T --temporary-directory=DIR 指定一个位置来存储临时工作文件
-t --field-separator=SEP 指定一个用来区分键位置的字符
-u --unique 和 -c 参数一起使用时,检查严格排序;不和 -c 参数一起用时,仅
输出第一例相似的两行
-z --zero-terminated 用NULL字符作为行尾,而不是用换行符
压缩与解压
解压工具
| 工具 | 扩展名 | 描述 |
|---|---|---|
| bzip2 | .bz2 | 采用Burrows-Wheeler块排序文本压缩算法和霍夫曼编码 |
| compress | .Z | 最初的Unix文件压缩工具,已经快没人用了 |
| gzip .gz | .gz | GNU压缩工具,用Lempel-Ziv编码 |
gzip xx 直接就能解压.gz文件
tar
-A –concatenate 将一个已有tar归档文件追加到另一个已有tar归档文件
-c –create 创建一个新的tar归档文件
-d –diff 检查归档文件和文件系统的不同之处
–delete 从已有tar归档文件中删除
-r –append 追加文件到已有tar归档文件末尾
-t –list 列出已有tar归档文件的内容
-u –update 将比tar归档文件中已有的同名文件新的文件追加到该tar归档文件中
-x –extract 从已有tar归档文件中提取文
命令选项
| 选项 | 描述 |
|---|---|
| -C dir | 切换到指定目录 |
| -f file | 输出结果到file |
| -j | 讲输出重定向给bzip2命令来压缩 |
| -p | 保留所有文件权限 |
| -v | 在处理文件时显示详细过程 |
| -z | 将输出重定向给gzip软件压缩 |
常用组合:
tar -zcf xx.tar.gz file1,file2,file3….
tar -xf xx.tar.gz 解压打包过的并且压缩过的文件
权限管理
/etc/passwd中文件含义

image-20200718145559428
登录用户名
用户密码
用户账户的UID(数字形式)
用户账户的组ID(GID)
用户账户的文本描述(称为备注字段)
用户HOME目录的位置
用户的默认shell
修改这个文件当中的内容十分危险,使用权限管理工具可以安全更改
密码x因为加密了
useradd
bash
-c comment 给新用户添加备注
-d home_dir 为主目录指定一个名字(如果不想用登录名作为主目录名的话)
-e expire_date 用YYYY-MM-DD格式指定一个账户过期的日期
-f inactive_days 指定这个账户密码过期后多少天这个账户被禁用; 0 表示密码一过期就立即禁用, 1 表示
禁用这个功能
-g initial_group 指定用户登录组的GID或组名
-G group ... 指定用户除登录组之外所属的一个或多个附加组
-k 必须和 -m 一起使用,将/etc/skel目录的内容复制到用户的HOME目录
-m 创建用户的HOME目录
-M 不创建用户的HOME目录(当默认设置里要求创建时才使用这个选项)
-n 创建一个与用户登录名同名的新组
-r 创建系统账户
-p passwd 为用户账户指定默认密码
-s shell 指定默认的登录shell
-u uid 为账户指定唯一的UID
修改默认值的参数
-b default_home 更改默认的创建用户HOME目录的位置
-e expiration_date 更改默认的新账户的过期日期
-f inactive 更改默认的新用户从密码过期到账户被禁用的天数
-g group 更改默认的组名称或GID
-s shell 更改默认的登录shell
一般就是 useradd -m -G wheel horo
wheel代表在sudo那个文件里取消注释的那个组(加入这个组可以取得root的一些权限) horo就是创建的用户名
userdel
userdel -r name 删除账户(但是不会删除太干净)
usermod
-l 修改用户账户的登录名。
-L 锁定账户,使用户无法登录。
-p 修改账户的密码。
-U 解除锁定,使用户能够登录。
修改用户的工具
usermod 修改用户账户的字段,还可以指定主要组以及附加组的所属关系
passwd 修改已有用户的密码
chpasswd 从文件中读取登录名密码对,并更新密码
chage 修改密码的过期日期
chfn 修改用户账户的备注信息
chsh 修改用户账户的默认登录shell
修改组
groupadd 命令可在系统上创建新组
usermod -G shared rich 讲rich加入到share组中
group代表修改组
文件权限
chmod 改变文件的权限
chown 改变文件的所有者 -R 递归修改
chgrp 改变文件的组
文件系统
主要就是知道ext系列是经典linux文件系统,新的比较好的有xfs 具体介绍还是去看鸟哥的
cfdisk 进行分区啥的
lsblk 列出当前的文件系统
理解LVM这个概念,简单来说就是linux支持将许多不同的物理磁盘合并为一个分区,这对于扩容来说,就省得备份了.或者是将一个磁盘分割成为许多不同的分区,极大方便了linux文件的管理
理解shell
当你登录Linux系统时,bash shell会作为登录shell启动。登录shell会从5个不同的启动文件里
读取命令:
/etc/profile
HOME/.bashrc
HOME/.bash_login
HOME/.profile
/etc/profile文件是系统上默认的bash shell的主启动文件。系统上的每个用户登录时都会执行
这个启动文件。
command1 & 讲命令放到后台执行,但是标准输出仍然会输出到屏幕上
jobs 列出后台执行的命令
Ctrl+Z 将一个正在执行的任务放到后台,并休眠
fg %num 将任务放到前台执行,并唤醒
环境变量
$env 显示变量当中的内容
export env=xxx 声明这个是全局环境变量,子shell可以使用这个变量,但关机后就会失效
可以在.zhsrv(shell的配置文件)中声明,来获得持久化的使用 因为每启动一次shell都会source下.zshrc 中的内容
shell基础语法
流程控制的语法
bash
if condition
then
command
else
command
fi
case var in xxx
part1)
command
part2)
command
*)
command
esac
while var in xx,xx,xx,xx,xx(以字段分割符分割的列表)
do
command
done
for((i=1;i<10;i++))
do
command
done
while condition
do
command
done

image-20200718153735701
exit 0
用$? 可以看出上一条命令的退出码
条件的设定
数字 字符串 文件

image-20200718154023094

image-20200718154046354

image-20200718154119647
以上三中比较都可以用[ ]符号将上述比较方法放在condition中
(()) 里面的条件可以用高级语言中的比较运算符直接进行比较,对于数字来说

image-20200718154330670
字符串使用[[]]即可
处理输入
getopts 命令能够和已有的shell参数变量配合默契。每次调用它时,它一次只处理命令行上检测到的一个参数。处理完所有的参数后,它会退出并返回一个大于0的退出状态码。这让它非常适合用解析命令行所有参数的循环中。
getopts 命令的格式如下:
getopts optstring variable
optstring 值类似于 getopt 命令中的那个。有效的选项字母都会列在 optstring 中,如果
选项字母要求有个参数值,就加一个冒号。要去掉错误消息的话,可以在 optstring 之前加一个
冒号。 getopts 命令将当前参数保存在命令行中定义的 variable 中。
getopts 命令会用到两个环境变量。如果选项需要跟一个参数值, OPTARG 环境变量就会保
存这个值。 OPTIND 环境变量保存了参数列表中 getopts 正在处理的参数位置。这样你就能在处理完选项之后继续处理其他命令行参数了。
variable 代表正在处理的参数
OPTARG 参数值
OPTND 正在处理的位置
示例:
shell
while getopts :abc: opt
do
case "$opt" in
a)echo this is -a
echo the postion is $OPTIND;;
b)echo this is -b
echo the postion is $OPTIND;;
c)echo this is -c with part $OPTARG
echo the postion is $OPTIND;;
*)echo unknown part
echo the postion is $OPTIND;;
esac
done
使用read即可
read var1
-s 输入用密码方式
-t 超时设置
-n2 输入两个字母时就会停止读取输入
$0 代表文件名
$@ 代表所有参数列表(但是会以空格分隔符分割)
$#命令行参数的个数
$* 代表所有参数列表,但是是整个字符串的
展示输出
文件描述符:
0 1 2 3–9
临时重定向
2> file 将stderror 输入到文件中
>&2 代表这一条语句向这标准错误输出写入内容
永久重定向
exec 1> file 永久将std 输入到file中
exec 3>&1 将文件描述符3标记的输出到stdout
&> file 标准输出和错误输出同时重定向到一个file
echo xxxx >&3 将xxx输入到文件描述符三定位的地方
一般使用3-6文件描述符的时候都是让他记住一个位置,之后再使用这个位置
bash
exec 3<&0
exec 0<test.log
read var1 这就是直接从teet.log 读取数据了
exec 0<&3 标准输入恢复从键盘输入
其实都可以理解为: 数据来源>数据写入到哪里
mkemp.xxxxx 生成随机名称的文件
注意:当程序在后台进行的时候,stdout和stderror仍然会出现在屏幕上
创建定时任务
crontab 的基本格式是:
<分钟> <小时> <日> <月份> <星期> <命令>
- 分钟 值从 0 到 59.
- 小时 值从 0 到 23.
- 日 值从 1 到 31.
- 月 值从 1 到 12.
- 星期 值从 0 到 6, 0 代表星期日.
空格用来分开字段,可以用下面特殊字符设定范围:
| 符号 | 描述 |
|---|---|
| ***** | 通配符,表示所有支持的时间值 |
| , | 用逗号分隔多个时间 |
| - | 连接两个数值,给出一个范围 |
| / | 指定一个周期或频率 |
函数的使用
name() {
return num(可选的语句,原理等同于 状态退出码)
}
$1 2 3 4 … 表示的是传给他的参数
name par1 par2 ….
使用写好的函数库,先提前source下库,然后再调用库里的函数
接受函数的输出:
使用命令转置 var=name
sed和gawk基础
这都是对流使用的编辑器,经常用于格式化文本或者批量处理某些文本,深入进去又是一门很大的学问,现在暂时用不到,先看看基础
基本格式:
sed ‘数字|/文本/commond/ 其他参数’
sed ‘范围 {
command1
commond2
…
}
替换
sed ‘1,3s/old/new/flag’
flag:
w xx.text
g gloable
p 原先行的内容要打印出来
3 新文本替换第3处的内容
删除
sed ‘1,3d’
sed ‘1,3/word/d’ 删除有个这个单词的行
插入
打印
p 打印这一行的所有文本
‘=’ 打印行号
从文件读取
‘r filename’
向文件写入
‘w filename’
…….之后的以后有时间用到再更新吧