【学习笔记】Linux知识点

54 阅读4分钟

1 文件系统和挂载点

Linux系统中一切皆文件

Linux目录结构.png

  • /bin:存放常用的命令
  • /opt:默认第三方软件的安装目录

挂载点:我们可以把某个硬盘的某个分区都挂载到某个目录下,如/home/abc,这样该目录下存放的数据都会存放在指定的硬盘的分区上。就是说Linux的目录结构是逻辑上的,是虚拟的,并不是物理上的硬盘目录

2 vim编辑器

vim.png

注意: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 变量

  1. 常见的系统变量有:HOMEHOME,PWD等,以及用户配置的环境变量,如$JAVA_HOME等

  2. 自定义变量:变量名=变量值,等号前后不能有空格

a=10
b=20
username="jack"
  1. 只读变量
readonly c=5
  1. 特殊变量
    • $n :n是数字,$0表示该脚本名称,$1~$9代表前9个参数,10个及以上的参数要加{},如${10}
    • $# :获取输入参数的个数,常用于循环
    • $* 和 $@ :获取所有输入参数,区别是前者把所有参数看成一个整体;后者把每个参数分开,得到一个集合
    • $? :最后一次执行命令的返回状态,如果为0,说明上一个命令正确执行;如果非0,则说明上一个命令执行有误

3.3 运算符

  1. expr
# 反引号表示里面命令符不看成字符串,而看成命令来执行,于是得到a变量的值为30。注意空格!
a=`expr 10 + 20`

# 乘号*要加转义符\
b=`expr 2 \* 5`
  1. ((运算式))或者((运算式)) 或者 [运算式子],可以不加空格
a=$((3+7))

b=$[3*(2+4)]

3.4 条件判断

  1. 基本语法:[ 条件 ],要注意中括号与条件之间的空格

  2. 比较符:

比较符含义
-eq等于
-ne不等于
-lt小于
-le小于等于
-gt大于
-ge大于等于
=字符串之间的判断相等
!=字符串之间的判断不等
-z字符串是否为空
-n字符串是否为不为空
  1. 文件相关的判断:
判断符含义
-r判断文件是否有权限
-w判断文件是否有权限
-x判断文件是否有执行权限
-e判断文件是否存在
-f判断是否为一个文件
-d判断是否为一个文件夹
  1. 逻辑与或:&&(逻辑与)、||(逻辑或)

同时使用&&和||,可实现三目运算符的作用,如下所示

# 判断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}前面可以加BEGINEND关键字。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等

  1. 进入目录/etc/yum.repos.d/,备份默认的repo文件
cd /etc/yum.repos.d/

cp CentOS-Base.repo CentOS-Base.repo.backup

rm -rf CentOS-Base.repo
  1. 下载aliyun的repo文件
wget https://mirrors.aliyun.com/repo/Centos-7.repo
  1. 更改新下载的repo文件名
mv Centos-7.repo CentOS-Base.repo
  1. 清理旧缓存
yum clean all
yum makecache

7 参考资料