1 文件系统和挂载点
Linux系统中一切皆文件
- /bin:存放常用的命令
- /opt:默认第三方软件的安装目录
挂载点:我们可以把某个硬盘的某个分区都挂载到某个目录下,如/home/abc,这样该目录下存放的数据都会存放在指定的硬盘的分区上。就是说Linux的目录结构是逻辑上的,是虚拟的,并不是物理上的硬盘目录
2 vim编辑器
注意:vim的操作是大小写敏感的,凡是有大写的都要按 shift 键
2.1 正常模式
功能分类 | 具体按键 | 作用 |
---|---|---|
移动光标 | h | 向左移动;前加数字可移动多列,如3h等 |
j | 向下移动;前加数字可移动多行 | |
k | 向上移动;前加数字可移动多行 | |
l | 向右移动;前加数字可移动多列 | |
G | 移动到最低行 | |
gg | 移动到最顶行 | |
w | 移动到下一个单词首部 | |
e | 移动到下一个单词尾部 | |
b | 移动到上一个单词首部 | |
赋值/粘贴 | yy | 赋值当前行 |
yw | 赋值一个单词 | |
p | 粘贴 | |
{数字}p | 粘贴数次 | |
删除/修改 | dd | 删除当前行 |
dw | 删除一个单词 | |
cw | 修改一个单词:先删除,然后进入编辑模式 | |
ci{ | 修改大括号里的内容:先删除,然后进入编辑模式 (要先把光标移动到大括号里面) | |
重复/撤回/恢复 | . | 重复上次操作 |
u | 撤回上次操作 | |
ctrl + r | 恢复上次操作 | |
视觉模式 | shift + v | 进入视觉模式,然后移动光标就可选中多行 |
2.2 编辑模式
通常在正常模式下按i
可进入该模式,表示在光标前面插入。此外还有其他方式
- i:在光标前面插入
- I:在本行最前面插入(大写的i)
- a:在光标前面追加
- A:在本行最后面追加
- o:在光标的下一行新建空行
- O:在光标的上一行新建空行
2.3 命令行模式
命令 | 功能 |
---|---|
/{字符串} | 搜索字符串 |
:noh | 取消高亮 |
:%s/{旧}/{新}/g | 全局替换 |
:q! | 强制退出 |
:wq | 先保存,后退出 |
:set nu | 显示行号 |
:set nonu | 关闭显示行号 |
2.4 配置
- 配置一直显示行号
# 查看vim的配置文件在哪
vim --version
# 编辑vim配置文件
vim $HOME/.vimrc
# 添加以下配置,并保存
set number
3 shell脚本
脚本一般均以**#!/bin/bash**开头,用于指定解释器
3.1 例子
# 创建脚本文件
touch hello.sh
# 输入以下内容
#!/bin/bash
echo "hello world!"
# 使用sh/bash命令执行脚本文件
sh hello.sh
# 或者先加上执行权限,然后直接执行脚本文件
chmod +x hello.sh
./hello.sh
3.2 变量
-
常见的系统变量有:PWD等,以及用户配置的环境变量,如$JAVA_HOME等
-
自定义变量:变量名=变量值,等号前后不能有空格
a=10
b=20
username="jack"
- 只读变量
readonly c=5
- 特殊变量
- $n :n是数字,$0表示该脚本名称,$1~$9代表前9个参数,10个及以上的参数要加{},如${10}
- $# :获取输入参数的个数,常用于循环
- $* 和 $@ :获取所有输入参数,区别是前者把所有参数看成一个整体;后者把每个参数分开,得到一个集合
- $? :最后一次执行命令的返回状态,如果为0,说明上一个命令正确执行;如果非0,则说明上一个命令执行有误
3.3 运算符
- expr
# 反引号表示里面命令符不看成字符串,而看成命令来执行,于是得到a变量的值为30。注意空格!
a=`expr 10 + 20`
# 乘号*要加转义符\
b=`expr 2 \* 5`
- [运算式子],可以不加空格
a=$((3+7))
b=$[3*(2+4)]
3.4 条件判断
-
基本语法:[ 条件 ],要注意中括号与条件之间的空格
-
比较符:
比较符 | 含义 |
---|---|
-eq | 等于 |
-ne | 不等于 |
-lt | 小于 |
-le | 小于等于 |
-gt | 大于 |
-ge | 大于等于 |
= | 字符串之间的判断相等 |
!= | 字符串之间的判断不等 |
-z | 字符串是否为空 |
-n | 字符串是否为不为空 |
- 文件相关的判断:
判断符 | 含义 |
---|---|
-r | 判断文件是否有读权限 |
-w | 判断文件是否有写权限 |
-x | 判断文件是否有执行权限 |
-e | 判断文件是否存在 |
-f | 判断是否为一个文件 |
-d | 判断是否为一个文件夹 |
- 逻辑与或:
&&
(逻辑与)、||
(逻辑或)
同时使用&&和||,可实现三目运算符的作用,如下所示
# 判断2是否大于1,若是,打印“2>1”;否则打印“2<1”
# &&可理解为上一条命令执行成功,才执行下一条命令;||可理解为上一条命令执行失败,才执行下一条命令
[root@vm my-shell]# [ 2 -gt 1 ] && echo "2>1" || echo "2<1"
2>1
3.5 流程控制
3.5.1 if判断
if [ 条件1 ]
then
程序1
elif [ 条件2 ]
then
程序2
else
程序3
fi
注意:一个中括号里写两个条件,要加 -a
或 -o
# 分号;的作用是多个命令写在同一行
# 使用 -a 来表示 逻辑与,下述两条命令作用一致
[root@vm my-shell]# if [ 10 -gt 5 -a 20 -gt 5 ]; then echo "OK"; fi
OK
[root@vm my-shell]# if [ 10 -gt 5 ] && [ 20 -gt 5 ]; then echo "OK"; fi
OK
3.5.2 case语句
case $变量名 in
值1)
程序1
;;
值2)
程序2
;;
*)
程序3
;;
esac
注意事项:
- case 行尾要加
in
,每一个匹配值要加)
- 双分号
;;
表示程序结束,相当于Java的break *)
相当于Java的default
例子如下:
#!/bin/bash
case $1 in
1)
echo "OK 1"
;;
2)
echo "OK 2"
;;
*)
echo "ERROR"
;;
esac
3.5.3 for循环
# 普通for循环
for ((初始值;循环条件;变量变化))
do
循环体
done
# 增强for循环
for 变量名 in 值1 值2 值3...
do
循环体
done
例子如下:
#!/bin/bash
sum=0
# 这里的条件判断之所以能用<=,是因为在双括号(())里面
for ((i=1;i<=$1;i++))
do
sum=$[$sum + $i]
done
echo $sum
sum2=0
for i in {1..100}
do
sum2=$[$sum2 + $i]
done
echo $sum2
3.5.4 while循环
while [ 循环条件 ]
do
循环体
done
例子:
#!/bin/bash
i=0
sum=0
while ((i<=100))
do
((sum+=i))
((i++))
done
echo $sum
3.6 读取控制台输入
-
语法:read (选项) 变量名
-
选项:
-p:提示信息
-t:等待的时间(秒)
#!/bin/bash
read -t 10 -p "Please enter your name:..." name
echo $name
3.7 函数
[function] functionName[()] {
函数体
[return int;]
}
- 中括号里面的内容可写可不写
- 调用函数直接必须先声明
- 函数的返回值通过
$?
获取,return值的范围只能在[0, 255],不写return则返回最后一条命令的执行结果 - 函数的入参通过
$1
、$2
等获取
例子如下:
#!/bin/bash
# 声明函数
function add() {
sum=$[$1 + $2]
echo $sum
}
read -p "please input num1:" a
read -p "please input num2:" b
# 使用$()进行命令替换,接收add()函数的打印值
sum=$(add $a $b)
echo "the sum is:"$sum
4 文本处理
4.1 cut
- 用法:cut [参数] filename
参数 | 作用 |
---|---|
-f | 列号,选取第几列的数据 |
-d | 指定分隔符来切割列,默认是制表符\t |
-c | 按字符进行切割,后面加数字n表示取第n列 |
4.2 awk
- 用法:awk [参数] '/pattern1/{action1} /pattern2/{action2}...' filename
- pattern:用于匹配的正则表达式,过滤满足的行
- action:执行的操作,可理解为对满足pattern的行执行某种操作
- {action}前面可以加BEGIN、END关键字。BEGIN是数据读取之前执行某种操作,END是数据读取之后执行某种操作,见案例3
参数 | 作用 |
---|---|
-F | 指定分隔符,默认是空格 |
-v | 赋予一个自定义的变量,见案例4 |
内置变量 | 含义 |
---|---|
FILENAME | 当前文件 |
NR | 当前行号 |
NF | 分割后的列数 |
**案例1:**搜索/etc/passwd
文件中以root开头的所有行,以冒号:
为分隔符,输出其第7列内容
# 这里的$7可理解为:把该行分割后的内容当作后续print的入参,所以输出第7列就可以用$7
cat /etc/passwd | awk -F ":" '/^root/{print $7}'
# 或者
awk -F ":" 'BEGIN{print "HELLO"} /^root/{print $1", "$7} END{print "WORLD"}' /etc/passwd '/^root/{print $7}' /etc/passwd
**案例2:**搜索/etc/passwd
文件中以root开头的所有行,以冒号:
为分隔符,输出其第1列和第7列内容,并以逗号连接
awk -F ":" 'BEGIN{print "HELLO"} /^root/{print $1", "$7} END{print "WORLD"}' /etc/passwd '/^root/{print $1", "$7}' /etc/passwd
**案例3:**搜索/etc/passwd
文件中以root开头的所有行,以冒号:
为分隔符,输出其第1列和第7列内容,并以逗号连接;并在这些内容的第一行打印"HELLO",在最后一行打印"WORLD"
awk -F ":" 'BEGIN{print "HELLO"} /^root/{print $1", "$7} END{print "WORLD"}' /etc/passwd
# 结果如下
HELLO
root, /bin/bash
WORLD
**案例4:**搜索/etc/passwd
文件中所有的用户id(以冒号分割后的第3列),打印这些用户id 加1后的值
# 引用-v定义的变量时,不需要加$
awk -F ":" -v var=1 '{print $3 + var}' /etc/passwd
案例5:测试内置变量
awk -F ":" '{print "文件名:"FILENAME ",当前行数:"NR ",本行列数:"NF }' /etc/passwd
5 shell脚本案例
5.1 文件备份
- 需求:对指定目录的文件进行压缩备份
#!/bin/bash
# 校验输入参数是否正确
if [ $# -ne 1 ]
then
echo "参数个数有误,应输入1个参数"
exit
fi
# 校验输入的参数目录是否存在
if [ -d $1 ]
then
echo
else
echo "目录不存在"
exit
fi
# 获取目录的绝对路径
dir_name=$(basename $1)
dir_path=$(cd $(dirname $1); pwd)
# 获取当前日期
date=$(date +%y%m%d)
# 定义备份文件名
file_name=archive_${dir_name}_${date}.tar.gz
dest=/opt/${file_name}
# 备份
echo "开始备份..."
tar -czPf ${dest} ${dir_path}/${dir_name}
if [ $? -eq 0 ]
then
echo "备份成功,文件为:${dest}"
else
echo "备份失败"
fi
exit
5.2 发送消息
- 需求:实现向某个用户发送消息的功能
- 基本命令:who 和 write
# 查看当前登录服务器的所有用户
who -T
# 结果如下
# “+”表示打开了消息功能,“pts/1”表示控制台
root + pts/0 2022-09-07 10:00 (10.168.6.84)
chihaya + pts/1 2022-09-07 11:08 (10.168.6.84)
# 给chihaya用户发送消息,要指定控制台
write chihaya pts/1
#!/bin/bash
# 该脚本第一个参数是指定用户,后面的参数是消息
# 校验指定用户是否登录
login_user=$(who -T | grep -i -m 1 $1 | awk '{print $1}')
# -z判断是否为空
if [ -z ${login_user} ]
then
echo "$1不在线"
exit
fi
# 校验指定用户是否开启消息功能
allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ ${allowed} != "+" ]
then
echo "$1未开启消息功能"
exit
fi
# 校验消息是否为空
if [ -z $2 ]
then
echo "消息为空"
exit
fi
# 获取用户的终端控制台
user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
# 获取要发送的消息,即第2个参数到最后一个参数
all_msg=$(echo $* | cut -d " " -f 2-)
# 发送消息
echo "${all_msg}" | write ${login_user} ${user_terminal}
if [ $? -eq 0 ]
then
echo "消息发送成功..."
else
echo "消息发送失败..."
fi
exit
6 软件包管理
6.1 RPM
RPM(RedHat Package Manager),RedHat 软件包管理工具,类似Windows的setup.exe,是Linux的打包安装工具。
例如xxx-1.3.23-11.i386.rpm
- xxx:软件名称
- 1.3.23-11:版本号
- i386:硬件平台,Intel 32处理器的统称
- rpm:文件后缀
命令 | 解释 | 例子 |
---|---|---|
rpm -qa | 查询所有安装的软件包 | rpm -qa | grep firefox |
rpm -qi xxx | 查询软件的详细信息 | rpm -qi firefox |
rpm -e [--nodeps] xxx | 卸载软件 可选参数--nodeps:表示无视依赖关系直接卸载 | rpm -e firefox |
rpm -ivh 安装包全名 | 安装软件 -i:install,表示安装 -v:显示详细信息 -h:显示进度条 --nodeps:安装前不坚持依赖 | rpm -ivh firefox-68.10.0-1.el7.centos.x86_64.rpm |
6.2 YUM
6.2.1 基本介绍
YUM是基于RPM包管理,能够从指定服务器自动下载RPM包并且安装,且可以自动处理软件包的依赖关系,一次性安装所有依赖的软件包。类似Maven工具,可以从镜像网站上下载程序并安装。基本命令如下:
yum [选项] [参数]
选项 | 解释 | 例子 |
---|---|---|
-y | 对操作过程中的所有提问都回答 "yes" |
参数 | 解释 | 例子 |
---|---|---|
install | 安装rpm软件包 | yum -y install firefox |
update | 更新rpm软件包 | |
check-update | 检查是否有可用的rpm更新包 | |
remove | 删除指定的rpm软件包 | |
list | 显示软件包信息 | |
clean | 清理过期的缓存 | |
deplist | 显示所有依赖关系 |
6.2.2 修改YUM源
默认的YUM源是连接国外网站,网速较慢,因此可以修改YUM源为国内的镜像网站,如aliyun等
- 进入目录
/etc/yum.repos.d/
,备份默认的repo文件
cd /etc/yum.repos.d/
cp CentOS-Base.repo CentOS-Base.repo.backup
rm -rf CentOS-Base.repo
- 下载aliyun的repo文件
wget https://mirrors.aliyun.com/repo/Centos-7.repo
- 更改新下载的repo文件名
mv Centos-7.repo CentOS-Base.repo
- 清理旧缓存
yum clean all
yum makecache