简单了解 Linux 系统,另外推荐一个 Linux 的学习网站:https://www.linuxshelltips.com/。

一、目录

目录名称 介绍
/home 用户主目录,子目录名称默认以该用户名命名。
/root root用户主目录。
/bin 常用的命令文件。
/sbin 包含系统管理员和root用户所使用的命令文件。
/boot Linux系统的内核文件和引导装载程序文件。
/opt 第三方应用程序的安装文件。
/etc Linux上的大部分配置文件,建议修改重要的配置文件之前先备份。
/usr 包含可以供所有用户使用的程序和数据。
/media 系统自动为某些设置(比如u盘等)挂载提供挂载目录。
/mnt 手动为某些设备(比如硬盘)挂载提供挂载目录。
/dev 大部分设备文件。

一般编译安装的可执行文件默认路径为 /usr/local/

二、权限

在 Linux 中可以明显感受到用户间的不同权限,如果你之前是使用 Windows 系统的话,可能经验比较少,突然使用 Linux 会不习惯,尤其是使用普通用户操作一些超级命令的时候。

在 Linux 中,打开终端 bash,普通用户是 $ 标识,root 用户是 # 标识。为了方便的管理用户,还有用户组的概念。

对于系统上的一个文件来说,对于它的操作用户有 3 种:创建它的用户,超级用户,其它用户。

用户操作

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
# 创建用户(如果创建用户的时候没有指定组名,默认会自动创建一个和用户名相同的组名): 
useradd -d 设置用户主目录 -g 设置用户组群 username

# 修改用户主目录并移动之前的主目录文件到新的目录中:
# 如果添加了 -m 选项,用户旧目录会移动到新的目录中;如果不存在,就新建
usermod -l new_username -d /home/develop –g developer -m old_username

# 删除用户
# 带 -rf 选项时记得做好备份,会将用户主目录和用户一并删除;若不带选项主目录将保留。
userdel -rf

# 添加组群:
groupadd group_name

# 修改组群名:
groupmod -n newName oldName

# 删除组群:
groupdel group_name

# 给指定的用户设置密码(如果新创建的用户没有密码,那么该用户是无法使用的,类似未激活)
passwd username

# 添加用户到组群
gpasswd -a username group_name

# 删除组群的指定用户
gpasswd -d username group_name

# 查看用户属于那些群组
groups username

# 让属于该群组的当前用户以指定的组群身份登录
newgrp groupName username

useradd、usermod 命令支持的常用选项如下:

选项 说明
-c 该用户的描述
-d 指定用户主目录,默认 /home/用户名;如果此目录不存在,可以同时使用-m选项,强制创建主目录。
-g 用户组 指定用户所属的用户组。
-G 用户组,用户组 指定用户所属的附加组。
-s Shell文件 指定用户的登录Shell。
-u 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。

授权操作

Linux 每个文件都是有对应操作权限的,可以使用 ls -l 查看当前所在路径的文件的所属用户、所属组和对应的权限。

可选项 意义
u 用户所有者
g 用户组群
o 其他用户
a 所有用户,系统默认值
+ 添加某个权限
-(减号) 取消某个权限
=(等号) 赋予给定权限并取消原有权限(如果有的话)
r 读取权限
w 写入权限
x 可执行权限

数字权限表示法:r=4,w=2,x=1

linux文件权限信息图
linux文件权限信息图
  • 给指定的文件添加某个权限:

    1
    2
    3
    4
    # 数字法
    chmod 777 file.sh
    # 字母法
    chmod u+x,g+wx file.sh
  • 更改文件和目录所有者(二选一):

    1
    2
    chown -R 用户.组群 文件/目录
    chown -R 用户:组群 文件/目录

    -R 选项是递归操作,把目录下的所有文件全部修改为当前的权限。

  • 只修改所属用户(即用户所有者)

    1
    chown newGroup file
  • 只修改所属用户组(二选一)

    1
    2
    chown .newGroup file
    chown :newGroup file

