Linux 重要知识整理汇总

18 minute

文件

文件类型

  • d: directory
  • -: file
  • l: link
  • p: pipeline,管道文件
  • b: block,块设备文件
  • c: character,字符设备文件
  • s: socket,套接字文件

重要配置文件

  • bashrc
    • /etc/bashrc:针对所有用户,每开启一个 shell 都会执行一次
    • /etc/skel/.bashrc:针对所有用户,用于在新建一个用户时默认给用户配置的 bashrc
    • ~/.bashrc:只针对单个用户,每开启一个 shell 执行一次
  • profile
    • /etc/profile: 针对所有用户,首次登录执行一次
    • /etc/skel/bash_profile: 针对所有用户,用于在新建一个用户时默认给用户配置的 bash_profile
    • ~/.bash_profile: 只针对单个用户,首次登录执行一次

换行符相关

我们知道的:

  • 回车 CR:\r
  • 换行 LF:\n

换行在不同 OS 中有差异:

  • win/dos 的换行:\r\n
  • unix mac linux 的换行:\n

导致问题:

  • unix to win: 换行失败
  • win to unix: 多了\r -> \r\n -> ^M。

解决方法,全部统一为 LF 即可。如果 win 下已经为 CRLF,那么可以在 linux 下通过 dos2unix 操作,可以将某目录下的所有文件从 dos 格式转为 unix 格式:

1yum install dos2unix
2find . -name '*' | xargs dos2unix 

文件系统

cp 命令

常用 cp -au

-a,即 -dpR,-d 复制时保留链接,-p 保持权限不变,-R 递归复制,-u 表示在源文件有更新或者目标文件不存在时进行目标文件的复制。

文件权限

权限

添加用户

1[root@VM-0-11-centos ~]# useradd jzh
2
3[root@VM-0-11-centos /]# id jzh
4uid=1000(jzh) gid=1000(jzh) groups=1000(jzh)
5
6[root@VM-0-11-centos /]# grep jzh /etc/passwd /etc/shadow /etc/group
7/etc/passwd:jzh:x:1000:1000::/home/jzh:/bin/bash
8/etc/shadow:jzh:!!:18980:0:99999:7:::
9/etc/group:jzh:x:1000:

x 指代密码,对应到 shadow 中,未设定即为 “!!”。

设置密码

在进行 useradd 后密码还未设定。

1[root@VM-0-11-centos /]# passwd jzh
2Changing password for user jzh.
3New password:
4BAD PASSWORD: The password is shorter than 8 characters
5Retype new password:
6passwd: all authentication tokens updated successfully.

若要让用户第一次能通过默认密码登录得上,并提示用户必须修改密码:

1[root@VM-0-11-centos /]# useradd vbird
2[root@VM-0-11-centos /]# echo "123456" | passwd --stdin vbird
3Changing password for user vbird.
4passwd: all authentication tokens updated successfully.
5[root@VM-0-11-centos /]# chage -d 0 vbird # -d接最近一次需要修改密码的时间

使用 vbird 用户登录:

 1vbird@101.34.217.138's password:
 2You are required to change your password immediately (root enforced)
 3Last login: Mon Dec 20 00:04:51 2021 from 113.200.174.13
 4WARNING: Your password has expired.
 5You must change your password now and login again!
 6# 提示需要修改密码
 7
 8# 修改密码
 9Changing password for user vbird.
10Changing password for vbird.
11(current) UNIX password:
12New password:
13Retype new password:
14passwd: all authentication tokens updated successfully.

添加群组与加入群组

1[root@VM-0-11-centos ~]# groupadd testgroup
2[root@VM-0-11-centos ~]# gpasswd testgroup
3Changing the password for group testgroup
4New Password:
5Re-enter new password:
6[root@VM-0-11-centos ~]# gpasswd -A vbird testgroup
7[root@VM-0-11-centos ~]# grep testgroup /etc/group /etc/gshadow
8/etc/group:testgroup:x:1002:
9/etc/gshadow:testgroup:$1$9v24LYZE$V/yYwmmoaKNpe9.zCPK3U.:vbird:

