searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Linux学习笔记

2025-09-08 02:21:53
1
0

1. Linux的文件权限

对于每一个文件来说,使用它的用户主要分为三个类别:文件的拥有者、文件所属群组中的用户、其他用户。另外,root用户是比较特别的,他拥有特别大的权利。 如果需要root的权限,可以使用 su - 这个指令来切换身份。处理完毕后使用 exit 退出。

使用ls命令查看当前工作目录下的文件信息:

dr-xr-x---.  5 root root  248 Jul 23 10:47 .
dr-xr-xr-x. 17 root root  224 Jan 27  2023 ..
-rw-------.  1 root root 2843 Jan 27  2023 anaconda-ks.cfg
-rw-------.  1 root root 1561 Jan 31  2023 .bash_history

...

前十个字符中,第一个表示文件(-)、目录(d)、链接(l)等,接下来的九个字符中,每三个一组就分别代表了三种用户的权限:r表示读权限、w表示写权限、x表示可执行权限,另外,-代表没有该种权限。 相关命令:

  • chgrp:改变文件所属的群组
  • chown:改变文件拥有者
  • chmod:改变文件的权限(rwx分别对应4,2,1)

对于文件来说:

  • r:可以读取该文件的内容。
  • w:可以编辑该文件的内容(不能删除)
  • x:该文件可以被执行

对于目录来说:

  • r:可以查询该目录下的文件名
  • w:可以创建删除新的文件、目录;对已存在的文件和目录更改名字等;
  • x:可以进入该目录作为工作目录(cd进来)

2. Linux文件和目录管理

一些特殊的目录:

.    此层目录
..   上一层目录
-    前一个工作目录
~    “目前使用者身份”所在的主文件夹

一些常见的处理目录的指令:

cd:变换目录
pwd:显示目前目录
mkdir:创建新的目录
rmdir:删除空目录

2.1 文件与目录管理

使用ls来查看目录下的内容,常用到 -l

使用cp复制文件或目录,默认复制出的新文件与来源文件的权限是不同的,新文件的拥有者是指令操作者。

使用rm来删除文件或者目录

使用mv来移动文件与目录,或者更名

使用basename、dirname取得路径的文件名和目录名

2.2 文件内容查阅

使用cat查看文件内容

使用tac(cat反过来)从后往前查看文件内容

使用more、less(更常用)查看文件内容(可以翻页)

使用head、tail查看文件的头部、尾部多少行内容(使用tail -f xxxx来持续检测文件内容,新写入的数据都会被显示到屏幕上)

使用touch来创建文件或者修改文件的时间属性为当前(mtime文件修改时间、atime文件读取时间)

2.3 文件与目录的默认权限和隐藏权限

使用 umask 命令查看或者设置当前使用者在创建文件或目录时的权限默认值。在默认权限的属性上,目录与文件是不一样的。另外,该命令显示的是被拿掉的值。例如,umask为022,则user没有被拿掉任何权限,group和others被拿掉了2的权限。

使用chattr设置文件隐藏属性,chattr +i 可以让文件“不能被删除、改名、修改内容”,连root都不能。

使用isattr显示文件隐藏属性。

另外,文件还存在一些特殊权限:SUID、SGID、SBIT

  • SUID:当s出现在文件拥有者的x权限时:“-rwsr-xr-x”,此时就叫做Set UID简称为SUID。SUID有这样的功能与限制:1. 执行者将具有该程序拥有者的权限。2. 本权限只在执行该程序的过程中有效。3. 执行者对于该程序需要具有x的可执行权限。 例子:虽然记录密码的文件/etc/shadow只有root可读且修改,但是普通用户也可以修改自己的密码呀。这不相当于普通用户修改了shadow文件吗?其实,这里就涉及到了SUID。普通用户在执行的过程中暂时过得了root权限。
  • SGID:显然,当这个s出现在group的x位置的时候,就叫做SGID,出现在文件中:1. 程序的执行者对于该程序来说,需要具备x的权限。2. 执行者在执行的过程中将会获得该程序群组的支持;出现在目录中:使用者在此目录下的有效群组将会变成该目录的群组。

2.4 指令与文件的搜索

使用which命令寻找可执行文件的文件名(根据PATH环境变量)

使用whereis命令查找文件或者目录(比find命令快很多,因为前者只在特定的几个目录里边寻找,后者全盘搜索)

(常用)使用locate命令查找文件或者目录,输入部分名称也能得到结果。(如果数据库没有及时更新,可能导致搜索不到目标文件。可以使用updatedb命令手动更新数据库)

使用find命令查找文件。可包含时间参数,例如查找四天内被修改过的文件。


2025.8.14

3. 定时任务调度

使用 crond、atd 来完成定时任务调度:

  • Crond 执行周期性任务
    • 使用 crontab -e 编辑内容,创建周期性任务
    • 使用 crontab -l 查看任务
  • Atd 执行一次性定时任务
    • 使用 at 指令指定任务
    • 使用 atq 查看任务队列

4. Linux文件系统底层

Linux操作系统的文件除了实际内容外,还有非常多的属性,例如文件权限(rwx)、文件属性(拥有者、群组、时间参数等),文件系统通常将这两部分数据分别放在不同的区块,权限和属性放在 inode 中,实际数据放在 data block中。另外,还有一个 superblock 用于记录整个文件系统的整体信息:

  • superblock: 记录此filesystem的整体信息,包括inode/block的总量、使用量等;
  • inode:记录文件属性,一个文件占用一个inode,同时记录此文件的数据所在block号码;
  • block:实际记录文件的内容,若文件太大,会占用多个block。一个block最多存放一个文件的数据。

以上被称为索引式文件系统。而U盘一般使用的文件系统叫FAT格式,这种格式没有inode,每一个block都会记录下一个block的位置 假设文件的数据依次写入1、7、4、15这四个block,但是这个文件系统没办法一口气直到这四个号码,它得一个一个地读。所以如果一个文件的数据写得太过分散时,磁盘就需要转好几圈才能读取到所有数据,效率低。