三、命令

Linux 中的命令非常的多,这里只介绍基础使用的命令,这些命令工具在几乎所有的 Linux 发行版中默认安装。另外常用的简单命令,例如 lscdcatclearhistory 等这里也略过。

系统信息

1
2
3
4
5
6
# Linux 发行版信息,也可以使用 cat /etc/os-release 查看
lsb_release -a
# 显示 Linux 内核版本(架构)、gcc 版本、以及操作系统内部版本
cat /proc/version
# 查看系统内核版本、系统内部版本和使用架构
uname -a

系统硬件信息

1
2
3
4
5
6
7
8
9
10
11
12
# 查看 cpu 信息
lscpu
# 如果没有该命令,请使用下面的命令
cat /proc/cpuinfo

# 查看内存 -g 以G为单位,-m 以MB为单位
free -h

# 查看磁盘信息
df -h <path>
# 或者
fdisk -l

cpu 信息部分参数说明:

参数名 说明
processor 核心编号
model name cpu 信息
cpu MHz 频率
cache size 缓存大小
flags 支持的指令集

Linux 的磁盘分区方式为 a、b、c、d 这种格式。
其中 /dev/sda 代表一块磁盘(物理),/dev/sda1、/dev/sda2 代表该盘上的第一个、第二个分区;而 /dev/sdb 是另一块磁盘。
Linux 中磁盘的编号从 1 到 4 的分区是主分区,大于 5 的分区是逻辑分区。
/dev/sda,/dev/vda,/dev/hda:s 代表 SCSI,而 h 代表旧的IDE hard磁盘(已经淘汰了),vda 是使用虚拟化感知磁盘驱动程序的磁盘,性能应该要好得多,因为虚拟机管理程序不必模拟某些硬件接口。
参考:https://unix.stackexchange.com/questions/145332/difference-between-sdx-and-vdx

tree

选项 说明
-a 显示所有文件和目录。
-A 使用ASNI绘图字符显示树状图而非以ASCII字符组合。
-C 对输出的文件和目录清单加上色彩,便于区分各种类型。
-d 显示目录名称而非内容。
-D 列出文件或目录的更改时间。
-f 在每个文件或目录之前,显示完整的相对路径名称。
-F 在执行文件,目录,Socket,符号连接,管道名称名称,各自加上"*“,”/“,”=“,”@“,”|"号。
-g 列出文件或目录的所属群组名称,没有对应的名称时,则显示群组识别码。
-i 不以阶梯状列出文件或目录名称。
-I 过滤不展示哪些文件
-L level 限制目录显示层级。
-l 如遇到性质为符号连接的目录,直接列出该连接所指向的原始目录。
-n 不在文件和目录清单加上色彩。
-N 直接列出文件和目录名称,包括控制字符。
-p 列出权限标示。
-P <范本样式> 只显示符合范本样式的文件或目录名称。
-q 用"?"号取代控制字符,列出文件和目录名称。
-s 列出文件或目录大小。
-t 用文件和目录的更改时间排序。
-u 列出文件或目录的拥有者名称,没有对应的名称时,则显示用户识别码。
-x 将范围局限在现行的文件系统中,若指定目录下的某些子目录,其存放于另一个文件系统上,则将该子目录予以排除在寻找范围外。

举个例子,显示除了 node_modules 以外的目录,其中目录层级为 2,更深层级的目录不显示:

1
tree -I node_modules -dL 2

node_modules 后面不能添加 /

其它命令

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
# 查看系统用户名称
hostname

# 按照时间降序并获取前 5 个文件
ls -lt [path] | head -5

# 实时监听文件输出
tail -f [filename]

# 获取文件最后 num 行记录
tail -n num [filename]

# 查看活动用户
w
# 查看用户登录日志
last
# 查看系统所有用户
cut -d: -f1 /etc/passwd
# 查看系统所有组
cut -d: -f1 /etc/group