可见 vbird 已经加入该群组

通过 ACL 设置专有权限

团队开发时,由于原有权限无法满足需求,通常需要对某些成员设置专有权限:

  1. -m 设置后续 acl 参数给文件使用
  2. -x 删除后续 acl 参数
  3. -R 递归设置
 1[root@VM-0-11-centos tmp]# touch acl
 2# 针对用户
 3[root@VM-0-11-centos tmp]# setfacl -m u:jzh:rx acl # 为jzh用户设置专有权限
 4
 5# 针对群组
 6[root@VM-0-11-centos tmp]# setfacl -m g:testgroup:rwx acl
 7[root@VM-0-11-centos tmp]# getfacl acl
 8# file: acl
 9# owner: root
10# group: root
11user::rw-
12user:jzh:r-x
13group::r--
14group:testgroup:rwx
15mask::rwx
16other::r--

登录

1su - # 使用root登录
2su - jzh # 使用jzh登录

服务

systemctl

  1. 立即启动一个服务:systemctl start my.service
  2. 立即停止一个服务:systemctl stop my.service
  3. 重启一个服务:systemctl restart my.service
  4. 重新加载一个服务的配置文件:systemctl reload my.service
  5. 重载所有修改过的配置文件:systemctl daemon-reload
  6. 开启自启动服务:systemctl enable my.service
  7. 取消开启自启动:systemctl disable my.service
  8. 查看是否已经自启动:systemctl is-enabled my.service
  9. 查看服务运行状态:systemctl status my.service
  10. 查看所有服务:systemctl --type service

service & chkconfig

  1. 启动服务:service my.service start
  2. 终止服务:service my.service stop
  3. 重启服务:service my.service restart
  4. 查看服务运行状态:service my.service status
  5. 开启或取消开机自启动:chkconfig my.service on/off
  6. 查看开机自启动列表:chkconfig --list

Unit 配置文件解释

 1- Unit
 2   - Description,服务的描述
 3   - Requires,定义此unit需在哪个daemon启动后才能够启动
 4- Service
 5   - Type,定义启动时的进程行为。它有以下几种值。
 6   - Type=simple,默认值,执行ExecStart指定的命令,启动主进程
 7   - Type=forking,以 fork 方式从父进程创建子进程,创建后父进程会立即退出
 8   - Type=oneshot,一次性进程,Systemd 会等当前服务退出,再继续往下执行
 9   - Type=dbus,当前服务通过D-Bus启动
10   - Type=notify,当前服务启动完毕,会通知Systemd,再继续往下执行
11   - Type=idle,若有其他任务执行完毕,当前服务才会运行
12   - ExecStart,启动当前服务的命令
13   - ExecStartPre,启动当前服务之前执行的命令
14   - ExecStartPost,启动当前服务之后执行的命令
15   - ExecReload,重启当前服务时执行的命令
16   - ExecStop,停止当前服务时执行的命令
17   - ExecStopPost,停止当其服务之后执行的命令
18   - RestartSec,自动重启当前服务间隔的秒数
19   - Restart,定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-successon-failureon-abnormalon-aborton-watchdog
20   - TimeoutSec,定义 Systemd 停止当前服务之前等待的秒数
21   - Environment,指定环境变量
22- Install
23   - WantedBy,值是一个或多个Target,当前Unit激活(enable)时,符号链接会放入/etc/systemd/system目录下面以Target名+.wants后缀构成的子目录中
24   - RequiredBy,它的值是一个或多个Target,当前Unit激活(enable)时,符号链接会放入/etc/systemd/system目录下面以Target名+.required后缀构成的子目录中
25   - Alias,当前Unit可用于启动的别名
26   - Also,当前Unit激活(enable)时,会被同时激活的其他Unit

自定义服务启动