继续介绍Ext2文件系统(Linux),其分为多个block group,每一个group都有独立的inode、block、superblock。

当我们创建一个目录时,文件系统会分配一个inode和至少一块block给该目录。其中inode用于记录该目录的相关权限与属性;而block则是记录在这个目录下的文件名与该文件名占用的inode号码数据。

所以文件的名字实际是存储在目录的block中的。

读取文件或者目录的流程:inode和block反复跳转。。。。 新建文件或者目录的流程:查看权限,查看inode bitmap,哪里有未使用的inode?查看block bitmap,哪里有未使用的block?

5. Shell script

shell有多个版本,/bin/sh /bin/bash... 通常是使用bash。在shell脚本中,通常以 #!/bin/bash开始。表明使用/bin/bash执行。如下:

#!/bin/bash

写好xxx.sh文件后,有几种执行它的方法。第一种是使用bash工具,如下:

bash xxx.sh

第二种是直接将这个xxx.sh的属性修改为可执行文件,然后直接运行它(这是常用方法):

chmod +x xxx.sh
./xxx.sh
# 这里的./只是为了防止直接写出xxx.sh,它会误认为xxx.sh是一个linux命令。

以上两种方法都会在当前的bash环境中创建一个子bash,那么父bash中的局部变量啊啥的就无法在子bash中使用了(全局变量还可以)。下面的两种方法,就不会创建父子bash环境,而是直接在大bash环境中执行:

source xxx.sh
# or
. xxx.sh

5.1 变量

通常来说,shell中的系统变量都以大写字母来表示,例如:

$HOME  $HOSTNAME

可以使用 set 命令来查看bash环境中的局部变量和全局变量:

set

用户自己定义局部变量,规范如下:

# 等号两边不要有空格
my_var="hello, world"
# 修改值就直接修改
my_var=hello
# 使用变量这个值的时候,需要加一个$符号
echo $my_var
# 使用export,将局部变量提升为全局变量
export my_var

此时,在子bash中就可以看到这个my_var了。但是,子bash中的修改对其不起作用。

可以使用readonly将变量设置为常量,如下:

readonly a=hello
a=tyy        # 报错

使用unset将一个变量清除掉:

b=hello
unset b
echo $b        # 没有了

在bash中,默认所有的变量都是字符串类型,比如:

x=1+5
echo $x        # 结果为1+5,而不是6

5.2 shell脚本参数

在bash中,每当你输入一个命令:

ls

系统会在一个特定的路径去寻找这个命令,有就执行,没有就报错。这个路径就是$PATH:

echo $PATH
# 结果:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

所以,如果你将自己写的xxx.sh放到其中的某一个路径下:

cp xxx.sh /bin/        # 将xxx.sh复制到根目录下的bin中

那么就可以实现,直接输入xxx.sh,就可以当做是一个命令一样去执行:

xxx.sh
# 输出xxx.sh中的结果

使用$n可以获取脚本的参数:

echo "name of script: $0"        # 其中$0比较特殊,会输出脚本的名称xxx.sh
echo "the first parameter: $1"
echo "the second parameter: $2"

使用$#可以获取脚本的参数个数,常用于循环:

echo $#

使用$*, 和$@都可以获取脚本的所有参数,只是前者返回的是一个整体(比如“a b c”),而后者相当于返回一个参数的集合(比如[a, b, c])

echo $@
echo $*

5.3 数值运算

在bash中,想要使用数值运算,可以将运算写在$[]中,例如:

#!/bin/bash
a=10
s=$[a + 2]        # 也可以使用$(())
echo $s        # 得到结果12

5.4 判断、循环等逻辑

在bash中,如果想要执行条件判断,可以使用 test condition,或者 [ condition ](通常使用这个),例如:

#!/bin/bash
a=10
s=$[$a + 2]
test $s = 12        # 或者 [ $s = 12 ],中括号里边一定要各有一个空格
echo $?        # 使用$?可以返回上一条命令执行的结果,0为true

使用 -lt -gt -eq等等判断数值(less than, greater than, equal)

使用 -r -w -x 判断文件的权限

[ -r xxx.sh ]        # 判断xxx.sh是否有可读的权限?

使用 -e 判断文件是否存在(existence), -f 文件存在,且是一个常规文件, -d 文件存在而且是一个目录

#!/bin/bash
[ -e /bin/bash ]
echo $?                # 得到0,表示存在

下面这句话可以起到java中的三目运算符的效果:

a=20
[ $a -gt 15 ] && echo "$a > 15" || echo "$a < 15"
# 输出20 > 15

条件判断,格式如下:

#!/bin/bash
str="chr"
if [ $str = "chr" ]
then
        echo "welcome, chr"
fi

多条件判断,如下:

if [ a -gt 12 ] && [......] || [....]
then
        do something
fi

如果想要把条件都放在一个括号里边,可以使用 -a 或者 -o连接。(and和or)

#!/bin/bash
age=140
if [ $age -lt 18 ]
then
        echo "未成年"
elif [ $age -lt 35 ]
then 
        echo "青年人"
elif [ $age -lt 60 ]
then 
        echo "壮年人"
else
        echo "老年人"
fi

多分支,使用case:(注意两个分号哦)

#!/bin/bash
number=3
case $number in
1) 
        echo "one"
;;
2)
        echo "two"
;;
*)
        echo "else"
;;
esac

for 循环:

#!/bin/bash
for animal in dog cat elephant
do
  echo "there are ${animal}"
done

while 循环:

#!/bin/bash
while [ "${yn}" != "yes" ]
do
  read-p "infor" yn
done

6. Linux 磁盘分区、挂载

Linux 使用“载入”的方法将硬盘的一个分区与文件系统的一个目录联系起来。

Linux 硬盘分为 IDE 硬盘和 SCSI 硬盘,其中 SCSI 硬盘的标识为 “sdx~”,比如 sda1 表示基本盘(“a”)的第一个分区,sdb3 表示从属盘的第二个分区。

使用 lsblk 命令 查看所有设备的挂载情况

