0%

Linux 快速上手

Linux头图

Linux 是一种自由和开放源码的类 UNIX 操作系统。该操作系统的内核由 Linus Torvalds 在 1991 年 10 月首次发布,在加上用户空间的应用程序之后,成为 Linux 操作系统。


Linux概述

Linux(/ˈlɪnəks/)是一种自由和开放源码的类 UNIX 操作系统。该操作系统的内核由 Linus Torvalds 在 1991 年 10 月首次发布,在加上用户空间的应用程序之后,成为 Linux 操作系统。

发展历史

与UNIX的渊源

UNIX 是美国 AT&T 公司贝尔实验室于 1969 年完成的操作系统,在 1971 年首次发布。1973 年被 C 语言(内核和 I/O 例外)重新编写,具有更佳的兼容性,能更容易地移植到不同的计算机平台。

1983 年,Richard Matthew Stallman 创立 GNU 计划,目标是发展一个完全自由的类 Unix 操作系统。1990 年代早期,GNU 开始大量地产生或收集各种系统所必备的组件,像是库、编译器、调试工具、文本编辑器,以及一个 Unix 的用户界面,但是像一些底层环境,如硬件驱动、守护进程、系统内核仍然不完整。GNU 计划是在 Mach 微内核的架构之上开发系统内核,也就是所谓的 GNU Hurd,但是这个基于 Mach 的设计异常复杂,发展进度则相对缓慢。

创立

1991 年,Linus Torvalds 在赫尔辛基大学上学时,对操作系统很好奇。MINIX 是一个为在计算机科学用作教学而设计的类 Unix 操作系统,Linus Torvalds 对 MINIX 只允许在教育上使用很不满,于是他便开始写他自己的操作系统,这就是后来的 Linux 内核。

Linus Torvalds 开始在 MINIX 上开发 Linux 内核,为 MINIX 写的软件也可以在 Linux 内核上使用,后来使用 GNU 软件代替 MINIX 的软件。之后许多开发者致力融合 GNU 元素到 Linux 中,做出一个有完整功能的、自由的操作系统。

命名

Hello! This is Linus Torvalds,
and I pronounce Linux as “Linux”

——Linus Torvalds

Linux 的第一个版本在 1991 年 9 月被大学 FTP 服务器管理员发布在因特网上。最初 Linus 称这个内核的名称为“Freax”,意为自由(free)和奇异(freak),并附上“x”这个字母,以配合所谓的类 Unix 的系统。但是FTP服务器管理员嫌“Freax”不好听,把内核的称呼改成“Linux”。

Linux 的标志和吉祥物是一只名字叫做 Tux 的企鹅,标志的由来是因为 Linus 在澳洲时曾被一只动物园里的企鹅咬了一口,便选择企鹅作为 Linux 的标志。

系统架构

基于 Linux 的系统是一个模块化的类 Unix 操作系统。Linux 操作系统的大部分设计思想来源于 Unix 操作系统所创建的基本设计思想。Linux 系统使用宏内核,由 Linux 内核负责处理进程控制、网络,以及外围设备和文件系统的访问。在系统运行的时候,设备驱动程序要么与内核直接集成,要么以加载模块形式添加。

InSide The Linux Kernel