# 创建链接文件
# -s 创建软链接,相当于 win 下的快捷方式,不加 -s 选项为硬链接。
ln -s 源文件 新的链接文件名

# 查看进程
ps -ef
ps -aux

# 挂载、卸载设备
mount 设备 挂载目录
umount 设备 挂载目录

四、Linux 常用软件

VIM

命令 说明
yy 复制光标所在行;
nyy 复制光标所在行开始的 n 行,n 代表数字;
p 粘贴复制的内容
dd 删除光标所在行;
ndd 删除光标所在行开始的 n 行,n代表数字;
i 在当前光标所在处后进行编辑
o 在当前光标所在行的下一行新开一行进行编辑
O 在光标当前所在行的上一行新开一行插入
gg 让光标移动到文件首(第一行的第一个非空白字符处)
G 使光标移动到文件尾(最后一行的第一个非空白字符)
u undo,取消上一步操作
Ctrl + r redo,回到 undo 之前
set nu/nonu 显示/不显示行号
ggdG 清空所有内容
:wq 保存并退出,:xShift+zz具有同样效果
:q! 强制退出

VI 和 Vim 的键盘输入有所不同,推荐使用 Vim,服务器等一些最小安装的版本一般需要手动安装 Vim。

cURL

选项 说明
-X 指定请求方式:GET、POST 等。
-H、–header 指定请求头
-d、–data 指定请求体
-O 下载文件
-C - -O 断点续传

另外还有一个工具:wget,如果你想了解一下 wget VS curl 的区别:可以阅读这篇文章:https://www.geeksforgeeks.org/difference-between-wget-vs-curl/

1
2
3
4
# 查看本机基础信息
curl ipinfo.io
# 本机公网
curl cip.cc

SSH

现在大部分的 Linux 发行版都含有 SSH 服务和客户端,这里只是提一下。

sshd:Unix/Linux 上的 SSH 服务器
sshd_config:Unix/Linux 上的服务器配置文件
ssh_config:Unix/Linux 上的客户端配置文件

iproute2

第二代网络工具,相比于 net-tools,命令更加完整一致。

1
2
3
4
5
6
7
# 本机 IP
ip addr
ip addr show ens33

ip link | ip link show [name] | ip route | ip route show [name]
# 路由规则
ip rule show

五、tar 包常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 打包
tar -cvf /usr/local/ xxx.tar.xx

# 查看包内容
tar -tvf xxx.tar

# 解包内容
tar -xvf xxx.tar

# 以下格式的包只需要在选项中加入以下字母即可
# 例如 tar -zxvf xxx.tar.gz
# gzip(.tar.gz结尾的包)
-z

# bzip2(.tar.bz2结尾的包)
-j

# xz(以.tar.xz结尾的包)
-J

# -C 可以在解压的时候指定解压路径
tar -C 指定路径 -zvxf 目标包文件

参数:
-v 显示详细处理信息
-f 指定归档包文件,后面必须跟 tar 包相关文件 xxx.tar.gz

六、任务计划(Crontab)命令

1
2
# 查看当前用户的计划任务服务
crontab -l
定时任务说明
定时任务说明

在以上各个字段中,还可以使用以下特殊字符:

符号 含义
* 代表所有的取值范围内的数字,如月份字段为*,则表示1到12个月;
/ 代表每一定时间间隔的意思,如分钟字段为 */10,表示每10分钟执行1次。
- 代表从某个区间范围,是闭区间。如“2-5”表示“2,3,4,5”,小时字段中0-23/2表示在0~23点范围内每2个小时执行一次。
, 分散的数字(不一定连续),如1,2,3,4,7,9。