6.1 如何增加一块硬盘?

  1. 添加一块硬盘
  2. 分区
    1. 使用命令 fdisk 对硬盘分区。例如新添加了一块硬盘 sdb(通常放置在 /dev/ 下),可以使用 fdisk /dev/sdb 对其进行分区
  3. 格式化(在分区上创建文件系统)
    1. 使用命令 mkfs 对硬盘进行格式化。例如 mkfs -t ext4 /dev/sdb1
  4. 挂载
    1. 使用 mount 命令将分区挂载到目录上。例如将 sbd1 分区挂载到 /newDist 目录上:mount /dev/sdb1 /newDist
    2. 可以使用 umount 卸载:umount /dev/sdb1
    3. 使用指令挂载分区,重启之后挂载会失效
  5. 设置自动挂载
    1. 编辑 /etc/fstab 文件,可以将分区自动挂载到目录

使用 df -h 查看磁盘使用情况

使用 du -h 指令查询指定目录的磁盘占用情况

一些常用指令:

  • 统计 /data 下文件的数量

ll /data | grep '^-' | wc -l

  • 统计 /data 下目录的个数

ll /data | grep '^d' | wc -l

  • 使用 tree 指令以树状图查看目录情况

7. Linux账号管理

每一个登录的使用者都会取得两个ID:一个user id,一个 group id。

一个用户可以同时存在多个群组中,那当这个用户创建一个文件后,该文件的群组是?(是用户当前的有效群组,使用groups命令查看,第一个群组就是有效群组) 可以使用newgrp来切换有效群组(会切换进入一个新的shell)

Linux的账号信息多涉及到:

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /etc/gshadow

使用 useradd 命令添加用户,在centos7中,每一个新用户newUser在/home目录都会有一个主文件夹。(比如用户chr的主文件夹为/home/chr)

使用 usermod 来修改用户相关

使用 userdel 删除用户

使用 id 查询某人或自己的UID等相关信息

groupadd, groupmod, groupdel

7.1 ACL

在linux中使用ACL来实现颗粒度更细的权限分配(以前只能在所有者、群组以及其他人这三个范围内修改权限)

使用

  • getfacl
  • setfacl
[root@study ~] setfacl -m u:vbird1:rx acl_test1
[root@study ~] ll acl_test1
-rw-r-xr--+ 1 root root 0 Jul 21 17:33 acl_test1
# 权限部分多了个 + ,且与原本的权限 (644)
[root@study ~]# getfacl acl_test1
# file: acl_test1   &lt;==说明文档名而已!
# owner: root       &lt;==说明此文件的拥有者,亦即 ls -l 看到的第三使用者字段
# group: root       &lt;==此文件的所属群组,亦即 ls -l 看到的第四群组字段
user::rwx           # 使用者列表栏是空的,代表文件拥有者的权限
user:vbird1:r-x     # 针对 vbird1 的权限设置为 rx ,与拥有者并不同!
group::r--         # 针对文件群组的权限设置仅有 r
mask::r-x          # mask用来规范此文件的最大权限,别人的权限只能是mask这里的子集
other::r--         # 其他人拥有的权限啰!

8. Linux网络配置

网络地址转换 NAT:

虚拟机的 ip 可以和宿主机的虚拟网卡 vmnet8 相互 ping 通,NAT 服务将由虚拟机发送的数据包的源 ip 转换为宿主机的物理网络适配器的 ip 地址。

可以通过修改配置文件来指定 ip,编辑:

vim /etc/sysconfig/network-scripts/ifcfg-ens33

可以通过修改 /etc/hostname 指定主机名

通过修改配置文件,可以建立主机名与 ip 的映射,例如,在 linux 中,可以修改 /etc/hosts 文件,指定某个 ip 与主机名的映射,之后就可以通过主机名来访问对应的 ip。

9. Linux进程管理

Linux中的每一个进程都有一个 pid

使用 ps -aux 命令查看当前所有的进程

其中 STAT 表示进程当前的状态,s 表示 sleeping,r 表示 running,z 表示 僵尸进程(需要定时清除)

TTY 表示终端名称

使用 ps -ef 可以查看到进程的父进程 pid

使用 kill 指令杀死某一个进程,使用 killall 杀死进程及其子进程

kill 1324
killall gedit
kill -9 423    # 强制 kill

使用 pstree 以树状的形式查看进程

9.1 服务管理

服务本质就是运行在后台的进程,也称为守护进程 daemon(所以多以 d 结尾)。它们通常都会监听某一个端口,等待其他程序的请求。

使用 service 服务名 [start | stop | status ...] 来管理服务(现在很多服务都不再用 service 管理,而是使用 systemctl 管理)

服务的运行级别有七种,常用的级别是3和5:

  • 3:多用户状态(有网络),无界面,登录后植入控制台命令行模式
  • 5:登录后进入图形GUI模式

使用 systemctl get-default 和 systemctl set-default 设置服务的运行级别

使用 chkconfig 管理各个服务在不同运行级别的自启动情况(同样也是被 systemctl 代替)

9.2 systemctl

几乎所有服务都可以使用 systemctl 管理。具体语法是:

systemctl [start | stop | restart | status] 服务名

Systemctl 管理的服务可以在 /usr/lib/systemd/system 中查看(ubuntu 下是在 /etc/systemd/system)

使用 systemctl list-unit-files 查看服务的自启动状态

使用 systemctl enable/disable 服务名 开启/关闭服务开机自启

使用 systemctl is-enabled 服务名 查询某个服务是否是自启动的

9.3 防火墙

外部客户端想要访问linux中的服务时,会首先被防火墙检测。如果这个服务的端口是对外开放的,则可以访问。反之,访问不了。

telnet 192.168.200.130 111    # 访问这个ip下面的111端口

防火墙比较重要,应该打开。但是有的时候,某一个服务就需要被外部客户端访问,如何将这个服务对外开放呢?

firewall-cmd --permanent --add-port=端口号/协议  # 开放某一个端口
# 关闭、重新载入防火墙、查询端口是否开放等都有相应的指令,这里就不记录了