[漫画赏析:Linux 内核到底长啥样](https://linux.cn/article-8290-1.html)
## 组成 ##

Linux组成

Linux组成
- 内核:是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序。 - 操作系统内核(Kernel):操作系统内核是指大多数操作系统的核心部分。它由操作系统中用于管理存储器、文件、外设和系统资源的那些部分组成。操作系统内核通常运行进程,并提供进程间的通信。 - SHELL:是系统的用户界面,提供了用户和内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行,是一个命令解释器。但 Shell 不仅是命令解释器,也是高级编程语言。 - 文件系统:文件系统是文件存放在磁盘等存储设备上的组织方法,Linux 支持多种文件系统,如 ext3、ext2、NFS、SMB、iso9660 等。 - 应用程序:Linux 操作系统上的应用程序,例如 X-Window、Open Office。

目录结构

Linux目录结构

Linux目录结构
- `/`:根目录。位于 Linux 文件系统目录结构的顶层,一般根目录下只存放目录,不存放文件。`/etc`、`/bin`、`/dev`、`/lib`、`/sbin` 应该和根目录放置在一个分区中。 - `/bin`, `/usr/bin`:命令文件目录,也称为二进制目录。包含了供系统管理员及普通用户使用的重要的 Linux 命令和二进制(可执行)文件,包含 shell 解释器等。 - `/boot`:该目录中存放系统的内核文件和引导装载程序文件,`/boot/vmlinuz` 为 Linux 的内核文件,`/boot/gurb` 为系统引导管理器。 - `/dev`:设备文件目录。存放 Linux 系统下的设备文件,访问该目录下某个文件,相当于访问某个设备(终端、磁盘驱动器、光驱及网卡等)。该目录下的文件由系统管理员来使用,普通用户对大部分文件有只读权限。 - `/etc`:系统配置文件存放的目录。该目录存放系统的大部分配置文件和子目录,不建议在此目录下存放可执行文件。该目录下的文件由系统管理员来使用,普通用户对大部分文件有只读权限。 - `/home`:默认存放系统的用户主目录。除了 root 用户的主目录为 `/root` 外,新增用户账号时,用户的主目录都存放在此目录下,如 `/home/user`。因为在 70 年代流行的终端机上 `home` 与 `~` 为同一个按键,因此可以用 `~` 表示 `/home/user`。 - `/lib`, `/usr/lib`, `/usr/local/lib`:系统使用的函数库的目录。程序在执行过程中,调用一些额外的参数时需要函数库的协助,该目录下存放了各种编程语言库。`/lib` 目录存放了所有重要的库文件,`/usr/lib` 目录存放其他的库文件。 - `/opt`:给主机额外安装软件所摆放的目录。如:Cloudera Manager 安装后位于 `/opt/cloudera`。 - `/proc`:文件系统 procfs(program file system)挂载到此目录,每个正在运行的进程对应于 `/proc` 下的一个目录,目录名就是进程的 PID。procfs 包含的是一个伪文件系统(启动时动态生成的文件系统),因此此目录不占用磁盘空间,数据都在内存中,如系统核心,外部设备,网络状态等。 - `/root`:系统管理员 root 用户的主目录。 - `/sbin`, `/usr/sbin`, `/usr/local/sbin`:放置系统管理员使用的可执行命令(如 `fdisk`、`shutdown`、`mount`)。与 `/bin` 不同的是,这几个目录是给系统管理员 root 使用的命令,一般用户只能查看而不能设置和使用。 - `/tmp`:存放临时文件目录。一些命令和应用程序会用的到这个目录,该目录下的所有文件会被定时删除。 - `/usr`:存放应用程序的目录。`/usr/bin` 存放应用程序,`/usr/share` 存放共享数据,`/usr/lib` 存放不能直接运行但是许多程序运行所必需的一些函数库文件,`/usr/local` 存放软件升级包,`/usr/share/doc` 存放系统说明文件,`/usr/share/man` 存放帮助命令的程序说明文件,使用 `man ls` 时会查询 `/usr/share/man/man1/ls.1.gz` 的内容。 - `/var`:放置系统执行过程中经常变化的文件。`/var/log`存放日志文件,`/var/log/messages`存放所有的登录文件,`/var/spool/mail` 存放邮件,`/var/run` 存放运行时变量数据。

Linux版本

Linux 的版本分为两种:内核版本和发行版本。内核主要是指操作系统或者相应软件中最核心的功能框架部分,它是实现该软件所有功能的基础。

  • 内核版本:只包含最核心的功能框架部分,是操作系统的核心,由 Linus 领导的内核小组开发维护。
  • 发行版本:包括了内核与一些其他与文件相关的操作,用户管理系统,和软件包管理器等一系列软件,由一些组织、团体、公司或者个人制作,让用户可以简便地安装和使用 Linux。

常见的发行版本:

  • Red Hat:目前全球最流行的商用 Linux,功能全面、稳定。
  • Centos:基于 Red Hat 发行版基础之上,重新编译发布的免费版本。
  • Ubuntu:以桌面应用为主的 Linux 发行版。

查看版本:

1
2
3
4
5
6
7
8
9
$ cat /proc/version
Linux version 3.10.0-957.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018

$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.6.1810 (Core)
Release: 7.6.1810
Codename: Core

安装Linux

配置虚拟机

在 Windows 系统下的 VMWare 虚拟机软件中安装 Linux 系统,使用的发行版本为 CentOS 6.10。打开虚拟网络编辑器,选择 VMnet8,选择 NAT 模式,配置子网 IP,点击 “NAT设置”,配置网关 IP。

虚拟网络编辑器

在 CentOS 的安装过程中,注意对主机名的修改,并点击“配置网络”,编辑 System eht0 这个网络,勾选“自动连接”,设置IPv4 为静态 IP,添加一条记录,IP 地址与虚拟网络编辑器中的子网 IP 处于同一个网段,子网掩码和网关与虚拟网络编辑器中的配置保持一致。安装版本选择 Basic Server。

配置防火墙

iptables

适用于 CentOS 6.x 等安装了 iptables 命令的 Linux 系统。

Linux iptables 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 用法
iptables [-t 表名] <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作

# 选项说明
-t 表名:指定要操纵的表,默认为filter表
-A:向规则链中添加规则,会被添加到尾部
-I:向规则链中插入规则,需要指定插入到哪一行
-D:从规则链中删除规则,需要指定规则内容或行数
-R:修改规则链中的规则
-L:显示规则链中已有的规则
-n:显示规则链时直接显示 IP
-F:清除规则链中已有的规则
-X:删除所有使用者自定义的 chain(其是 tables)
-Z:清空规则链中的数据包计算器和字节计数器
-N:创建新的用户自定义规则链
-P:定义规则链中的默认目标
-h:显示帮助信息
-p:指定要匹配的数据包协议类型
-m:指定 iptables 的插件模块,常见的模块有:
state:状态模块
mac:处理网卡硬件地址(hardware address)的模块
--state:指定数据包的状态,常见的状态有:
INVALID:无效的数据包状态
ESTABLISHED:已经连接成功的数据包状态
NEW:想要新建立连接的数据包状态
RELATED:这个最常用,它表示该数据包与我们主机发送出去的数据包有关
-s:指定要匹配的数据包源ip地址
-j <目标>:指定要跳转的目标
-i <网络接口>:指定数据包进入本机的网络接口
-o <网络接口>:指定数据包要离开本机所使用的网络接口

# 表名
raw:高级功能,如:网址过滤
mangle:数据包修改(QOS),用于实现服务质量
net:地址转换,用于网关路由器
filter:包过滤,用于防火墙规则

# 规则名
INPUT:处理输入数据包
OUTPUT:处理输出数据包
PORWARD:处理转发数据包
PREROUTING:用于目标地址转换(DNAT)
POSTOUTING:用于源地址转换(SNAT)

# 动作
ACCEPT:接收数据包
DROP:丢弃数据包
REDIRECT:重定向、映射、透明代理
SNAT:源地址转换
DNAT:目标地址转换
MASQUERADE:IP伪装(NAT),用于ADSL
LOG:日志记录

开放指定的端口:

1
$ iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

也可以直接修改规则文件,添加要开放的端口:

1
2
3
$ vim /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

修改防火墙规则

设置完成后,需要重启防火墙:

1
service iptables restart

关闭防火墙服务:

1
service iptables stop

查看防火墙状态:

1
service iptables status

禁止防火墙开机自启动:

1
chkconfig iptables off

查看自启动状态:

1
2
3
4
5
6
7
8
9
10
11
$ chkconfig iptables --list
iptables 0:关闭 1:关闭 2:关闭 3:关闭 4:关闭 5:关闭 6:关闭

# 含义
# 等级0表示:表示关机
# 等级1表示:单用户模式
# 等级2表示:无网络连接的多用户命令行模式
# 等级3表示:有网络连接的多用户命令行模式
# 等级4表示:不可用
# 等级5表示:带图形界面的多用户模式
# 等级6表示:重新启动

firewalld

CentOS 7 默认使用 firewalld 作为防火墙,带来最大的好处有两个:支持动态更新,不用重启服务;加入了域(zone)的概念,使用起来更人性化。firewalld 和 iptables 的作用都是用于维护规则,自身并不具备防火墙的功能,根据规则干活的是内核的 netfilter。

firewall-cmd 是 firewalld 的字符界面管理工具,常用操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 查看状态
$ firewall-cmd --state
running

# 查看所有域
$ firewall-cmd --list-all-zones

# 查看当前的活动域,默认为public
$ firewall-cmd --get-active-zones
public
interfaces: ens3

# 添加80端口到public域,并永久生效
$ firewall-cmd --zone=public --add-port=80/tcp --permanent

# 查看public域所有打开的端口
$ firewall-cmd --zone=public --list-ports
80/tcp

# 更新防火墙规则,不会中断连接
firewall-cmd --reload

# 更新防火墙规则,会中断连接
firewall-cmd --complete-reload

克隆虚拟机

克隆虚拟机

如果需要多台虚拟机组建集群,可以选择“克隆虚拟机”。

克隆虚拟机后该如何做?

  1. 在启动克隆出来的虚拟机之前,生成新的MAC地址,并记录下来。

修改MAC地址

  1. 修改主机名称:
1
2
3
4
5
6
7
8
9
10
# CentOS6修改
$ vim /etc/sysconfig/network
NETWORKING=yes
- HOSTNAME=node01
+ HOSTNAME=node02

# CentOS7修改
$ vim /etc/hostname
- node01
+ node02
  1. 修改网卡网络配置中的 MAC 地址和 IP 地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
UUID=eea6b2f7-66d0-4254-92be-2b476ee1a454
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=none
- HWADDR=00:50:56:37:F9:FF
+ HWADDR=00:50:56:34:79:4D
- IPADDR=192.168.153.100
- IPADDR=192.168.153.101
PREFIX=24
GATEWAY=192.168.153.2
DNS1=8.8.8.8
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"
  1. 修改 udev (设备管理器)的配置文件 70-persistent-net.rules ,只保留 eth0 的记录,更新记录的 MAC 地址:
/etc/udev/rules.d/70-persistent-net.rules
1
2
# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:56:34:79:4D", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
  1. 重启 reboot

  2. 查看网络配置,能够显示这块网卡的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:56:34:79:4D
inet addr:192.168.153.101 Bcast:192.168.153.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea8:42d0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:638 errors:0 dropped:0 overruns:0 frame:0
TX packets:543 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:61442 (60.0 KiB) TX bytes:61249 (59.8 KiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

免密登录

  1. 配置三台虚拟机的 hosts
1
2
3
4
$ vim /etc/hosts
192.168.153.100 node01
192.168.153.101 node02
192.168.153.102 node03
  1. 在三台虚拟机上执行 ssh-keygen,使用默认选项,会在 /root/.ssh 目录下生成公钥 id_rsa.pub 和私钥 id_rsa
1
$ ssh-keygen -t rsa
  1. 将 node02 和 node03 上执行 ssh-copy-id 命令将公钥拷贝到 node01 上,会在 node01 的 /root/.ssh 目录下生成 authorized_keys 文件进行记录:
/root/.ssh/
1
$ ssh-copy-id node01
  1. 将 node01 的公钥也添加进 authorized_keys
/root/.ssh/
1
$ cat id_rsa.pub >> authorized_keys
  1. 将 node01 上的 authorized_keys 分发到 node02 和 node03:
/root/.ssh/
1
2
$ scp authorized_keys node02:$PWD
$ scp authorized_keys node03:$PWD
  1. 测试免密是否打通:
1
2
3
$ ssh node01
$ ssh node02
$ ssh node03

Linux基础命令

管理整个计算机硬件的是操作系统的核心 (Kernel),这个核心是需要被保护的,所以我们一般只能通过 Shell 来指挥核心完成各种工作。Shell 也有很多版本,Linux 默认使用的是 Bash(Bourne Again Shell) 。查看下 /etc/shells这个文件,里面便是我们可以使用的 Shell。

Linux 命令,其实就是 Shell 命令,是使用 Linux 的关键。

Bash功能

Bash 是 GNU 计划中重要的工具软件之一,提供了以下功能:

命令记录

通过按上、下键就可以找到前一个、后一个输入的命令,默认的命令记录可以到达 1000 个。注销登录后,历史命令还会记录到 ~/.bash_history

1
2
3
4
$ tail -3 ~/.bash_history 
vim ifTest.sh
crontab -e
crontab -l

命令与文件补全

使用Tab键可以自动补全命令或文件,在 bash 环境中使用 Tab 可以让你少打很多字,并且确保输入的内容是正确的。

Tab 的功能还根据使用的时机而有所不同:

  • 接在一串命令的第一个单词中,则为命令补全
  • 接在一串命令的第一个单词的后面,则为文件补齐

连按两次 Tab 键还能够列出所有符合条件的可运行命令和文件。

配置命令的别名

输入 alias 就可以知道目前配置了别名的命令有哪些了。别名的配置在 /root/.bashrc,如果只对单次登录临时启用某个别名,可以直接输入别名配置命令:

1
2
3
4
5
6
7
8
9
$ alias lm='ls -al'
$ lm
总用量 20
drwxr-xr-x. 2 root root 62 8月 6 10:55 .
dr-xr-x---. 8 root root 4096 8月 6 10:55 ..
-rwxr-xr-x. 1 root root 29 8月 5 14:28 a.sh
-rwxr-xr-x. 1 root root 20 8月 5 14:29 b.sh
-rwxr-xr-x. 1 root root 108 8月 4 15:32 ifTest.sh
-rwxr-xr-x. 1 root root 61 8月 6 10:55 loop.sh

前后台与工作控制

启动的脚本默认在前台执行,也可以使用 command & 将其放在后台去运行。工作控制的用途则更广,可以让我们随时将前台运行的命令丢到后台中运行,而不怕不小心使用了 Ctrl + C停掉该程序。

  • command:在前台执行命令;
  • command &:将进程放在后台执行;
  • Ctrl + C:停止前台进程;
  • Ctrl + Z:暂停当前进程,并放入后台(但不执行);
  • jobs:查看当前后台任务;
  • bg job_spec:将任务转为后台执行;
  • fg job_spec:将任务转为前台执行;
  • kill %job_spec:结束任务进程。
  • nohup:忽略所有发送给子进程的挂断(SIGHUP)信号。关闭终端时,系统会发送 SIGHUP 信号到后台进程,使用 nohup 可以在关闭终端后仍保持后台进程的执行。

示例:

  1. 编写脚本,循环输出数字,持续 100 秒:
loop.sh
1
2
3
4
5
#!/bin/bash
for ((i = 1; i <= 100; i++)); do
echo $i
sleep 1
done
  1. 授予脚本执行权限,执行脚本,并在执行过程中切换前后台:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 授予执行权限
$ chmod +x loop.sh

# 前台执行脚本
# 执行过程中用 Ctrl + Z 暂停脚本,将其放入后台(
$ ./loop.sh
1
2
^Z
[1]+ 已停止 ./loop.sh

# 查看后台任务,中括号中的 1 为该任务的编号(又叫任务声明,job_specification)
$ jobs
[1]+ 已停止 ./loop.sh

# 后台执行任务
$ bg 1
[1]+ ./loop.sh &
3
4

# 前台执行任务(标准输出内容并不影响输入命令的执行)
$ fg 1
./loop.sh
5
6

# 结束后台任务
$ kill %1
  1. 后台执行脚本时常用的完整命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
# 不挂断,执行脚本,保存标准输出和错误输出信息到指定文件,后台执行
$ nohup ./loop.sh > loop.log 2>&1 &
[1] 10797

# 查看后台任务
$ jobs
[1]+ 运行中 nohup ./loop.sh > loop.log 2>&1 &

# 查看指定文件实时内容
$ tail -f loop.log
29
30
31

程序化脚本

将平时管理系统常需要下达的连续命令写成一个文件,该文件并且可以透过对谈交互式的方式来进行主机的侦测工作,也可以藉由 shell 提供的环境变量及相关命令来进行设计。

通配符

bash 还支持通配符来帮助用户查询与下达命令:

1
2
$ ls /usr/bin/ba*
/usr/bin/base64 /usr/bin/basename /usr/bin/bash /usr/bin/bashbug /usr/bin/bashbug-64

内嵌命令

输入man bash可以查看 bash 的说明文档,在里面可以看到cd命令,说明cd也是bash的内建命令。通过 type command 可以查看一个命令是外部命令还是 bash 内嵌命令:

1
2
3
4
5
# 查看 cd/man/ll 命令
$ type cd man ll
cd 是 shell 内嵌
man 是 /usr/bin/man
ll 是 `ls -l --color=auto' 的别名

基本格式

命令名称 [命令参数] [命令对象]

  • 命令参数:可选,有长格式(–help)和短格式(-h)
  • 命令对象:可选,指定命令作用的目标,如文件、目录、URL

注意:命令严格区分大小写。

查看目录

查看当前工作目录

pwd:显示当前的工作目录

/root
1
2
$ pwd
/root

查看目录下的内容

ls [选项]... [文件]...:列出指定目录下的文件和目录的信息,默认为当前目录,根据字母排序

  • -a--all:查看所有内容,包括以 . 开头的隐藏文件
  • -h--human-readable:与 -l 一起,以易于阅读的格式输出文件大小
  • -l:使用较长格式列出信息,别名为 ll
  • -r--reverse:以相反的顺序列出目录下的内容
  • -R--recursive:递归显示子目录
  • -S:根据文件大小排序
  • -t:根据修改时间排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 查看/usr的内容
$ ls
bin dfs etc games include lib lib64 libexec local sbin share src tmp

# 查看/usr的所有内容(包含隐藏)
$ ls -a
. .. bin dfs etc games include lib lib64 libexec local sbin share src tmp

# 查看 /usr 的详细内容,分为七列
# 第一列共 10 位,每位的含义详见十位文件权限
# 第二列表示链接数量,表示链接到该文件 inode 号码的文件数量
# 第三列表示拥有者
# 第四列表示所属群组
# 第五列表示文档容量大小,单位字节
# 第六列表示文档最后修改时间
# 第七列表示文档名称,以点.开头的是隐藏文档
$ ls -l
# 部分 Linux 提供了 ll 作为 ls -l 的别名
$ ll
总用量 256
dr-xr-xr-x. 2 root root 49152 3月 1 05:59 bin
drwxr-xr-x. 3 root root 18 3月 13 21:00 dfs
drwxr-xr-x. 2 root root 6 4月 11 2018 etc
drwxr-xr-x. 2 root root 6 4月 11 2018 games
drwxr-xr-x. 9 root root 4096 2月 28 21:55 include
dr-xr-xr-x. 33 root root 4096 3月 1 05:59 lib
dr-xr-xr-x. 141 root root 77824 2月 28 21:55 lib64
drwxr-xr-x. 46 root root 12288 2月 28 21:55 libexec
drwxr-xr-x. 12 root root 131 2月 28 21:49 local
dr-xr-xr-x. 2 root root 20480 2月 28 21:55 sbin
drwxr-xr-x. 223 root root 8192 3月 1 05:59 share
drwxr-xr-x. 4 root root 34 2月 28 21:49 src
lrwxrwxrwx. 1 root root 10 2月 28 21:49 tmp -> ../var/tmp

# 以易于阅读的格式展示大小
$ ls -lh
# 或
$ ll -h
总用量 256K
dr-xr-xr-x. 2 root root 48K 3月 1 05:59 bin
drwxr-xr-x. 3 root root 18 3月 13 21:00 dfs
drwxr-xr-x. 2 root root 6 4月 11 2018 etc
drwxr-xr-x. 2 root root 6 4月 11 2018 games
drwxr-xr-x. 9 root root 4.0K 2月 28 21:55 include
dr-xr-xr-x. 33 root root 4.0K 3月 1 05:59 lib
dr-xr-xr-x. 141 root root 76K 2月 28 21:55 lib64
drwxr-xr-x. 46 root root 12K 2月 28 21:55 libexec
drwxr-xr-x. 12 root root 131 2月 28 21:49 local
dr-xr-xr-x. 2 root root 20K 2月 28 21:55 sbin
drwxr-xr-x. 223 root root 8.0K 3月 1 05:59 share
drwxr-xr-x. 4 root root 34 2月 28 21:49 src
lrwxrwxrwx. 1 root root 10 2月 28 21:49 tmp -> ../var/tmp

查看目录和文件大小

du [OPTION]... [PATH]...:递归汇总目录的磁盘使用情况

  • -a:显示每个文件和目录的大小,而非只显示目录
  • -c:统计总和
  • -h:以易于阅读的格式展示文件大小
1
2
3
4
5
$ du -ach
0 ./upload
177M ./oracle-j2sdk1.8-1.8.0+update181-1.x86_64.rpm
177M .
177M 总用量

操作目录

切换目录

cd [dir]:切换工作目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 切换到 /usr/local(绝对路径)
$ cd /usr/local

# 切换到上一级
$ cd ..

# 切换到 tmp(相对路径)
$ cd tmp

# 切换到上次所在目录
$ cd -

# 切换到用户主目录
$ cd
# 或
$ cd ~

创建目录

mkdir [选项]... 目录...:创建目录

  • -p--parents:需要时创建目标目录的上层目录,但即使这些目录已存在也不当作错误处理;
  • -v--verbose:每次创建新目录都显示信息。
1
2
3
4
# 创建aaa/bbb目录并显示信息
$ mkdir -pv aaa/bbb
mkdir: 已创建目录 "aaa"
mkdir: 已创建目录 "aaa/bbb"

删除目录

rmdir [选项]... 目录...:删除指定的空目录

  • -p--parents:删除指定目录及上层目录
  • -v--verbose:输出处理的目录详情
1
2
3
4
# 删除aaa/bbb目录并显示信息
$ rmdir -pv aaa/bbb
rmdir: 正在删除目录 "aaa/bbb"
rmdir: 正在删除目录 "aaa"

操作文件

  • touch:创建文件
  • rm:删除文件(remove)
  • -f:不经确认强制删除文件(force)
  • -r:递归删除目录及目录中的内容(recursion)
  • -rf:不经过确认递归删除目录及目录中的内容
  • -rf *:不经过确认递归删除当前目录的所有内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建1.txt
$ touch 1.txt

# 在 aaa 目录下创建 2.txt,在 ccc/ddd 目录下创建 3.txt
$ touch aaa/2.txt ccc/ddd/3.txt

# 删除 1.txt
$ rm 1.txt
rm:是否删除普通空文件 "1.txt"?y

# 不经确认强制删除2.txt
$ rm -f aaa/2.txt

# 不经确认强制删除bbb目录和ccc目录
$ rm -rf aaa ccc

复制和移动

  • cp:复制文件或目录(copy)
  • -n:不覆盖已存在的文件
  • -R/-r:递归复制目录及其子目录内的所有内容(recursive)
  • -v:显示详细的进行步骤
  • mv:移动文件或目录(move)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建1.txt文件和aaa目录
$ touch 1.txt
$ mkdir aaa

# 复制1.txt文件到aaa目录
$ cp 1.txt aaa

# 复制1.txt文件到aaa目录,并且更改文件名为2.txt
$ cp 1.txt aaa/2.txt

# 将aaa目录复制到新建的bbb目录
$ cp -r aaa bbb

# 将1.txt移动到新建的ccc目录
$ mkdir ccc
$ mv 1.txt ccc

# 创建2.txt文件,重命名为3.txt
$ touch 2.txt
$ mv 2.txt 3.txt

打包和压缩

tar 命令可以为 Linux 的文件和目录创建档案。利用 tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件。tar 最初被用来在磁带上创建档案,现在用户可以在任何设备上创建档案。利用 tar 命令,可以把一大堆的文件和目录全部打包成一个文件,这对于备份文件或将几个文件组合成为一个文件以便于网络传输是非常有用的。

首先要分清楚打包和压缩是两个概念:打包是指将一大堆文件或目录变成一个大文件;压缩则是将一个大文件通过一些压缩算法变成一个小文件。

tar <选项> <文件或目录>

选项:

  • -c:创建新的归档文件
  • -v:显示运行过程信息
  • -f:指定操作的文件或目录名
  • -z:使用 gzip 压缩处理
  • -x:解包

追加选项:

  • -C:解压至指定目录

常用命令组合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 打包。将DirectoryA目录打包成DirectoryA.tar
$ tar -cvf DirectoryA.tar DirectoryA
.
├── DirectoryA.tar
└── DirectoryA
├── a.txt
└── b.log

# 解包。对DirectoryA.tar进行解包
$ tar -xvf DirectoryA.tar

# 解包到指定目录下,指定目录需存在
$ tar -xvf DirectoryA.tar -C DirectoryB
.
├── DirectoryA.tar
├── DirectoryB
│   └── DirectoryA
│   ├── a.txt
│   └── b.log
└── DirectoryA
├── a.txt
└── b.log

# 打包并压缩。将DirectoryA目录打包并压缩成DirectoryA.tar.gz
$ tar -zcvf DirectoryA.tar.gz DirectoryA

# 解压缩包。可省略选项-z
$ tar -zxvf DirectoryA.tar.gz

# 解压缩包到指定目录下,指定目录需存在。可省略选项-z
$ tar -zxvf DirectoryA.tar.gz -C DirectoryC

查找文件

find 命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。

语法:find [path] <选项> <参数>

选项:

  1. 根据名称查找
  • -name pattern:以文件或目录名查找,支持 glob 风格通配符。
  • -iname pattern:以文件或目录名查找,忽略大小写,支持 glob 风格通配符。
  • -regex pattern:基于正则表达式查找路径,此时是对整个路径进行匹配,而非只是匹配文件名。默认为 Emacs 正则表达式,可以使用 -regextype 选项进行更改。
  1. 根据文件类型查找
  • -type <TYPE> : 以文件类型查找。文件类型如下:
  • f:普通文件
  • d:目录文件
  • b:块设备文件
  • c:字符设备文件
  • l:连接文件
  • s:套接字文件
  • p:管道文件
  1. 根据文件大小查找
  • -size [+|-]SIZE : 以文件大小查询,大小包含 K,M,G 的单位
  • -size 5M : 查找大小为 5 MB 的文件,允许有偏差
  • -size -5M : 查询小于 5 MB 的文件
  • -size +5M : 查询大于 5 MB 的文件
  • -empty:查找空文件
  1. 根据时间查找,+ 表示之前,- 表示之后,无符号表示刚好
  • -atime [+/-]<NUM>:以访问时间(天)查找
  • -mtime [+/-]<NUM>:以数据修改时间(天)查找
  • -ctime [+/-]<NUM>:以元数据修改时间(天)查找
  • -amin [+/-]<NUM>:以访问时间(分钟)查找
  • -mmin [+/-]<NUM>:以数据修改时间(分钟)查找
  • -cmin [+/-]<NUM>:以元数据修改时间(分钟)查找
  • -newer <FILE>:以 FILE 文件为基准,查询比它新的文件
  1. 根据文件从属关系查找
  • -user <USERNAME>:以用户名查找
  • -group <GROUPNAME>:以组名查找
  • -nouser:查找没有属主的文件
  • -nogroup:查找没有属组的文件
  1. 根据权限查找
  • -perm <MODE>:根据权限精确查找
  • -perm </MODE>:任何一类用户(u/g/o)含有对应的一种权限(r/w/x)即可
  • -perm /666:至少有一类用户有读或写权限
  • -perm /660:主用户或组用户有读或写权限
  • -perm /001:其他用户有执行权限
  • -perm <-MODE>:每一类用户(u/g/o)满足对应的每一种权限(r/w/x)
  • -perm -666:每一类用户都有读和写权限
  • -perm -660:主用户或组用户有读和写权限
  • -perm -700:主用户有读、写和执行权限
  1. 组合条件
  • -a:与,两个条件同时满足。默认组合,可以省略。
  • -o:或,两个条件满足任意一个。例如:find . -type f -o root
  • -not / !:非,不满足该条件。例如:find . -not -type f
  1. 指定目录层级
  • -maxdepth <NUM>:指定最多搜索目录层级到 NUM 层
  • -mindepth <NUM>:指定最少搜索目录 NUM 层级
  1. 处理动作
  • -print:输出到屏幕上。默认选项,可以省略。
  • -ls:输出文件或目录的详细信息。
  • -delete:删除查找到的文件。
  • -ok COMMAND {} \;:查找到的文件传递给 COMMAND 命令,每步都需要用户确认
  • -exec COMMAND {} \;:查找到的文件传递给 COMMAND 命令,不需要用户确认

注意:find 将查找到的路径一次性传递给后面的命令,但有很多的命令不能接受过长的参数,导致命令的执行失败,可以使用 xargs 命令避免这种错误的发生。详见示例。

glob 风格通配符规则

Pattern Matches
? 匹配一个字符
* 匹配任意个(包括0个)字符
[] 匹配括号中的任一字符,例如[1,2,3]。可以使用 - 表示范围,例如 [1-3][a-d]
\\x 用于转义符号。例如匹配 ? 就需要使用 \\?

Emacs 正则表达式常用模式

Pattern Matches
. 除换行 \\n 以外的所有字符
\\. 一个点 .
[0-9]+ 一个或多个数字
[^0-9]+ 一个或多个非数字
[A-Za-z]+ 一个或多个字母
[-A-Za-z0-9]+ 一个或多个{字母,数字,连字符}
[_A-Za-z0-9]+ 一个或多个{字母,数字,下划线}
[-_A-Za-z0-9]+ 一个或多个{字母,数字,连字符,下划线}
Pattern Matches
+ 匹配一次或多次前一个模式
* 匹配零次或多次前一个模式
? 匹配零次或一次前一个模式
+? 匹配一次或多次前一个模式,但使用最小匹配(即,非贪婪模式)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 示例文件的目录树,以及权限、大小
$ tree -p -u -g -s -h .
.
├── [drwxr-xr-x root root 55] dir1
│   ├── [-rw-r--r-- root root 0] readme.txt
│   ├── [-rwxr--r-- root root 42] start.sh
│   └── [-rwxr-xr-x root root 51] stop.sh
├── [-rw-r--r-- root root 6.4K] QuickVideo-1.0-SNAPSHOT.jar
├── [-rw-r--r-- root root 13K] QuickVideo-1.1-SNAPSHOT.jar
├── [-rwxr--r-- root root 42] start.sh
├── [-rwxr-xr-x root root 51] stop.sh
├── [-rw-r--r-- root root 0] testfile.txt
├── [-rw-r--r-- root root 8] testFile.txt
└── [-rw-r--r-- mysql root 102] test.txt

# 1.根据名称查找
# 根据名称查找
$ find . -name testfile.txt
./testfile.txt
# 根据名称查找,忽略大小写
$ find . -iname testfile.txt
./testFile.txt
./testfile.txt
# 使用通配符查找,建议用单引号或双引号将文件名引起来,或者使用\进行转义,否则会报错
$ find . -name '*.jar'
./QuickVideo-1.0-SNAPSHOT.jar
./QuickVideo-1.1-SNAPSHOT.jar
$ find . -name \*.jar
./QuickVideo-1.0-SNAPSHOT.jar
./QuickVideo-1.1-SNAPSHOT.jar
$ find . -name *.jar
find: 路径必须在表达式之前: QuickVideo-1.1-SNAPSHOT.jar
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
# 基于正则表达式查找路径
# 如果从相对路径开始查找(例如path为.),进行匹配的路径也是相对路径
# 如果从绝对路径开始查找(例如path为/data),进行匹配的路径也是绝对路径
# 正则表达式中的.用来通配换行符\n以外的所有字符,所以匹配路径中的.时需要转义为\.,如果不加引号需要转义为\\.
$ find . -regex \\./test.*\\.txt
./testFile.txt
./testfile.txt
./test.txt
$ find /data -regex '/data/test.+\.txt'
/data/testFile.txt
/data/testfile.txt
$ find . -regex './QuickVideo-[0-9]\.[0-9]-SNAPSHOT\.jar'
./QuickVideo-1.0-SNAPSHOT.jar
./QuickVideo-1.1-SNAPSHOT.jar

# 2.根据文件类型查找
# 查找目录
$ find . -type d
.
./dir1

# 3.根据文件大小查找
# 查找大小为0的文件
$ find . -size 0
./testfile.txt
./dir1/readme.txt
# 查找大于5KB的文件
$ find . -size +5k
./QuickVideo-1.0-SNAPSHOT.jar
./QuickVideo-1.1-SNAPSHOT.jar

# 4.根据时间查找
# 查找昨天进行过数据修改的文件或目录
$ find . -mtime 1
./QuickVideo-1.0-SNAPSHOT.jar
# 查找数据修改时间在5分钟内的文件或目录
$ find . -mmin -5
.
./test.txt
./dir1
./dir1/start.sh
./dir1/stop.sh

# 5.根据文件从属关系查找
$ find . -user mysql
./test.txt

# 6.根据权限查找
# 查找权限为744的文件或目录
$ find ./dir1 -perm 744
./dir1/start.sh
# 查找至少一类用户拥有读或写权限的文件或目录
$ find ./dir1 -perm /666
./dir1
./dir1/stop.sh
./dir1/readme.txt
./dir1/start.sh
# 查找主用户拥有执行权限的文件或目录
$ find ./dir1 -perm /100
./dir1
./dir1/stop.sh
./dir1/start.sh
# 查找其他用户拥有执行权限的文件或目录
$ find ./dir1 -perm /001
./dir1
./dir1/stop.sh
# 查找每一类用户都有读和执行权限的文件或目录
$ find ./dir1 -perm -555
./dir1
./dir1/stop.sh
# 查找主用户有读、写和执行权限的文件或目录
$ find ./dir1 -perm -700
./dir1
./dir1/stop.sh
./dir1/start.sh

# 7.组合条件
# 查找以.jar结尾并且大于10KB的文件
$ find . -name '*.jar' -a -size +10k
./QuickVideo-1.1-SNAPSHOT.jar

# 8.指定目录层级
$ find / -maxdepth 1 -name '*.txt'
/data/testfile.txt
/data/testFile.txt
/data/test.txt
$ find /data/ -mindepth 2 -maxdepth 2 -name '*.txt'
/data/dir1/readme.txt

# 9.处理动作
# 输出查找到的文件或目录的详细信息
$ find ./dir1 -name '*.txt' -ls
68371915 0 -rw-r--r-- 1 root root 0 7月 12 20:05 ./dir1/readme.txt
# 删除查找到的文件
$ find ./dir1 -name '*.txt' -delete
# 复制查找到的文件到当前目录。xargs接收到的参数,由-i声明后赋给了{}
$ find ./dir1 -type f | xargs -i cp {} ./
# 查找/var/log目录中数据修改时间在7天以前的普通文件,并在删除之前询问它们
$ find /var/log -type f -mtime +7 -ok rm {} \;

查找文件内容

grep [OPTIONS] <PATTERN> <FILE>:在指定文件中搜索与给定模式(PATTERN)匹配的行

  • -A<行数>/--after-context=<行数>:除了符合条件的那行内容外,还显示该行之后指定行数的内容。
  • -B<行数>/--before-context=<行数>:除了符合条件的那行内容外,还显示该行之前指定行数的内容。
  • -c/--count:输出匹配到多少行。
  • -C <行数> / --context=<行数>:除了符合条件的那行内容外,还显示该行之前和之后指定行数的内容,行数连续的为一个匹配组,在不同匹配组之间放置组分隔符(分隔符由 --group-separator 指定)。
  • --group-separator=<分隔符>:设置不同匹配组之间的组分隔符,默认为 --
  • -d ACTION / --directories=ACTION:如果输入的是目录,请使用 ACTION 进行处理。默认情况下,ACTIONread,即读取目录就像它们是普通文件。如果 ACTIONskip,则静默地跳过目录。如果 ACTIONrecurse,则递归读取目录下的所有文件,等效于 -r 选项。
  • -e<PATTERN> / --regexp=<PATTERN> : 指定字符串为用于匹配的模式。
  • -f <模式文件> / --file=<模式文件>:使用模式文件来查找文件内容,模式文件格式为每行一个模式。
  • -i / --ignore-case:忽略大小写。
  • -n / --line-number:显示输出的每一行在文件中的行号。
  • -r, --recursive:递归读取每个目录下的所有文件,等效于 -d recurse 选项。
  • -v--revert-match:显示不与模式匹配的所有行。
  • --color:以彩色显示(高亮)匹配到的内容。

模式表达式

模式 说明 示例
^ 锚定行的开始 ^sannaha 匹配所有以 sannaha 开头的行
$ 锚定行的结束 sannaha$ 匹配所有以 sannaha 结尾的行
\< 锚定单词的开始 '\<san' 匹配所有以 san 开头的单词
\> 锚定单词的结束 ‘ha\>’ 匹配所有以 ha 结尾的单词
. 匹配一个非换行符的字符 san.aha 匹配 san 后接一个任意字符,然后是 aha,可以匹配到 sannaha / sanaaha
* 匹配零个或多个先前字符 san*aha 匹配 san 后接任意个任意字符,然后是aha,可以匹配到 sannaha / sannnnaha
.* 匹配任意个任意字符
[] 匹配一个指定范围内的字符 [Ss]annaha 可以匹配到 Sannaha / sannaha
[^] 匹配一个不在指定范围内的字符 [^A-RT-Za-rt-z]annaha 匹配不以 A-RT-Za-rt-z 字母开头,紧跟 annaha 的行
x\{m\} 字符 x 连续出现 m 次 'n\{2\}' 匹配连续出现 2 个 n 的行
x\{m,\} 字符 x 连续出现至少 m 次 'n\{2\}' 匹配至少连续出现 2 个 n 的行
x\{m,n\} 字符 x 连续出现至少 m 次,至多 n 次 'n\{2,5\}' 匹配连续出现 2~5 个 n 的行
\w 匹配文字(含括中文字符)和数字字符,也就是除了标点符号 's\w*ha' 匹配以 S 后跟零个或多个文字或数字,然后是 ha
\W \w相反,匹配标点符号(包含全角) 's\W*ha' 匹配以 S 后跟零个或多个标点符号,然后是 ha
\b 单词锁定符 '\bsannaha\b' 只匹配 sannaha

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 查找日志文件中包含Huawei字符串的行
$ grep Huawei test.log

# 查找日志文件中包含Huawei字符串的行,并显示前后2行的内容
$ grep -A2 -B2 Huawei test.log

# 查找日志文件中包含Huawei字符串的行,并显示前后2行的内容,不同匹配组之间用--分割,显示输出的每一行在文件中的行号
$ grep -C2 -n Huawei test.log
1017:2020-07-15 01:33:16.111 {"ba":"Huawei","detail":"325","en":"start","entry":"3","extend1":"","g":"[email protected]","hw":"640*1136","l":"en","la":"-40.6","ln":"-78.0","loading_time":"0","md":"Huawei-4","mid":"987","nw":"4G","open_ad_type":"1","os":"8.1.3","sr":"N","sv":"V2.7.9","t":"1594660652034","uid":"987","vc":"19","vn":"1.3.1"}
1018-2020-07-15 01:33:16.111 {"ba":"HTC","detail":"433","en":"start","entry":"4","extend1":"","g":"[email protected]","hw":"640*960","l":"es","la":"-7.5","ln":"-53.5","loading_time":"10","md":"HTC-10","mid":"988","nw":"4G","open_ad_type":"1","os":"8.2.4","sr":"Q","sv":"V2.3.1","t":"1594686697202","uid":"988","vc":"7","vn":"1.0.8"}
1019-2020-07-15 01:33:16.111 {"cm":{"ba":"Sumsung","sr":"M"},"ap":"app","et":[{"ett":"1594670873278","en":"display","kv":{"goodsid":"253","action":"2","extend1":"2","place":"4","category":"23"}},{"ett":"1594692533469","en":"loading","kv":{"extend2":"","loading_time":"1","action":"1","extend1":"","type":"3","type1":"433","loading_way":"2"}},{"ett":"1594652353013","en":"ad","kv":{"entry":"2","show_style":"4","action":"4","detail":"","source":"1","behavior":"1","content":"1","newstype":"9"}},{"ett":"1594722037235","en":"active_background","kv":{"active_source":"2"}},{"ett":"1594694827276","en":"error","kv":{"errorDetail":"at cn.lift.dfdfdf.control.CommandUtil.getInfo(CommandUtil.java:67)\\n at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\\n at java.lang.reflect.Method.invoke(Method.java:606)\\n","errorBrief":"at cn.lift.appIn.control.CommandUtil.getInfo(CommandUtil.java:67)"}},{"ett":"1594725790390","en":"praise","kv":{"target_id":1,"id":2,"type":2,"add_time":"1594701200613","userid":3}}]}
--
1022-2020-07-15 01:33:16.112 {"cm":{"ba":"Sumsung","sr":"A"},"ap":"app","et":[{"ett":"1594676478453","en":"ad","kv":{"entry":"1","show_style":"4","action":"3","detail":"","source":"1","behavior":"2","content":"2","newstype":"9"}},{"ett":"1594656458123","en":"notification","kv":{"ap_time":"1594734739250","action":"3","type":"2","content":""}},{"ett":"1594679882683","en":"favorites","kv":{"course_id":3,"id":0,"add_time":"1594671137871","userid":1}}]}
1023-2020-07-15 01:33:16.112 {"ba":"Sumsung","detail":"102","en":"start","entry":"3","extend1":"","g":"[email protected]","hw":"640*960","l":"es","la":"-13.7","ln":"-118.6","loading_time":"17","md":"sumsung-7","mid":"993","nw":"WIFI","open_ad_type":"1","os":"8.2.2","sr":"C","sv":"V2.5.5","t":"1594742307465","uid":"993","vc":"6","vn":"1.0.9"}
1024:2020-07-15 01:33:16.112 {"ba":"Huawei","detail":"","en":"start","entry":"5","extend1":"","g":"[email protected]","hw":"750*1134","l":"en","la":"16.5","ln":"-78.2","loading_time":"4","md":"Huawei-1","mid":"994","nw":"WIFI","open_ad_type":"2","os":"8.0.0","sr":"T","sv":"V2.8.1","t":"1594709075161","uid":"994","vc":"10","vn":"1.1.0"}

# 输出匹配到Huawei多少行
$ grep -c Huawei test.log
336

# 递归读取flume目录下的所有文件,匹配a1.sources.r1.type
$ grep -d recurse a1.sources.r1.type flume
flume/spooldir-kafka.conf:a1.sources.r1.type = spooldir
flume/taildir-without-kafka.conf:a1.sources.r1.type = TAILDIR
flume/taildir-kafka.conf:a1.sources.r1.type = TAILDIR

# 匹配行的开头
$ echo sannaha | grep ^san
# 匹配行的结尾
$ echo sannaha | grep ha$
# 匹配单词的开头
$ echo sannaha | grep '\<san'
# 匹配单词的结尾
$ echo sannaha | grep 'ha\>'
# 匹配一个非换行符的字符
$ echo sannaha | grep san.aha
# 匹配零个或多个先前字符
$ echo sannaha | grep san*aha
# 匹配一个指定范围内的字符
$ echo sannaha | grep [Ss]annaha
# 匹配一个不在指定范围内的字符
$ echo sannaha | grep [^A-RT-Za-rt-z]annaha
# 字符n连续出现2次
$ echo sannaha | grep 'n\{2\}'
# 字符n连续出现至少2次
$ echo sannnnaha | grep 'n\{2\}'
# 字符n连续出现至少2次,至多5次
$ echo sannnnaha | grep 'n\{2,5\}'
# 匹配文字(含括中文字符)和数字字符,也就是除了标点符号
$ echo san誓愿233naha | grep 'san\w*ha'
# 匹配标点符号(包含全角)
$ echo san,,.。naha | grep 'san\W*naha'
# 单词锁定符
$ echo sannaha sannaha666 | grep '\bsannaha\b'

查看文件内容

  • cat <FILE>:将文件信息全部输出到控制台,适合内容较少的文件。
  • more <FILE>:适合显示内容比较多的文件,先显示一屏,按回车键显示下一行,按空格键显示下一屏,按 Q 键退出。
  • less <FILE>:与 more 类似,支持使用 PgUp 键和 PgDn 键翻页。
  • tail [参数] <FILE>:用于查看文件最后 10 行的内容:
  • -<行数>:查看文件最后指定行数的内容。
  • -f:动态显示文件最后指定行数的内容,常用来查看日志。
  • -<行数>f:动态显示文件最后指定行数的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看文件的内容
$ cat 1.txt
sannaha

# 使用more查看日志文件的内容
$ more catalina.2018-11-21.log
21-Nov-2018 10:11:03.067 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.31
21-Nov-2018 10:11:03.098 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Apr 27 2018 20:24:25 UTC
--More--(1%)

# 使用less查看日志文件的内容
$ less catalina.2018-11-21.log
21-Nov-2018 10:11:03.067 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.31
21-Nov-2018 10:11:03.098 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Apr 27 2018 20:24:25 UTC
catalina.2018-11-21.log

# 使用tail查看日志文件最后20行的内容
$ tail -20 catalina.2018-11-21.log

# 使用tail动态查看日志文件最后20行的内容
$ tail -20f catalina.2018-11-21.log

查看帮助手册

man 命令是 Linux 下的帮助指令,通过 man 指令可以查看 Linux 中的指令帮助、配置文件帮助和编程帮助等信息。

语法:man [选项] [参数]

选项:

  • -a:在所有的 man 帮助手册中搜索。
  • -f:等价于 whatis 指令,显示给定关键字的简短描述信息。
  • -P:指定内容时使用分页程序。
  • -M:指定 man 手册搜索的路径。

man 存放帮助命令的程序说明文件的目录为 /usr/share/man,可以看见该目录下又有多个目录,如 man1man2 等等,用于存放不同用途的命令:

1
2
3
$ ls /usr/share/man
cs de fr id ja man0p man1p man2 man3 man3x man4x man5x man6x man7x man8x man9x nl pt ru sv zh_CN
da es hu it ko man1 man1x man2x man3p man4 man5 man6 man7 man8 man9 mann pl pt_BR sk tr zh_TW

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
$ man date 
DATE(1) User Commands DATE(1)
# 请注意上面这个括号内的数字
NAME <==这个命令的完整全名,如下所示为date且说明简单用途为配置与显示日期/时间
date - print or set the system date and time

SYNOPSIS <==这个命令的基本语法如下所示
date [OPTION]... [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]

DESCRIPTION <==详细说明刚刚语法谈到的选项与参数的用法
Display the current time in the given FORMAT, or set the system
date.

-d, --date=STRING <==左边-d为短选项名称,右边--date为完整选项名称
display time described by STRING, not 'now'

-f, --file=DATEFILE
like --date once for each line of DATEFILE

-r, --reference=FILE
display the last modification time of FILE
....(中间省略)....
# 找到了!底下就是格式化输出的详细数据!
FORMAT controls the output. The only valid option for the second
form specifies Coordinated Universal Time. Interpreted sequences
are:

%% a literal %

%a locale's abbreviated weekday name (e.g., Sun)

%A locale's full weekday name (e.g., Sunday)
....(中间省略)....
ENVIRONMENT <==与这个命令相关的环境参数有如下的说明
TZ Specifies the timezone, unless overridden by command line
parameters. If neither is specified, the setting from
/etc/localtime is used.

AUTHOR <==这个命令的作者啦!
Written by David MacKenzie.

REPORTING BUGS <==有问题请留言给底下的email的意思!
Report bugs to <[email protected]>.

COPYRIGHT <==受到著作权法的保护!用的就是 GPL 了!
Copyright ? 2006 Free Software Foundation, Inc.
This is free software. You may redistribute copies of it under the
terms of the GNU General Public License
<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to
the extent permitted by law.

SEE ALSO <==这个重要,你还可以从哪里查到与date相关的说明文件之意
The full documentation for date is maintained as a Texinfo manual.
If the info and date programs are properly installed at your site,
the command

info date

should give you access to the complete manual.

date 5.97 May 2006 DATE(1)

出现的这个屏幕画面,我们称呼他为 man page, 你可以在里头查询他的用法与相关的参数说明。如果仔细一点来看这个 man page 的话,你会发现几个有趣的东西。

首先,在上个表格的第一行,你可以看到的是:DATE(1),DATE我们知道是命令的名称, 那么 (1) 代表什么呢?他代表的是“一般用户可使用的命令”的意思!在查询数据的后面的数字可以帮助我们了解或者是直接查询相关的数据。 常见的几个数字的意义是这样的:

代号 代表内容
1 使用者在 shell 环境中可以操作的命令或可运行文件
2 系统核心可呼叫的函数与工具等
3 一些常用的函数(function)与函式库(library),大部分为 C 的函式库(libc)
4 装置文件的说明,通常在/dev下的文件
5 配置文件或者是某些文件的格式
6 游戏(games)
7 惯例与协议等,例如 Linux 文件系统、网络协议、ASCII code 等等的说明
8 系统管理员可用的管理命令
9 跟 Kernel 有关的文件

上述的表格内容可以使用 man 7 man 来更详细的取得说明。透过这张表格的说明, 未来你如果使用 man page在察看某些数据时,就会知道该命令/文件所代表的基本意义是什么了。

重定向输入输出

命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
1
2
3
4
5
6
7
8
9
10
11
12
13
# 在文件中写入内容
$ echo Hello > file.txt

# 在文件中追加内容
$ echo World >> file.txt

# 将 EOT 标记内的内容作为输入发送给 ftp 程序
$ ftp -in 192.168.153.121 << EOT
user ftpadmin ftpadmin
cd mydir
nlist . mydirlist.txt
bye
EOT

注:文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

标准输入输出

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件:stdin的文件描述符为 0,Unix 程序默认从 stdin 读取数据。
  • 标准输出文件:stdout 的文件描述符为 1,Unix 程序默认向 stdout 输出数据。
  • 标准错误文件:stderr 的文件描述符为 2,Unix 程序会向 stderr 流中写入错误信息。
1
2
3
4
5
6
7
8
9
10
11
# 将 stdout 重定向到 file
$ command > file
# 将 stdin 重定向到 file
$ command < file
# 将 stdout 和 stderr 合并后重定向到 file
$ command > file 2>&1
# 将 stdout 和 stderr 合并后重定向到 /dev/null,实现丢弃所有输出
$ command > /dev/null 2>&1

# 将 stdin 重定向到 file1,将 stdout 重定向到 file2
$ command < file1 > file2

Here文档

Here Document 是一种在命令行 Shell 里定义一个字符串的方法。它可以保存文字里面的换行或是缩进等空白字元。是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。

here文档最通用的语法是 << 紧跟一个标识符,从下一行开始是想要引用的文字,然后再在单独的一行用相同的标识符关闭。在 Unix shell 里,here 文档通常用于给命令提供输入内容。它的基本的形式如下:

1
2
3
$ command << delimiter
document
delimiter

它的作用是将两个 delimiter 之间的内容作为输入传递给 command

注意:

  • delimiter 可以是自定标记作为标识符,常用标记有 EOFEOT
  • 结尾的 delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进;
  • 开始的 delimiter 前后的空格会被忽略掉;
  • 对于那些非常复杂的任务,最好考虑使用 expect 脚本语言,这种语言就是为了达到向交互程序添加输入的目的而量身定做的。详见 *expect *

管道

管道是Linux命令的一个重要概念,它的作用是将一个命令的输出用作另一个命令的输入。

  • ls --help | more:分页查看 ls 命令的帮助信息
  • ps -ef | grep java:查找名称中包含 java 的进程

逻辑控制

命令之间使用 && 连接,实现类似逻辑与的功能。只有在 && 左边的命令运行成功后,右边的命令才会被执行:

1
2
3
4
5
# 打印1.txt和2.txt的内容
$ cat 1.txt && cat 2.txt

# 启动 tomcat 成功后,使用 tail 命令查看日志,如果启动失败,则不查看
$ ./startup.sh && tail -50f ../logs/catalina.out

系统相关命令

查看系统版本

查看 Linux 系统版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# CentOS7
$ cat /proc/version
Linux version 5.0.4-1.el7.elrepo.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)) #1 SMP Sat Mar 23 18:00:44 EDT 2019
$ uname -a
Linux site 5.0.4-1.el7.elrepo.x86_64 #1 SMP Sat Mar 23 18:00:44 EDT 2019 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

# Red Hat
$ cat /proc/version
Linux version 3.10.0-957.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Oct 4 20:48:51 UTC 2018
$ uname -a
Linux ██ 3.10.0-957.el7.x86_64 #1 SMP Thu Oct 4 20:48:51 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.6 (Maipo)

# Debian9
$ cat /proc/version
Linux version 4.9.0-15-amd64 ([email protected]) (gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1) ) #1 SMP Debian 4.9.258-1 (2021-03-08)
$ uname -a
Linux vultr.guest 4.9.0-15-amd64 #1 SMP Debian 4.9.258-1 (2021-03-08) x86_64 GNU/Linux

查看主机名

1
2
3
4
5
6
7
# 查看
$ hostname
node01

# 修改主机名
$ vi /etc/hostname
node01

查看网络信息

查看 IP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:A8:42:D0
inet addr:192.168.153.100 Bcast:192.168.153.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fea8:42d0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:33715 errors:0 dropped:0 overruns:0 frame:0
TX packets:41069 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3116951 (2.9 MiB) TX bytes:3560438 (3.3 MiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:14410 errors:0 dropped:0 overruns:0 frame:0
TX packets:14410 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:806960 (788.0 KiB) TX bytes:806960 (788.0 KiB)

集群要求使用万兆网卡,先检查网卡带宽:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ ethtool eth0
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
-> Speed: 1000Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
MDI-X: off (auto)
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes

然后修改网卡配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ vi /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="none"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="0d3a0253-024f-4033-97e0-06309768cc9d"
DEVICE="ens33"
ONBOOT="yes"
IPADDR="192.168.153.200"
PREFIX="24"
GATEWAY="192.168.153.2"
DNS1="8.8.8.8"
IPV6_PRIVACY="no"

最后重启网络服务:

1
service network restart

如果提示 ifconfig 命令未找到,可能是被 if 命令替代了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 命令格式
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }

# 对象列表
OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
vrf }
link:网络设备
address:设备上的协议(IP或IPv6)地址
addrlabel:协议地址选择的标签配置
route:路由表条目
rule:路由策略数据库中的规则

# 选项列表
OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
-h[uman-readable] | -iec |
-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |
-4 | -6 | -I | -D | -B | -0 |
-l[oops] { maximum-addr-flush-attempts } | -br[ief] |
-o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
-rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}
-V:显示命令的版本信息;
-s:输出更详细的信息;
-f:强制使用指定的协议族;
-4:指定使用的网络层协议是IPv4协议;
-6:指定使用的网络层协议是IPv6协议;
-0:输出信息每条记录输出一行,即使内容较多也不换行显示;
-r:显示主机时,不使用IP地址,而使用主机的域名。

# 常用命令组合
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:4f:64:ed brd ff:ff:ff:ff:ff:ff
inet 192.168.153.120/24 brd 192.168.153.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::dd89:51f8:acf7:b2ec/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: br-8af2350d93b3: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:58:10:20:1b brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-8af2350d93b3
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:bf:9c:17:09 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever

日期和时间

  • date:显示系统当前日期和时间
  • -s <STRING>:根据字符串设置系统日期和时间
  • -d <STRING>:显示由字符串描述的日期和时间
  • +<FORMAT>:指定显示格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 显示系统当前日期和时间
$ date
2019年 05月 06日 星期一 20:05:48 CST

# 设置系统日期和时间
$ date -s "2019-05-06 20:08:09"

# 显示昨天的日期和时间,支持day/week/month/year
$ date -d '-1 day'
2020年 10月 12日 星期一 00:46:49 CST

# 显示完整日期,两种方式等价
$ date +%F
$ date +"%Y-%m-%d"
2020-10-13

# 输出1天后的日期
$ date -d '+1 day' +%F
2020-10-14

# 输出300秒后的日期和时间
$ date -d "300 second" +"%Y-%m-%d %H:%M:%S"
2020-10-13 00:53:17

时钟同步

网络时间协议(Network Time Protocol)是计算机系统之间通过分组交换进行时钟同步的一个网络协议。

  • ntpdate:使用网络时间协议来设置日期和时间
1
2
# 使用NTP服务器进行时钟同步
$ ntpdate us.pool.ntp.org

设置时钟同步定时任务

cron 是一款类 Unix 的操作系统下的基于时间的任务管理系统,可以通过 cron 在固定时间、日期、间隔下,运行定期任务(可以是命令和脚本),通过守护进程形式运行的 cron 程序称为 crond。通过 crontab 命令,可以在固定的间隔时间执行指定的系统指令或 shell 脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 安装cron的主程序
yum install -y vixie-cron

# 安装crontabs软件包,用于维护每个用户的任务时间表(crontab)文件
yum install -y crontabs

# 启停crond服务
service crond start //启动服务
service crond stop //关闭服务
service crond restart //重启服务
service crond reload //重新载入配置
service crond status //查看服务状态

# 设置开机启动
chkconfig crond on

# 为当前用户设置定时任务
crontab -e

# 每隔1分钟进行一次时钟同步
*/1 * * * * /usr/sbin/ntpdate us.pool.ntp.org;
  • crontab:设置定时任务
  • -l:列出crontab文件
  • -e:编辑crontab文件
  • -r:删除crontab文件

crontab的文件格式:

1
2
3
4
5
6
7
.---------------- 分钟 (0 - 59)
| .------------- 小时 (0 - 23)
| | .---------- 日 (1 - 31)
| | | .------- 月 (1 - 12) OR jan,feb,mar,apr ...
| | | | .---- 星期 (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
| | | | |
* * * * * 要执行的命令

域中数值的格式:

  • ,:在同一个域中使用多个数值
  • -:指定值的范围。如1-3,等同于1,2,3
  • *:代表任何可能的值
  • */n:代表可以被n整除的值。如*/4在小时域中等同于0,4,8,12,16,20

系统信息

  • df:显示磁盘信息(disk free)
  • -h:友好显示大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ df
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/centos-root 37406880 13636640 23770240 37% /
devtmpfs 3983028 0 3983028 0% /dev
tmpfs 3995144 0 3995144 0% /dev/shm
tmpfs 3995144 11968 3983176 1% /run
tmpfs 3995144 0 3995144 0% /sys/fs/cgroup
/dev/sda1 1038336 148528 889808 15% /boot
/dev/mapper/centos-home 18262016 32992 18229024 1% /home
cm_processes 3995144 2284 3992860 1% /run/cloudera-scm-agent/process
tmpfs 799032 0 799032 0% /run/user/0

$ df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 36G 14G 23G 37% /
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 12M 3.8G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 146M 869M 15% /boot
/dev/mapper/centos-home 18G 33M 18G 1% /home
cm_processes 3.9G 2.3M 3.9G 1% /run/cloudera-scm-agent/process
tmpfs 781M 0 781M 0% /run/user/0
  • free:显示内存状态
  • -m:以 mb 单位显示内存状态
1
2
3
4
5
6
7
8
9
$ free
total used free shared buff/cache available
Mem: 7990288 5308560 159948 14456 2521780 2364948
Swap: 6160380 0 6160380

$ free -m
total used free shared buff/cache available
Mem: 7803 5183 156 14 2462 2309
Swap: 6015 0 6015
  • who:显示目前登入系统的用户信息
1
2
$ who
root pts/0 2020-06-01 12:34 (192.168.153.1)
  • hostname:查看当前主机名
1
2
$ hostname
node01

修改主机名:

1
2
3
4
5
6
7
8
9
10
# CentOS6修改
$ vim /etc/sysconfig/network
NETWORKING=yes
- HOSTNAME=node01
+ HOSTNAME=node02

# CentOS7修改
$ vim /etc/hostname
- node01
+ node02
  • uname:显示系统信息
  • -a:显示详细信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 方式一(支持CentOS6和CentOS7),本质和方式二相同
$ uname -a
Linux node01 2.6.32-754.el6.x86_64 #1 SMP Tue Jun 19 21:26:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
#内核名称(类别) 主机名 内核版本号 内核版本 内核编译日期 硬件名 处理器类型 硬件平台类型 操作系统名称

# 方式二(支持CentOS6和CentOS7)
$ cat /proc/version
Linux version 3.10.0-957.el7.x86_64 ([email protected]) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018

# 方式三(支持CentOS7)
$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.6.1810 (Core)
Release: 7.6.1810
Codename: Core

监视进程状态

top 命令用于动态的监视进程活动与系统负载等信息。

Top命令查看系统运行状态

  • PID:进程id
  • USER:进程所有者的用户名
  • PR:进程的优先级
  • NI:nice值。负值表示高优先级,正值表示低优先级
  • VIRT:进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
  • RES:进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
  • SHR:共享内存大小,单位kb
  • S:进程状态
  • D:不可中断的睡眠状态
  • R:运行
  • S:睡眠
  • T:跟踪/停止
  • Z:僵尸进程
  • %CPU:上次更新到现在的CPU时间占用百分比
  • %MEM:进程使用的物理内存 百分比
  • TIME+:进程使用的CPU时间总计,单位1/100秒
  • COMMAND:启动任务的命令行(包括参数)

查看进程

通过 ps 命令(Process Status)可以查看 Linux 中正在运行的某个进程的状态。

Linux 上的进程有 5 种状态:

  1. 运行:正在运行或在运行队列中等待。
  2. 中断:休眠中, 受阻, 在等待某个条件的形成或接受到信号。
  3. 不可中断:收到信号不唤醒和不可运行, 进程必须等待直到有中断发生。
  4. 僵死:进程已终止, 但进程描述符存在, 直到父进程调用 wait4() 系统调用后释放。
  5. 停止:进程收到 SIGSTOP, SIGSTP, SIGTIN, SIGTOU 信号后停止运行运行。

ps 工具标识进程的 5 种状态码:

  • D:不可中断的睡眠状态 uninterruptible sleep (usually IO)
  • R:运行 runnable (on run queue)
  • S:睡眠 sleeping
  • T:跟踪/停止 traced or stopped
  • Z:僵尸进程 a defunct (”zombie”) process

语法:ps [参数]

参数:

  • a:取消 BSD 样式的 “only yourself” 限制,显示进程而不管其所有者是谁(默认情况下,BSD样式的 ps 仅列出运行用户所拥有的进程)。结合 x 参数使用可以显示所有进程。
  • x:取消 BSD 样式的 “must have a tty” 限制。结合 a 参数使用可以显示所有进程。
  • u:显示面向用户的(user-oriented)格式。
  • U:按有效用户 ID(EUID)或名称选择,同 -u
  • -A, -e:显示所有进程。
  • -f:显示全格式列表(full-format listing),显示更多列信息。
  • -F:显示额外全格式列表(Extra full format),显示列再增加。
  • -U, --User:按真实用户 ID(RUID)或名称进行选择。
  • -u, --user:按有效用户 ID(EUID)或名称选择。

常用命令组合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 查看所有进程(使用标准语法)
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Apr15 ? 00:01:00 /sbin/init
...
$ ps -eF
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
root 1 0 0 4824 1988 0 Apr15 ? 00:01:00 /sbin/init
...

# 查看所有进程(使用BSD语法)
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 19296 1988 ? Ss Apr15 1:00 /sbin/init
...

# 查看指定用户的进程
$ ps

# 查看指定进程(使用标准语法)
$ ps -ef | grep mysql
root 20013 1 0 May04 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock --pid-file=/var/run/mysqld/mysqld.pid --basedir=/usr --user=mysql
mysql 20121 20013 0 May04 ? 00:09:41 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
root 32545 31667 0 16:57 pts/1 00:00:00 grep mysql --color

# 查看指定进程(使用BSD语法)
$ ps aux | grep mysql
root 20013 0.0 0.3 108244 3124 ? S May04 0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock --pid-file=/var/run/mysqld/mysqld.pid --basedir=/usr --user=mysql
mysql 20121 0.0 2.9 689876 30144 ? Sl May04 9:41 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
root 32561 0.0 0.2 103380 2048 pts/1 S+ 16:58 0:00 grep mysql

说明:

USER:该 process 属于那个使用者账号的

PID :该 process 的号码

%CPU:该 process 使用掉的 CPU 资源百分比

%MEM:该 process 所占用的物理内存百分比

VSZ :该 process 使用掉的虚拟内存量 (Kbytes)

RSS :该 process 占用的固定的内存量 (Kbytes)

TTY :该 process 是在那个终端机上面运作,若与终端机无关,则显示 ?,另外, tty1-tty6 是本机上面的登入者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。

STAT:该程序目前的状态,主要的状态有

R :该程序目前正在运作,或者是可被运作

S :该程序目前正在睡眠当中 (可说是 idle 状态),但可被某些讯号 (signal) 唤醒。

T :该程序目前正在侦测或者是停止了

Z :该程序应该已经终止,但是其父程序却无法正常的终止他,造成 zombie (疆尸) 程序的状态

START:该 process 被触发启动的时间

TIME :该 process 实际使用 CPU 运作的时间

COMMAND:该程序的实际指令

结束进程

Linux 中的 kill 命令用来终止指定进程的运行。通常,终止一个前台进程可以使用 Ctrl + C 组合键,但是对于一个后台进程就须用 kill 命令来终止。需要先使用 ps/top 等工具获取进程 PID,然后使用 kill 命令来杀掉该进程。

kill 命令用于发送指定的信号到指定进程。不指定信号将发送 SIGTERM(15)终止指定进程。如果无法终止该程序,可用 -KILL 参数发送 SIGKILL(9) 信号,强制结束进程。

语法:kill [参数]

参数:

  • -l [信号编号]:查看信号声明。如果不指定信号编号,则列出全部的信号。
  • -[s ]<信号声明> <进程号>:使用指定信号声明终止指定进程的运行。
  • -[n ]<信号编号> <进程号>:使用指定信号编号终止指定进程的运行。

说明:

只有 9 号信号(SIGKILL)才可以无条件终止进程,其他信号进程都有权利忽略。 下面是常用的信号:

信号声明 信号编号 说明
HUP 1 终端断线
INT 2 中断(同 Ctrl + C
QUIT 3 退出(同 Ctrl + \
KILL 9 强制终止
TERM 15 终止
CONT 18 继续
STOP 19 暂停

常用命令组合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 查看全部信号
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

# 查看信号编号为9对应的信号声明
$ kill -l 9
KILL

# 杀掉进程号为2333的进程
$ kill 2333

# 强制杀死进程号为2333的进程
$ kill -KILL 2333
$ kill -9 2333

开机和关机

关机命令:

1
2
3
4
5
6
7
8
9
10
11
# 立刻关机
$ shutdown -h now

# 5分钟后关机
$ shutdown -h 5

# 立刻关机
$ poweroff

# 立刻关机
$ halt

重启命令:

1
2
3
4
5
6
7
8
# 立刻重启
$ shutdown -r now

# 5分钟重启
$ shutdown -r 5

# 立刻重启
$ reboot

关闭SELinux

安全增强型 Linux(SELinux)是一种采用安全架构的 Linux 系统,它能够让管理员更好地管控哪些人可以访问系统。它最初是作为 Linux 内核的一系列补丁,由美国国家安全局(NSA)利用 Linux 安全模块(LSM)开发而成。SELinux 主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)。

查看 SELinux 状态:

1
2
3
4
5
6
7
$ /usr/sbin/sestatus -v
SELinux status: enforcing

# SELinux 有三种工作模式
# enforcing:强制模式。违反SELinux规则的行为将被阻止并记录到日志中
# permissive:宽容模式。违反SELinux规则的行为只会记录到日志中,一般为调试用
# disabled:关闭SELinux

关闭 SELinux:

1
2
3
$ vi /etc/selinux/config
- SELINUX=enforcing
+ SELINUX=disabled

挂载磁盘

Linux 服务器运行一段时间,磁盘容量可能无法满足业务需求,在服务器上添加新磁盘后,需要在 Linux 中挂载磁盘。这里使用虚拟机演示挂载磁盘的过程。

新增磁盘

虚拟机关机,在 VMware 虚拟机设置中添加磁盘,磁盘类型选择默认的 SCSI,创建新虚拟磁盘,将虚拟磁盘拆分成多个文件,设置存储磁盘文件的路径。

挂载磁盘

开机后需要对新磁盘进行格式化,创建分区,挂载分区目录到指定位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看磁盘及使用情况
$ df -lh
# 查看磁盘分区情况
$ fdisk -l

# 对/dev/sdb进行分区。输入n新建分区,输入p设置类型为主分区,输入1设置使用一个分区,起始和结束柱面(cylinder)使用默认,输入w开始写入分区
$ fdisk /dev/sdb
# 查看磁盘分区情况,可以看到新的分区/dev/sdb1
$ fdisk -l
# 在分区上创建文件系统,使用-t指定文件系统类型为ex4,使用-c在创建之前检查是否有坏道
$ mkfs -t ext4 -c /dev/sdb1
# 创建目录,用于将新的分区挂载到该目录下
$ mkdir /data02
# 挂载系统外的文件,使用-t指定文件系统类型为ext4
$ mount -t ext4 /dev/sdb1 /hd02

$ df -lh

# 将分区信息写入到文件系统表,否则mount挂载会在重启服务器后失效
$ echo "/dev/sdb1 /hd02 ext4 defaults 0 0" >> /etc/fstab

HDFS存储多目录

如果服务器为 Hadoop 集群,挂载磁盘后需要配置多目录:

1
2
3
4
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/data01,file:///hd02/dfs/data02,file:///hd03/dfs/data03,file:///hd04/dfs/data04</value>
</property>

添加磁盘后,需要对集群数据进行平衡:

1
2
3
4
5
# 开始数据平衡,各个节点磁盘空间利用率相差不超过10%
$ bin/start-balancer.sh -threshold 10

# 停止数据平衡
$ bin/stop-balancer.sh

网络防火墙

开机自启

服务开机自启

设置已有的服务开机自启:

1
2
$ systemctl enable nginx.service
$ systemctl start nginx.service

创建系统服务并设置自启

创建系统服务,并设置开机自启:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建系统服务
$ cat > /etc/systemd/system/mtp.service <<EOF
[Unit]
Description=mtp
After=network.target

[Service]
Type=forking
ExecStart=/bin/bash /home/mtproxy/mtproxy.sh start
ExecReload=/bin/bash /home/mtproxy/mtproxy.sh restart
ExecStop=/bin/bash /home/mtproxy/mtproxy.sh stop

[Install]
WantedBy=multi-user.target
EOF

# 启动服务并设置开机自启
$ systemctl start mtp
$ systemctl enable mtp

脚本开机自启

chkconfig 命令用于检查、设置系统的各种服务,可以用来设置开机自启:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 语法
chkconfig [--add][--del][--list][系统服务]
chkconfig [--level <等级代号>][系统服务][on/off/reset]

# 选项
--add:增加所指定的系统服务,让chkconfig指令得以管理它,并同时在系统启动的叙述文件内增加相关数据
--del:删除所指定的系统服务,不再由chkconfig指令管理,并同时在系统启动的叙述文件内删除相关数据
--level<等级代号>:指定读系统服务要在哪一个执行等级中开启或关毕

# 等级代号列表
等级0:表示关机
等级1:单用户模式
等级2:无网络连接的多用户命令行模式
等级3:有网络连接的多用户命令行模式
等级4:不可用
等级5:带图形界面的多用户模式
等级6:重新启动

将需要自动启动的脚本 /etc/rc.d/init.d 目录下,然后用命令 chkconfig --add filename 将自动注册开机启动和关机关闭。实质就是在 rc0.d ~ rc6.d 目录(对应 0~6 运行级)下生成一些文件链接,链接到 /etc/rc.d/init.d 目录下指定文件的脚本。

  1. /etc/rc.d/init.d 目录下添加开机自启脚本:
/etc/rc.d/init.d/autostart_mtp
1
2
3
4
#!/bin/bash
#chkconfig: 2345 10 90
#description: autostart mtp
/home/mtproxy/mtproxy.sh start

每个被 chkconfig 管理的服务需要在脚本中添加两行注释:第一行告诉 chkconfig 缺省启动的运行级(06)以及启动和停止的优先级(0100,数字越大优先级越低)。如果某服务缺省不在任何运行级启动,那么使用 - 代替运行级;第二行对服务进行描述。

autostart_mtp 脚本中 chkconfig 的含义:该服务必须在 2/3/4/5 这些运行级下被启动或关闭,启动优先级为 10,停止优先级为 90

  1. 添加脚本到开机启动项目中:
/etc/rc.d/init.d/
1
2
3
4
5
6
# 为脚本添加可执行权限
$ chmod +x /etc/rc.d/init.d/autostart_mtp

# 将脚本添加到开机自启项目中
$ chkconfig --add autostart_mtp
$ chkconfig autostart_mtp on

IP和主机名映射

修改 host 文件:

1
2
3
4
$ vi /etc/hosts
192.168.153.100 node01 node01.hadoop.com
192.168.153.101 node02 node02.hadoop.com
192.168.153.102 node03 node03.hadoop.com

Issuse

Xshell粘贴缩进错乱

使用 Xshell 终端,粘贴脚本到 vim 编辑器时,会出现缩进错乱的问题。解决方法如下:

  1. :set paste:设置 vim 进入粘贴模式;
  2. i:进入 插入(粘贴) 模式,将复制的脚本内容插入即可。

系统进入紧急模式

CentOS 启动时提示进入紧急模式:Entering emergency mode.

异常断电导致 CentOS 服务器启动时报错:

1
2
3
4
5
6
7
8
[    3.773417]XFS (dm-0): metadata I/O error:block 0x1 ("xfs_trans_read_buf_map") error 117 numblks 1

Genrating "/run/initramfs/rdsosreport.txt"

Entering emergency mode. Exit the shell to continue.
Type "journalctl" to view system logs.
You might want to save "/run/initramfs/rdsosreport.txt" to usb stick or /boot
after mounting them and attach it to a bug report.

XFS(dm-0):metadata IO error:metadata IO error.png)

阅读一些论坛后, 找到了解决问题的方案 ,需要运行 xfs_repair 命令:

1
xfs_repair -v -l /dev/dm-0

上述原因可能是电源切断、不正确关机或 CentOS 服务器受到攻击。

Shell脚本报错

Shell 脚本执行时报错 bash: java: 未找到命令

脚本内容如下:

1
2
3
4
#!/bin/bash
for i in devcdh1.cdh.com devcdh2.cdh.com devcdh3.cdh.com; do
ssh $i "java -classpath /data/emall-logcollect-1.0-SNAPSHOT-jar-with-dependencies.jar moe.sannaha.appclient.AppMain"
done

在 Shell 中报错,原因是 bash 找不到 java 命令,一般来说是 Java 的环境变量有问题,或是需要对环境变量重新编译。但在脚本中报错,又可能是其他原因。

环境变量有两种修改方式:

  1. 修改 /etc/profile:用来设置全局环境变量,对所有用户生效,修改后需要对环境变量重新编译 source /etc/profile
  2. 修改 ~/.bashrc:用来设置当前用户的环境变量,只对该用户生效,该用户运行 bash 时就会读取该文件。

登录式 Shell,例如使用 root 用户登录,会自动加载 /etc/profile。非登录式 Shell,例如使用 ssh 的方式登录,不会自动加载 /etc/profile,会自动加载 ~/.bashrc

所以执行脚本时会报错,需要修改 .bashrc,确保每次打开 bash 时都会更新 Java 的路径到 PATH 变量:

1
echo "export PATH=\$PATH:/usr/java/jdk1.8.0_181-cloudera/bin" >> ~/.bashrc

参考资料
linux目录结构详细讲解
每天一个linux命令(41):ps命令
每天一个linux命令(42):kill命令
What does this paragraph in the ps man page mean?
第五章、首次登陆与在线求助 man page
Linux之Find命令详解
第十四章、Linux 账号管理与 ACL 权限配置
awk 入门教程
文件描述符(File Descriptor)简介

  • 本文作者: SANNAHA
  • 本文链接: https://sannaha.moe/Linux/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!