crontab注意点:
由于各个地方每周第一天不一样,因此Sunday=0(第一天)或Sunday=7(最后1天)。
crontab 有2种编辑方式:直接编辑 /etc/crontab 文件与 crontab –e,其中 /etc/crontab 里的计划任务是系统中的计划任务,而用户的计划任务需要通过 crontab –e 来编辑;每次编辑完某个用户的cron设置后,cron自动在 /var/spool/cron 下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用 crontab -e 来编辑。
crontab 中的 command 尽量使用绝对路径,否则会经常因为路径错误导致任务无法执行。
新创建的cron job 不会马上执行,至少要等2分钟才能执行,可重启cron来立即执行。
% 在 crontab 文件中表示“换行”,因此假如脚本或命令含有%,需要使用 \\% 来进行转义。

Crontab配置实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#每一分钟执行一次command(因cron默认每1分钟扫描一次,因此全为*即可)
* * * * * command

#每小时的第3和第15分钟执行command
3,15 * * * * command

# 每天上午8-11点的第3和15分钟执行command:
3,15 8-11 * * * command

# 每隔2天的上午8-11点的第3和15分钟执行command:
3,15 8-11 */2 * * command

# 每个星期一的上午8点到11点的第3和第15分钟执行command
3,15 8-11 * * 1 command

# 每晚的21:30重启smb
30 21 * * * /etc/init.d/smb restart

# 每月1、10、22日的4 : 45重启smb
45 4 1,10,22 * * /etc/init.d/smb restart

七、Shell

https://www.geeksforgeeks.org/how-to-create-a-shell-script-in-linux/
https://www.geeksforgeeks.org/conditional-statements-shell-script

Linux中有许多可用的Shell,例如The bourne shell(sh),The Korn Shell(ksh)和 GNU Bourne-Again Shell(bash)。为 sh shell 编写的脚本称为 shell 脚本,它们可以由 ksh 和 bash shell 解释。ksh 和 Bash 是原始 sh shell 的改进版本,它们比 sh 具有更多的功能。Bash 通常是大多数 Linux 发行版中的默认 shell,专门为 bash shell 编写的脚本称为 bash 脚本。

您可以指定脚本将使用哪个 shell,即使脚本是从另一个 shell 终端执行的。为此,请在脚本文件顶部添加“#!”,后跟所选 shell 的绝对路径。要将 bash 指定为解释器,请在 shell 脚本顶部添加以下行。

1
#!/bin/bash

1. 整数比较

操作符 描述
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于

2. 字符串比较

操作符 描述
== 等于
!= 不等于
< 小于,按 ASCII 字母顺序排列
> 大于,按 ASCII 字母顺序排列

<> 之前添加一个 \,因为它们在 [ ] 结构中键入时需要转义。

3. 几个内置的 shell 变量

参数 说明
$? 每当命令结束并将控件返回到父进程时,它都会返回介于 0 和 255 之间的退出代码。退出代码 0 表示命令成功,任何其他退出代码表示命令不成功。
$# 传递到脚本的参数个数。
$* 以一个单字符串显示所有向脚本传递的参数。如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号。
$- 显示Shell使用的当前选项,与set命令功能相同。

在 shell 中,有 [][[]] 两种条件测试表达式,它们有一些区别:

  1. [] 是 shell 自带的 test 命令的一种表现形式,而 [[ ]] 可以看作是内建的测试功能,是相对于传统的 test 命令的扩展强化版本。
  2. [] 只是指针对常规的字符串匹配和文件匹配的,[[ ]] 支持字符串、文件、模式匹配、类型匹配等。
  3. [] 中的变量在没有使用双引号包括时会被扩展和分割,而在 [[ ]] 中不会发生这种情况。
  4. [] 中,|| 和 && 代表或和和逻辑运算,而 [[ ]] 中,还有两个额外的操作符:<> 可用于字符串比较和整数比较。
  5. [] 支持一些正则表达式的特殊字符,[[ ]] 支持更多的扩展的正则表达式特性。

因为 [[ ]] 支持的东西更多更强大,建议优先使用 [[ ]] 语法。但需要注意,[[ ]] 只在 bash 及其衍生版本支持,像 sh,dash 等不支持。