9.4 动态查看进程

使用 top 动态显示正在执行的进程

使用 P 按照CPU使用率排序,使用 M 以内存使用率排序

输入 u 可以指定查看目标用户相关的进程

输入 k 可以杀死目标进程

9.5 netstat 查看系统网络状况

键入 netstat -anp 可以查看当前系统有哪些服务处于监听状态,哪些服务处于连接状态等

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      1235/dnsmasq    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      5989/sshd       
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      3076/cupsd      
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      944/postgres    
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      2715/8          
tcp        0      0 192.168.163.129:22      192.168.163.1:51474     ESTABLISHED 2715/8          
tcp        0      0 192.168.163.129:22      192.168.163.1:51483     ESTABLISHED 2870/sshd: root@not

# 第八行表示,本地的22端口与外部ip为192.168.163.1,端口号为51483的服务进行了连接
# 协议为tcp协议(且本地的这个服务是sshd)

10. Linux软件包管理

Yum是一个shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,同时它可以自动处理依赖性关系,一次安装所有依赖的软件包。

使用 yum list 查询yum服务器是否有需要安装的软件

下载安装指定的yum包: yum install xxx

(在ubuntu系统中,与yum所对应的是 apt 指令)

当执行 apt install 命令时,linux从远程服务器下载软件包。主要涉及:

  • 软件源:软件源通常是官方或者第三方维护的软件仓库,这些服务器上存放着大量的软件包。
  • 源列表:Linux系统上有一个配置文件,里面记录了这些软件源服务器的地址。

所以,总结就是:软件包来源于远程的软件源服务器,但 apt 依靠本地的索引数据库来知道该下载什么。(软件被安装后,它的文件就分散到了系统的各个标准位置,而不是集中在一个文件夹里)

apt工具的相关指令有:

  • Sudo apt update: 当你执行 sudo apt update 时,apt 工具会连接到源列表中配置的服务器,下载最新的软件包索引列表到本地。(sudo apt update 几乎是必做的一个步骤)
  • Sudo apt upgrade: 升级所有已安装的软件包。
  • Sudo apt install <package name="">: 安装指定软件包。
  • Sudo apt remove <package name="">: 卸载指定软件包。
  • apt search <keyword>:在软件源中搜索包含关键字的软件包。

11. Linux日志管理

在Linux系统中,日志文件通常是存储在 /var/log 下面。其中日志文件较多,重要的日志文件主要有:

/var/log/syslog

  • 系统的“万能日志”,几乎所有服务和内核消息都会写入这里。
  • 用来查看大部分系统运行时信息和排错。

/var/log/auth.log

  • 记录认证相关日志,例如 SSH 登录、sudo 使用、用户登录和失败尝试。
  • 对安全审计非常关键。

/var/log/kern.log

  • 内核日志,记录内核产生的消息。
  • 当涉及驱动、硬件问题时非常重要。

/var/log/dmesg

  • 系统启动时内核检测硬件的输出信息。
  • 经常用来排查设备驱动加载和硬件识别问题。

/var/log/apt/history.log

  • 记录通过 APT(包管理器)进行的软件安装、升级和卸载操作。
  • 用于追踪系统软件变动历史。

/var/log/dpkg.log

  • 更底层的包管理日志,记录 dpkg 的具体操作。
  • 结合 apt/history.log 可以完整了解系统软件变动。

/var/log/Xorg.0.log

  • X Window(图形界面)的日志文件。
  • 图形界面启动失败时,常要查看这里。