服务的管理通过 systemd 进行,systemd 大部分配置文件位于 /usr/lib/systemd/system/ 内,一般不在这进行修改。

修改的位置位于 /etc/systemd/system 内,在这里可以加入自己的服务。

新建 service 文件

 1vim /etc/systemd/system/test.service
 2
 3# test.service
 4[Unit]
 5Description=service test
 6
 7[Service]
 8Type=simple
 9ExecStart=/bin/bash -c " ~/test-service.sh"
10
11[Install]
12WantedBy=multi-user.target

开启服务并观察

 1[root@VM-0-11-centos ~]# systemctl daemon-reload
 2[root@VM-0-11-centos ~]# systemctl start test.service
 3[root@VM-0-11-centos ~]# systemctl status test.service
 4● test.service - service test
 5   Loaded: loaded (/etc/systemd/system/test.service; disabled; vendor preset: disabled)
 6   Active: active (running) since Wed 2022-04-13 00:04:24 CST; 4s ago
 7 Main PID: 15428 (bash)
 8   CGroup: /system.slice/test.service
 9           ├─15428 /bin/bash -c  ~/test-service.sh | at now;
10           ├─15429 /bin/bash -c  ~/test-service.sh | at now;
11           ├─15430 at now
12           └─15432 sleep 30s
13
14Apr 13 00:04:24 VM-0-11-centos systemd[1]: Started service test.

查看 Unit 启动日志

Systemd 统一管理了所有 Unit 的启动日志,因此只需要使用 journalctl 命令就可以查看到服务的日志。

  1. 显示尾部指定行数的日志:journalctl -n 20
  2. 查看指定服务的日志:journalctl /usr/lib/systemd/systemd
  3. 查看指定进程的日志:journalctl _PID=1
  4. 查看某个 Unit 的日志:journalctl -u nginx.service

通过 PM2 管理应用服务

 1# 启动名为 xxx 的 python 应用
 2pm2 start api.py --name xxx --interpreter ~/Codes/scripts/.venv/bin/python3
 3# 重启 xxx 应用
 4pm2 restart xxx
 5# 列出 pm2 应用
 6pm2 l
 7# 监视 pm2 所有应用
 8pm2 dash
 9# 查看应用日志
10pm2 logs xxx
11# 保存 pm2 应用列表快照
12pm2 save
13# 从快照恢复 pm2 应用列表
14pm2 resurrect

文本

使用 grep 抓取期望的结果

 1grep [-acinv] [--color=auto] '搜寻字串' filename
 2
 3# 选项与参数:
 4
 5-a :将 binary 文件以 text 文件的方式搜寻数据
 6
 7-c :计算找到 '搜寻字串' 的次数
 8
 9-i :忽略大小写的不同,所以大小写视为相同
10
11-n :顺便输出行号
12
13-v :反向选择,亦即显示出没有 '搜寻字串' 内容的那一行
14
15--color=auto :可以将找到的关键字部分加上颜色的显示喔

在过去登录主机的人中截取登录信息含 root 的行信息:

1last | grep root

使用 awk 命令操作文本

1awk '{[pattern] action}' {filenames}
2awk -F  #-F指定所操作文件中的目标分割字符
3awk -v  # 设置变量
4awk -k {awk_script} {file} # 使用 awk 脚本

以 tab 隔开打印前五行中每行的第一和第三个字符:

1# 注意必须是内双引号外单引号的形式
2last -n 5 | awk '{print $1 "\t" $3}'

使用 “,” 分隔字符:

1awk -F, '{print $1 " - " $2}' log.txt

设置变量 k 等于 1:

1awk -vk=1 '{print $1, $1+k}' log.txt

使用 my.awk 处理 log.txt

1awk -k my.awk log.txt

fzf

匹配完整单词 “linux” 而不是 “linux” 中的字母: 'linux

使用 sed 命令操作文本

 1a: add
 2
 3c: commute
 4
 5d: delete
 6
 7i: insert
 8
 9p: print