比如寻找文件名是否以某个后缀结尾,可以使用以下语法:

1
2
3
4
5
if [[ $filename =~ \.zip$ ]];then
echo "文件以 zip 结尾"
else
echo "文件不以 zip 结尾"
fi

4. 循环语法

1. for 循环语句

运算时使用 let

1
2
3
4
5
6
7
8
9
10
11
for 条件
do
语句块
done
其中:
for ad in 1 2 3 4
for ab in `seq 1 4`
for ((ab = 1; ab < 4; ab++))
这三种写法的意思都是相同的,需要特别注意的是,
第二行那个符号不是单引号,而是 Tab 上面,Esc 下面的那个键。因为使用的时候不容易看懂,不推荐使用。
推荐第三种写法,注意有两个括号。

2. while 循环语句

1
2
3
4
while 条件
do
语句块
done

3. until 循环语句

和while循环同样,不同的是判断循环的条件,while条件为真时循环,until 条件为假时循环。
1
2
3
4
until 条件
do
语句块
done

4. 判断语法

shell 脚本的判断语句使用中括号,两端需要加入空格。比如下面这段代码(文件名为:test.sh):

test.sh
1
2
3
4
5
6
7
#!/bin/bash

if [ 1 -ge 2 ];then
echo "yes"
else
echo "no"
fi

在 [ 和 ] 之前键入一个空格,同时指定要检查的条件,否则会出现错误。