日志管理服务 rsyslogd 负责将日志写入 /var/log/*.log 中去,它通过配置文件 /etc/rsyslog.conf 决定将不同的日志信息写入到不同的日志文件中。

  • 查询Linux中的rsyslogd服务是否启动 ps aux | grep "rsyslog"
  • 查询rsyslogd服务的自启动状态 systemctl list-unit-files | grep "rsyslog"

在ubuntu中,重要的配置文件在/etc/rsyslog.d/*.conf中,如下:

其中的格式是:

*.*      存放日志文件
第一个*代表日志类型,比如auth、corn、kern、mail等
第二个*代表日志级别,比如debug、info、emerg等

具体的日志信息如何看?

Aug 24 22:47:42 ubuntu sshd[4699]: Accepted password for root from 192.168.163.1 port 49709 ssh2
     日期        主机      服务       具体信息

(在现代Ubuntu中,很多系统服务的日志是先写到systemd-journald,再由它转发给rsyslog)

11.1 日志轮替

在Ubuntu中,日志轮替主要是依靠 logrotate 工具来完成,它的配置文件在 /etc/logrotate.conf,这里用于存放所有日志的轮替规则。同时, /etc/logrotate.d/ 下可以单独为某些日志存放轮替规则。

日志轮替怎么运行的?

/var/log/syslog 为例:

当前日志文件​​满了​,logrotate 会:

  • syslog 重命名为 syslog.1
  • 创建一个新的空白 syslog 文件(继续写入)
  • 旧的 syslog.1 可以再压缩成 syslog.1.gz
  • 更老的可能是 syslog.2.gz, syslog.3.gz ……

保留时间与数量

  • 通过配置指定,比如“保留 7 天日志”或者“保留 4 个历史文件”。

配置文件大概长这样:

# /etc/logrotate.d/rsyslog

/var/log/syslog
{
    rotate 7
    daily
    missingok
    notifempty
    delaycompress
    compress
    postrotate
        invoke-rc.d rsyslog rotate > /dev/null
    endscript
}
  • rotate 7 → 保留 7 个旧日志
  • daily → 每天轮替一次
  • missingok → 如果日志不存在,不报错
  • notifempty → 如果日志为空,就不轮替
  • compress → 用 gzip 压缩旧日志
  • delaycompress → 延迟一轮再压缩(避免刚写完的日志立刻压缩)
  • postrotate … endscript → 通知 rsyslog 重新打开日志文件
0条评论
作者已关闭评论
陈****然
3文章数
0粉丝数
陈****然
3 文章 | 0 粉丝
陈****然
3文章数
0粉丝数
陈****然
3 文章 | 0 粉丝
原创

Linux学习笔记

2025-09-08 02:21:53
1
0

1. Linux的文件权限

对于每一个文件来说,使用它的用户主要分为三个类别:文件的拥有者、文件所属群组中的用户、其他用户。另外,root用户是比较特别的,他拥有特别大的权利。 如果需要root的权限,可以使用 su - 这个指令来切换身份。处理完毕后使用 exit 退出。

使用ls命令查看当前工作目录下的文件信息:

dr-xr-x---.  5 root root  248 Jul 23 10:47 .
dr-xr-xr-x. 17 root root  224 Jan 27  2023 ..
-rw-------.  1 root root 2843 Jan 27  2023 anaconda-ks.cfg
-rw-------.  1 root root 1561 Jan 31  2023 .bash_history

...

前十个字符中,第一个表示文件(-)、目录(d)、链接(l)等,接下来的九个字符中,每三个一组就分别代表了三种用户的权限:r表示读权限、w表示写权限、x表示可执行权限,另外,-代表没有该种权限。 相关命令:

  • chgrp:改变文件所属的群组
  • chown:改变文件拥有者
  • chmod:改变文件的权限(rwx分别对应4,2,1)

对于文件来说:

  • r:可以读取该文件的内容。
  • w:可以编辑该文件的内容(不能删除)
  • x:该文件可以被执行

对于目录来说:

  • r:可以查询该目录下的文件名
  • w:可以创建删除新的文件、目录;对已存在的文件和目录更改名字等;
  • x:可以进入该目录作为工作目录(cd进来)

2. Linux文件和目录管理

一些特殊的目录:

.    此层目录
..   上一层目录
-    前一个工作目录
~    “目前使用者身份”所在的主文件夹

一些常见的处理目录的指令:

cd:变换目录
pwd:显示目前目录
mkdir:创建新的目录
rmdir:删除空目录

2.1 文件与目录管理

使用ls来查看目录下的内容,常用到 -l

使用cp复制文件或目录,默认复制出的新文件与来源文件的权限是不同的,新文件的拥有者是指令操作者。

使用rm来删除文件或者目录

使用mv来移动文件与目录,或者更名

使用basename、dirname取得路径的文件名和目录名

2.2 文件内容查阅

使用cat查看文件内容

使用tac(cat反过来)从后往前查看文件内容

使用more、less(更常用)查看文件内容(可以翻页)

使用head、tail查看文件的头部、尾部多少行内容(使用tail -f xxxx来持续检测文件内容,新写入的数据都会被显示到屏幕上)

使用touch来创建文件或者修改文件的时间属性为当前(mtime文件修改时间、atime文件读取时间)

2.3 文件与目录的默认权限和隐藏权限

使用 umask 命令查看或者设置当前使用者在创建文件或目录时的权限默认值。在默认权限的属性上,目录与文件是不一样的。另外,该命令显示的是被拿掉的值。例如,umask为022,则user没有被拿掉任何权限,group和others被拿掉了2的权限。

使用chattr设置文件隐藏属性,chattr +i 可以让文件“不能被删除、改名、修改内容”,连root都不能。

使用isattr显示文件隐藏属性。

另外,文件还存在一些特殊权限:SUID、SGID、SBIT

  • SUID:当s出现在文件拥有者的x权限时:“-rwsr-xr-x”,此时就叫做Set UID简称为SUID。SUID有这样的功能与限制:1. 执行者将具有该程序拥有者的权限。2. 本权限只在执行该程序的过程中有效。3. 执行者对于该程序需要具有x的可执行权限。 例子:虽然记录密码的文件/etc/shadow只有root可读且修改,但是普通用户也可以修改自己的密码呀。这不相当于普通用户修改了shadow文件吗?其实,这里就涉及到了SUID。普通用户在执行的过程中暂时过得了root权限。
  • SGID:显然,当这个s出现在group的x位置的时候,就叫做SGID,出现在文件中:1. 程序的执行者对于该程序来说,需要具备x的权限。2. 执行者在执行的过程中将会获得该程序群组的支持;出现在目录中:使用者在此目录下的有效群组将会变成该目录的群组。

2.4 指令与文件的搜索

使用which命令寻找可执行文件的文件名(根据PATH环境变量)

使用whereis命令查找文件或者目录(比find命令快很多,因为前者只在特定的几个目录里边寻找,后者全盘搜索)

(常用)使用locate命令查找文件或者目录,输入部分名称也能得到结果。(如果数据库没有及时更新,可能导致搜索不到目标文件。可以使用updatedb命令手动更新数据库)

使用find命令查找文件。可包含时间参数,例如查找四天内被修改过的文件。


2025.8.14

3. 定时任务调度

使用 crond、atd 来完成定时任务调度:

  • Crond 执行周期性任务
    • 使用 crontab -e 编辑内容,创建周期性任务
    • 使用 crontab -l 查看任务
  • Atd 执行一次性定时任务
    • 使用 at 指令指定任务
    • 使用 atq 查看任务队列

4. Linux文件系统底层

Linux操作系统的文件除了实际内容外,还有非常多的属性,例如文件权限(rwx)、文件属性(拥有者、群组、时间参数等),文件系统通常将这两部分数据分别放在不同的区块,权限和属性放在 inode 中,实际数据放在 data block中。另外,还有一个 superblock 用于记录整个文件系统的整体信息:

  • superblock: 记录此filesystem的整体信息,包括inode/block的总量、使用量等;
  • inode:记录文件属性,一个文件占用一个inode,同时记录此文件的数据所在block号码;
  • block:实际记录文件的内容,若文件太大,会占用多个block。一个block最多存放一个文件的数据。

以上被称为索引式文件系统。而U盘一般使用的文件系统叫FAT格式,这种格式没有inode,每一个block都会记录下一个block的位置 假设文件的数据依次写入1、7、4、15这四个block,但是这个文件系统没办法一口气直到这四个号码,它得一个一个地读。所以如果一个文件的数据写得太过分散时,磁盘就需要转好几圈才能读取到所有数据,效率低。

继续介绍Ext2文件系统(Linux),其分为多个block group,每一个group都有独立的inode、block、superblock。

当我们创建一个目录时,文件系统会分配一个inode和至少一块block给该目录。其中inode用于记录该目录的相关权限与属性;而block则是记录在这个目录下的文件名与该文件名占用的inode号码数据。

所以文件的名字实际是存储在目录的block中的。

读取文件或者目录的流程:inode和block反复跳转。。。。 新建文件或者目录的流程:查看权限,查看inode bitmap,哪里有未使用的inode?查看block bitmap,哪里有未使用的block?

5. Shell script

shell有多个版本,/bin/sh /bin/bash... 通常是使用bash。在shell脚本中,通常以 #!/bin/bash开始。表明使用/bin/bash执行。如下:

#!/bin/bash

写好xxx.sh文件后,有几种执行它的方法。第一种是使用bash工具,如下:

bash xxx.sh

第二种是直接将这个xxx.sh的属性修改为可执行文件,然后直接运行它(这是常用方法):

chmod +x xxx.sh
./xxx.sh
# 这里的./只是为了防止直接写出xxx.sh,它会误认为xxx.sh是一个linux命令。

以上两种方法都会在当前的bash环境中创建一个子bash,那么父bash中的局部变量啊啥的就无法在子bash中使用了(全局变量还可以)。下面的两种方法,就不会创建父子bash环境,而是直接在大bash环境中执行:

source xxx.sh
# or
. xxx.sh

5.1 变量

通常来说,shell中的系统变量都以大写字母来表示,例如:

$HOME  $HOSTNAME

可以使用 set 命令来查看bash环境中的局部变量和全局变量:

set

用户自己定义局部变量,规范如下:

# 等号两边不要有空格
my_var="hello, world"
# 修改值就直接修改
my_var=hello
# 使用变量这个值的时候,需要加一个$符号
echo $my_var
# 使用export,将局部变量提升为全局变量
export my_var

此时,在子bash中就可以看到这个my_var了。但是,子bash中的修改对其不起作用。

可以使用readonly将变量设置为常量,如下:

readonly a=hello
a=tyy        # 报错

使用unset将一个变量清除掉:

b=hello
unset b
echo $b        # 没有了

在bash中,默认所有的变量都是字符串类型,比如:

x=1+5
echo $x        # 结果为1+5,而不是6

5.2 shell脚本参数

在bash中,每当你输入一个命令:

ls

系统会在一个特定的路径去寻找这个命令,有就执行,没有就报错。这个路径就是$PATH:

echo $PATH
# 结果:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

所以,如果你将自己写的xxx.sh放到其中的某一个路径下:

cp xxx.sh /bin/        # 将xxx.sh复制到根目录下的bin中

那么就可以实现,直接输入xxx.sh,就可以当做是一个命令一样去执行:

xxx.sh
# 输出xxx.sh中的结果

使用$n可以获取脚本的参数:

echo "name of script: $0"        # 其中$0比较特殊,会输出脚本的名称xxx.sh
echo "the first parameter: $1"
echo "the second parameter: $2"

使用$#可以获取脚本的参数个数,常用于循环:

echo $#

使用$*, 和$@都可以获取脚本的所有参数,只是前者返回的是一个整体(比如“a b c”),而后者相当于返回一个参数的集合(比如[a, b, c])

echo $@
echo $*

5.3 数值运算

在bash中,想要使用数值运算,可以将运算写在$[]中,例如:

#!/bin/bash
a=10
s=$[a + 2]        # 也可以使用$(())
echo $s        # 得到结果12

5.4 判断、循环等逻辑

在bash中,如果想要执行条件判断,可以使用 test condition,或者 [ condition ](通常使用这个),例如:

#!/bin/bash
a=10
s=$[$a + 2]
test $s = 12        # 或者 [ $s = 12 ],中括号里边一定要各有一个空格
echo $?        # 使用$?可以返回上一条命令执行的结果,0为true

使用 -lt -gt -eq等等判断数值(less than, greater than, equal)

使用 -r -w -x 判断文件的权限

[ -r xxx.sh ]        # 判断xxx.sh是否有可读的权限?

使用 -e 判断文件是否存在(existence), -f 文件存在,且是一个常规文件, -d 文件存在而且是一个目录

#!/bin/bash
[ -e /bin/bash ]
echo $?                # 得到0,表示存在

下面这句话可以起到java中的三目运算符的效果:

a=20
[ $a -gt 15 ] && echo "$a > 15" || echo "$a < 15"
# 输出20 > 15

条件判断,格式如下:

#!/bin/bash
str="chr"
if [ $str = "chr" ]
then
        echo "welcome, chr"
fi

多条件判断,如下:

if [ a -gt 12 ] && [......] || [....]
then
        do something
fi

如果想要把条件都放在一个括号里边,可以使用 -a 或者 -o连接。(and和or)

#!/bin/bash
age=140
if [ $age -lt 18 ]
then
        echo "未成年"
elif [ $age -lt 35 ]
then 
        echo "青年人"
elif [ $age -lt 60 ]
then 
        echo "壮年人"
else
        echo "老年人"
fi

多分支,使用case:(注意两个分号哦)

#!/bin/bash
number=3
case $number in
1) 
        echo "one"
;;
2)
        echo "two"
;;
*)
        echo "else"
;;
esac

for 循环:

#!/bin/bash
for animal in dog cat elephant
do
  echo "there are ${animal}"
done

while 循环:

#!/bin/bash
while [ "${yn}" != "yes" ]
do
  read-p "infor" yn
done

6. Linux 磁盘分区、挂载

Linux 使用“载入”的方法将硬盘的一个分区与文件系统的一个目录联系起来。

Linux 硬盘分为 IDE 硬盘和 SCSI 硬盘,其中 SCSI 硬盘的标识为 “sdx~”,比如 sda1 表示基本盘(“a”)的第一个分区,sdb3 表示从属盘的第二个分区。

使用 lsblk 命令 查看所有设备的挂载情况

6.1 如何增加一块硬盘?

  1. 添加一块硬盘
  2. 分区
    1. 使用命令 fdisk 对硬盘分区。例如新添加了一块硬盘 sdb(通常放置在 /dev/ 下),可以使用 fdisk /dev/sdb 对其进行分区
  3. 格式化(在分区上创建文件系统)
    1. 使用命令 mkfs 对硬盘进行格式化。例如 mkfs -t ext4 /dev/sdb1
  4. 挂载
    1. 使用 mount 命令将分区挂载到目录上。例如将 sbd1 分区挂载到 /newDist 目录上:mount /dev/sdb1 /newDist
    2. 可以使用 umount 卸载:umount /dev/sdb1
    3. 使用指令挂载分区,重启之后挂载会失效
  5. 设置自动挂载
    1. 编辑 /etc/fstab 文件,可以将分区自动挂载到目录

使用 df -h 查看磁盘使用情况

使用 du -h 指令查询指定目录的磁盘占用情况

一些常用指令:

  • 统计 /data 下文件的数量

ll /data | grep '^-' | wc -l

  • 统计 /data 下目录的个数

ll /data | grep '^d' | wc -l

  • 使用 tree 指令以树状图查看目录情况

7. Linux账号管理

每一个登录的使用者都会取得两个ID:一个user id,一个 group id。

一个用户可以同时存在多个群组中,那当这个用户创建一个文件后,该文件的群组是?(是用户当前的有效群组,使用groups命令查看,第一个群组就是有效群组) 可以使用newgrp来切换有效群组(会切换进入一个新的shell)

Linux的账号信息多涉及到:

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /etc/gshadow

使用 useradd 命令添加用户,在centos7中,每一个新用户newUser在/home目录都会有一个主文件夹。(比如用户chr的主文件夹为/home/chr)

使用 usermod 来修改用户相关

使用 userdel 删除用户

使用 id 查询某人或自己的UID等相关信息

groupadd, groupmod, groupdel

7.1 ACL

在linux中使用ACL来实现颗粒度更细的权限分配(以前只能在所有者、群组以及其他人这三个范围内修改权限)

使用

  • getfacl
  • setfacl
[root@study ~] setfacl -m u:vbird1:rx acl_test1
[root@study ~] ll acl_test1
-rw-r-xr--+ 1 root root 0 Jul 21 17:33 acl_test1
# 权限部分多了个 + ,且与原本的权限 (644)
[root@study ~]# getfacl acl_test1
# file: acl_test1   &lt;==说明文档名而已!
# owner: root       &lt;==说明此文件的拥有者,亦即 ls -l 看到的第三使用者字段
# group: root       &lt;==此文件的所属群组,亦即 ls -l 看到的第四群组字段
user::rwx           # 使用者列表栏是空的,代表文件拥有者的权限
user:vbird1:r-x     # 针对 vbird1 的权限设置为 rx ,与拥有者并不同!
group::r--         # 针对文件群组的权限设置仅有 r
mask::r-x          # mask用来规范此文件的最大权限,别人的权限只能是mask这里的子集
other::r--         # 其他人拥有的权限啰!

8. Linux网络配置

网络地址转换 NAT:

虚拟机的 ip 可以和宿主机的虚拟网卡 vmnet8 相互 ping 通,NAT 服务将由虚拟机发送的数据包的源 ip 转换为宿主机的物理网络适配器的 ip 地址。

可以通过修改配置文件来指定 ip,编辑:

vim /etc/sysconfig/network-scripts/ifcfg-ens33

可以通过修改 /etc/hostname 指定主机名

通过修改配置文件,可以建立主机名与 ip 的映射,例如,在 linux 中,可以修改 /etc/hosts 文件,指定某个 ip 与主机名的映射,之后就可以通过主机名来访问对应的 ip。

9. Linux进程管理

Linux中的每一个进程都有一个 pid

使用 ps -aux 命令查看当前所有的进程

其中 STAT 表示进程当前的状态,s 表示 sleeping,r 表示 running,z 表示 僵尸进程(需要定时清除)

TTY 表示终端名称

使用 ps -ef 可以查看到进程的父进程 pid

使用 kill 指令杀死某一个进程,使用 killall 杀死进程及其子进程

kill 1324
killall gedit
kill -9 423    # 强制 kill

使用 pstree 以树状的形式查看进程

9.1 服务管理

服务本质就是运行在后台的进程,也称为守护进程 daemon(所以多以 d 结尾)。它们通常都会监听某一个端口,等待其他程序的请求。

使用 service 服务名 [start | stop | status ...] 来管理服务(现在很多服务都不再用 service 管理,而是使用 systemctl 管理)

服务的运行级别有七种,常用的级别是3和5:

  • 3:多用户状态(有网络),无界面,登录后植入控制台命令行模式
  • 5:登录后进入图形GUI模式

使用 systemctl get-default 和 systemctl set-default 设置服务的运行级别

使用 chkconfig 管理各个服务在不同运行级别的自启动情况(同样也是被 systemctl 代替)

9.2 systemctl

几乎所有服务都可以使用 systemctl 管理。具体语法是:

systemctl [start | stop | restart | status] 服务名

Systemctl 管理的服务可以在 /usr/lib/systemd/system 中查看(ubuntu 下是在 /etc/systemd/system)

使用 systemctl list-unit-files 查看服务的自启动状态

使用 systemctl enable/disable 服务名 开启/关闭服务开机自启

使用 systemctl is-enabled 服务名 查询某个服务是否是自启动的

9.3 防火墙

外部客户端想要访问linux中的服务时,会首先被防火墙检测。如果这个服务的端口是对外开放的,则可以访问。反之,访问不了。

telnet 192.168.200.130 111    # 访问这个ip下面的111端口

防火墙比较重要,应该打开。但是有的时候,某一个服务就需要被外部客户端访问,如何将这个服务对外开放呢?

firewall-cmd --permanent --add-port=端口号/协议  # 开放某一个端口
# 关闭、重新载入防火墙、查询端口是否开放等都有相应的指令,这里就不记录了

9.4 动态查看进程

使用 top 动态显示正在执行的进程

使用 P 按照CPU使用率排序,使用 M 以内存使用率排序

输入 u 可以指定查看目标用户相关的进程

输入 k 可以杀死目标进程

9.5 netstat 查看系统网络状况

键入 netstat -anp 可以查看当前系统有哪些服务处于监听状态,哪些服务处于连接状态等

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      1235/dnsmasq    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      5989/sshd       
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      3076/cupsd      
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      944/postgres    
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      2715/8          
tcp        0      0 192.168.163.129:22      192.168.163.1:51474     ESTABLISHED 2715/8          
tcp        0      0 192.168.163.129:22      192.168.163.1:51483     ESTABLISHED 2870/sshd: root@not

# 第八行表示,本地的22端口与外部ip为192.168.163.1,端口号为51483的服务进行了连接
# 协议为tcp协议(且本地的这个服务是sshd)

10. Linux软件包管理

Yum是一个shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,同时它可以自动处理依赖性关系,一次安装所有依赖的软件包。

使用 yum list 查询yum服务器是否有需要安装的软件

下载安装指定的yum包: yum install xxx

(在ubuntu系统中,与yum所对应的是 apt 指令)

当执行 apt install 命令时,linux从远程服务器下载软件包。主要涉及:

  • 软件源:软件源通常是官方或者第三方维护的软件仓库,这些服务器上存放着大量的软件包。
  • 源列表:Linux系统上有一个配置文件,里面记录了这些软件源服务器的地址。

所以,总结就是:软件包来源于远程的软件源服务器,但 apt 依靠本地的索引数据库来知道该下载什么。(软件被安装后,它的文件就分散到了系统的各个标准位置,而不是集中在一个文件夹里)

apt工具的相关指令有:

  • Sudo apt update: 当你执行 sudo apt update 时,apt 工具会连接到源列表中配置的服务器,下载最新的软件包索引列表到本地。(sudo apt update 几乎是必做的一个步骤)
  • Sudo apt upgrade: 升级所有已安装的软件包。
  • Sudo apt install <package name="">: 安装指定软件包。
  • Sudo apt remove <package name="">: 卸载指定软件包。
  • apt search <keyword>:在软件源中搜索包含关键字的软件包。

11. Linux日志管理

在Linux系统中,日志文件通常是存储在 /var/log 下面。其中日志文件较多,重要的日志文件主要有:

/var/log/syslog

  • 系统的“万能日志”,几乎所有服务和内核消息都会写入这里。
  • 用来查看大部分系统运行时信息和排错。

/var/log/auth.log

  • 记录认证相关日志,例如 SSH 登录、sudo 使用、用户登录和失败尝试。
  • 对安全审计非常关键。

/var/log/kern.log

  • 内核日志,记录内核产生的消息。
  • 当涉及驱动、硬件问题时非常重要。

/var/log/dmesg

  • 系统启动时内核检测硬件的输出信息。
  • 经常用来排查设备驱动加载和硬件识别问题。

/var/log/apt/history.log

  • 记录通过 APT(包管理器)进行的软件安装、升级和卸载操作。
  • 用于追踪系统软件变动历史。

/var/log/dpkg.log

  • 更底层的包管理日志,记录 dpkg 的具体操作。
  • 结合 apt/history.log 可以完整了解系统软件变动。

/var/log/Xorg.0.log

  • X Window(图形界面)的日志文件。
  • 图形界面启动失败时,常要查看这里。

日志管理服务 rsyslogd 负责将日志写入 /var/log/*.log 中去,它通过配置文件 /etc/rsyslog.conf 决定将不同的日志信息写入到不同的日志文件中。

  • 查询Linux中的rsyslogd服务是否启动 ps aux | grep "rsyslog"
  • 查询rsyslogd服务的自启动状态 systemctl list-unit-files | grep "rsyslog"

在ubuntu中,重要的配置文件在/etc/rsyslog.d/*.conf中,如下:

其中的格式是:

*.*      存放日志文件
第一个*代表日志类型,比如auth、corn、kern、mail等
第二个*代表日志级别,比如debug、info、emerg等

具体的日志信息如何看?

Aug 24 22:47:42 ubuntu sshd[4699]: Accepted password for root from 192.168.163.1 port 49709 ssh2
     日期        主机      服务       具体信息

(在现代Ubuntu中,很多系统服务的日志是先写到systemd-journald,再由它转发给rsyslog)

11.1 日志轮替

在Ubuntu中,日志轮替主要是依靠 logrotate 工具来完成,它的配置文件在 /etc/logrotate.conf,这里用于存放所有日志的轮替规则。同时, /etc/logrotate.d/ 下可以单独为某些日志存放轮替规则。

日志轮替怎么运行的?

/var/log/syslog 为例:

当前日志文件​​满了​,logrotate 会:

  • syslog 重命名为 syslog.1
  • 创建一个新的空白 syslog 文件(继续写入)
  • 旧的 syslog.1 可以再压缩成 syslog.1.gz
  • 更老的可能是 syslog.2.gz, syslog.3.gz ……

保留时间与数量

  • 通过配置指定,比如“保留 7 天日志”或者“保留 4 个历史文件”。

配置文件大概长这样:

# /etc/logrotate.d/rsyslog

/var/log/syslog
{
    rotate 7
    daily
    missingok
    notifempty
    delaycompress
    compress
    postrotate
        invoke-rc.d rsyslog rotate > /dev/null
    endscript
}
  • rotate 7 → 保留 7 个旧日志
  • daily → 每天轮替一次
  • missingok → 如果日志不存在,不报错
  • notifempty → 如果日志为空,就不轮替
  • compress → 用 gzip 压缩旧日志
  • delaycompress → 延迟一轮再压缩(避免刚写完的日志立刻压缩)
  • postrotate … endscript → 通知 rsyslog 重新打开日志文件
文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0