10
11s: s/old/new/g

打印删除了第二到第五行的文本:

1nl /etc/passwd | sed '2,5d'
2# 注:nl 可以额外输出行号
  • ‘2,$d’ 匹配删除了第 2 到最后一行的文本
  • ‘/root/d’ 匹配删除了含 root 的行的文本

使用 cut 处理结果

对以 : 隔开的结果,输出第三个到第五个:

1echo $PATH | cut -d ':' -f 3,5

使用 sort 和 uniq 处理结果

使用 last 将帐号列出,仅取出帐号栏,进行排序后仅取出一位

1last | cut -d ' ' -f 1 | sort | uniq

根据进程号进行对 ps -ef 列出的前 10 个进程进行排序:

1ps -ef | head -n  10 | sort -k 2

-k 指定了第二列的数据(进程号)作为排序的元素。

进程

查看进程

ps -ef

  • -e : all processes (-A)
  • -f : full-format, including command lines
1[root@VM-0-11-centos ~]# ps -ef | head -n 1
2UID PID PPID C STIME TTY TIME CMD

解释如下:

  • PPID 父进程ID
  • C 占用CPU百分比
  • STIME 就是"start time"
  • TTY 进程在哪个终端显示
  • CMD 命令的名称和参数

ps aux

  • a: all with tty, including other users (和-a是不同的)
  • u: user-oriented format
  • x: processes without controlling ttys
1[root@VM-0-11-centos ~]# ps -aux | head -n 1
2USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

解释如下:

  • %MEM 占用内存百分比
  • VSZ 该进程使用的虚拟內存量(KB)
  • RSS 该进程占用的固定內存量(KB)(驻留中页的数量)
  • STAT 进程状态

STAT状态位常见的状态字符有:

1D      //无法中断的休眠状态(通常 IO 的进程); 
2R      //正在运行可中在队列中可过行的; 
3S      //处于休眠状态; 
4T      //停止或被追踪; 
5Z      //僵尸进程; 
6s      //进程的领导者(在它之下有子进程); 
7l      //多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads); 
8+      //位于后台的进程组;

终止进程

kill

kill 用于想某个进程发送信号。列出所有序号代表的信号含义:

1[root@VM-0-11-centos ~]# kill -l
2 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL ......

最常用的信号是:

  • 1 (SIGHUP):重新加载进程。
  • 9 (SIGKILL):杀死一个进程。
  • 15 (SIGTERM):正常停止一个进程。

默认不带信号序号的 kill 就是 SIGTERM,SIGTERM 可以被阻塞、处理和忽略,因此有的进程可能无法按预期的结束。

根据某个名称获取 PID 并 KILL:

1kill -9 `ps -ef | grep ins | grep -v color | awk '{print $2}'`

killall

无需 PID,通过指定的名称进行对应进程的 kill 操作。

1killall [-iIe] -signal 指令名称
2
3-i: interactive, 互动式 kill

依次询问每个 htppd 相关程序是否需要被终止:

1killall -i -9 httpd

背景工作切换

  1. 观察当前工作状态:jobs,jobs -l 可同时列出PID。
  2. 将背景工作拿到前景来处理:fg %jobnumber
  3. 让工作运行在背景:bg &jobnumber

当按下 ctrl-z 将 vim 工作放到背景后,默认情况下,vim 工作将处于 “Stpped” 状态,使用 bg 开始运行。

plus: & 将工作放到背景“执行”。

离线管理进程

1nohup {cmd} &

不打印日志:

1nohup {cmd} >/dev/null 2>&1 &

/dev/null 类似于回收站,只是无法像 window 的回收站一样恢复。

>/dev/null,就是把标准输出(1)写到 /dev/null

对于 2>&1

我们知道,1 代表标准输出,而 2 代表标准错误输出,而 0 代表标准输入,这里就是将标准错误输出重定向到标准输出,这样也让标准错误输出写到了 /dev/null