1
./test.sh: line 3: [1: command not found

5. 脚本示例

如果你的脚本是在 Window 下写完上传到 Linux 中的,那么文件的换行符可能有问题,可以使用以下命令进行转换:

1
2
3
# 两个命令二选一
tr -d '\r' < 文件名 > 新文件名
sed -i 's/\r//g' 文件名

Linux 换行符是 \n(LF),Windows 是 \r\n(CRLF).

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
#!/bin/bash

# 使用超级管理员的命令需要输入密码,这里先输入一下,yourpassword 替换为超级管理员的密码
sudo -S -v << EOF
yourpassword
EOF

echo -n "请输入创建的文件夹:"
read name

if [ ! -d "$name" ];then
echo "$name 文件夹不存在,正在创建"
sudo mkdir /$name
else
echo "/$name 文件夹已存在"

sudo mkdir /$name/test

if [ $? eq 0 ];then
echo "文件夹创建成功"
else
echo "创建失败"

sudo touch /$name/test/111.txt
# 对文件写入内容
echo "自古星耀晦明时,不持太阿误剑诗" | tee /$name/test/111.txt
# -a 追加内容
echo "无边落木萧萧下,不尽长江滚滚滚来" | tee -a /$name/test/111.txt

Shell 脚本对 bash 中的 > 或者 >> 有不同的处理,如果 shell 中使用这种方式将会报错;

因此这里使用了 tee 命令来进行文本输入追加。

附:Linux 其它知识

KDE、Gnome、Xfce

如果要决定使用 Linux 作为日常使用的话,你可能还需要知道 Plasma(KDE)、Gnome、Xfce、x11、Wayland。

本文不会过多讲解,只是简单提一下。Plasma、Gnome、Xfce 是不同的桌面系统,例如 Plasma 类似 Windows 桌面,Gnome 类似 MacOS 桌面,这三者对于系统资源的占用、以及各自的可定制化均有不同;而 x11、Wayland 是开发桌面系统的协议,由于 x11 过于古老,出现了很多缺点,且基本不再维护了,2008 年诞生了 Wayland,越来越多的软件、Linux 系统积极拥抱 Wayland。但是目前来看,Wayland 彻底取代 x11 还有很长的路要走。一方面,是 Wayland 自身的问题,很多功能还没有完善、有一定的缺陷;另一方面 x11 应用还有 x11 与 Wayland 混合应用还有很多,为了兼容这些应用,允许 x11 与 Wayland 共存:Xwayland,系统会自动切换。最好一个阻力就是显卡驱动了。

Plasma 又称 KDE,定制化程度最高,而 Gnome 比较现代,主张开箱即用,定制化选项较少,Xfce 号称占用资源最少,不过这一项优点除非是老机器否则参考价值不大,这三种桌面系统各有千秋,推荐每一种都试试选择自己最喜欢的。

初始化程序

Linux 系统使用不同的 init 系统来管理服务和守护进程。两个最常见的初始化系统是 systemd 和 SysVinit。它们在系统中的 ID 为 1,表示初始化进程。Linux 自身的 ID 为 0。一旦启动,初始化过程将控制系统的启动。它读取配置文件,并根据配置文件中的配置状态启动所有其他服务和进程。

sysVinit 最初是为 UNIX 系统创建的,后来在 Linux 中进行了改编。在 RHEL5 之前,RedHat 将其用作其默认系统初始化程序。此后,他们切换到了 systemd。

SysVinit 以一种同步的方式加载服务,而不是在 systemd 中并行加载服务。并且只有在当前正在加载的服务超时后,才能加载下一个服务。

Systemd 是现代系统初始值设定项程序。大多数 Linux 开发人员,包括 RedHat(从版本 7 开始)和 Ubuntu(从版本 15.04 开始)都使用 systemd 作为默认的系统初始值设定项程序。它提供了一套全面的工具和功能来管理服务,包括并行启动、按需激活和依赖项管理。

使用以下命令查看,输出结果为 init 的就是使用的 sysVinit。

1
ps -p 1 -o comm=
Systemd Sysvinit
systemctl start service_name service service_name start
systemctl stop service_name service service_name stop
systemctl restart service_name service service_name restart
systemctl status service_name service service_name status
systemctl enable service_name chkconfig service_name on
systemctl disable service_name chkconfig service_name off

更多命令请参考:https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet

防火墙

Linux 系统通常通过防火墙直接或间接连接到互联网,但 Linux 本身也内置了防火墙。该防火墙在不断开发和升级,并且配置起来并不总是那么容易。为此,创建了 firewalld 作为管理整个防火墙的统一方式。

Linux 2.0 附带了 ipfwadm,在 Linux 2.2 中被 ipchains 取代。在 Linux 2.4 中,ipchains 被 iptables 取代。几年来,已经开始用 nftables 替换 iptables,以提供更灵活、更强大的防火墙。使用 nftables 可以动态配置防火墙,并且应该能够在具有 10 Gbps 或更多网络带宽的环境中工作。

一般,早期的基于 sysVinit 的 Linux 发行版使用 iptables,而使用 systemd 的 Linux 发行版使用 firewalld。

firewalld 防火墙功能强大,设置起来也非常简单。在底层,Linux 防火墙依赖于 netfilter,即系统内核端网络过滤框架。在用户侧,我们可以选择与 netfilter 交互的工具,例如 iptables、ufw 这些简单的防火墙和 firewalld。

Firewalld 与 iptables 不兼容,不应一起使用。同时运行这两个服务会弄乱防火墙。无论您选择哪种服务,都可以禁用并屏蔽其他服务。

有三种 iptables 服务:

  • 用于 IPv4 配置的 iptables
  • 用于 IPv6 配置的 ip6tables
  • 用于软件桥接的 ebtables
1
2
3
systemctl disable iptables
systemctl disable ip6tables
systemctl disable ebtables

多用户环境中,其它用户可能会有意或无意重启 iptables。因此,我们可以屏蔽它,屏蔽的服务无法手动或自动启动:

1
2
3
systemctl mask iptables
systemctl mask ip6tables
systemctl mask ebtables

如果刚刚禁用了活动的 iptables 服务并尝试启用 firewalld 服务,那么 firewalld 服务可能无法启动。从 iptables 切换到 firewalld 需要重新启动系统,然后启动 firewalld 服务。


本站由 江湖浪子 使用 Stellar 1.29.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。