Linux 学习笔记

Linux笔记

基础命令

  • 创建多个嵌套目录

    mkdir -p a/b/c
  • 查看嵌套目录

    ls -R ./

    ls -h会显示文件的大小

  • 复制文件保留元信息(复制文件默认会修改文件的元信息)

    cp -a a b
  • 通配符,只匹配一个字符

    ls a?
    # 会匹配ab 不会匹配abc
  • 打包文件,解包文件

    # 打包文件
    tar cf xxx.tar /a
    
    # 解包文件
    tar xf xxx.tar -C /a

    将a目录下的文件打包成xxx.tar文件,f表示打包成文件

    tar命令的参数是不带-

  • 压缩文件,解压文件

    # gzip压缩文件,打包文件加压缩
    tar czf xxx.tar.gz /a
    
    #解压文件
    tar xzf xxx.tar.gz -C /a
    
    # bzip2压缩文件,打包文件加压缩
    tar cjf xxx.tar.bz2 /a
    
    #解压文件
    tar xjf xx.tar.gz _v /a

    bzip2压缩的文件方式要比gzip小,压缩比例更高

vim

进入插入模式:

-i:当前位置进入插入模式

-I:跳转到行前进入插入模式

-a:跳转到下一个字符进入插入模式

-A:跳转到行尾进入插入模式

-o:下一行进入插入模式

-O:上一行进入插入模式

命令行模式

!:可以执行linux命令

:s/a/b:对当前行进行替换

:%s/a/b/g:对所有符合条件的内容进行替换

:10,25s/a.b/g:对10-25行中的内容进行替换

可视模式

v:字符可视模式

V:行可视模式

^+v:块可视模式

I:可以在快模式下编辑多行,编辑完后按两下esc键,修改就会同步到其他行

d:在快模式下,删除多行选中的字符

复制

yy:复制正行

n yy:复制n行

y$:从当前字符复制到行尾

p:粘贴

剪切

dd:剪切整行

n dd:剪切n行

d$:剪切当前字符到行尾

撤销

u:撤销

^+r:反向撤销

替换

r:替换单个字符

x:删除单个字符

跳转到指定行

n G:跳转到第n行

gg:跳转到第一行

G:跳转到最后一行

$:跳转到该行的行尾

^:跳转到该行的行首

用户管理

添加用户(需要在root用户下执行,其他普通用户无法创建用户)

# 不会创建用户目录、设定密码等
useradd abc

# 会创建用户目录、设定密码等
adduser abc

设置密码

passwd abc

查看某一个用户是否存在

id abc
# uid=0(root) gid=0(root) groups=0(root),113(docker)

添加用户会进过那些操作

  1. 会在/etc/passwd中添加用户

    cat /etc/passwd
    # abc:x:1002:1002::/home/abc:/bin/sh
  2. 会在/etc/shadow中添加用户

    cat /etc/shadow
    # abc:!:18510:0:99999:7:::

删除用户

# 不会删除用户目录
userdel abc

# 删除用户目录
userdel -r abc

修改用户属性

修改用户目录

usermod -d /home/dd abc

修改用户所属的组

usermod -g group1 abc

新建用户组

groupadd group1

切换用户

su - abc

-表示完全切换,会切换到该用户的目录下,如果没有-则还会在当前目录

给特定用户执行某些命令的权限

visudo

用上面的命令可以给某些用户赋予某些命令的权限

/etc/passwd文件解析

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

# 用户名/用户是否需要密码进行验证/uid/gid/注释/用户目录/命令解释器
# sbin/nologin 是不能被登录的

在新建用户时可以不用adduser命令,直接编辑该文件也可以起到新增用户的目的

/etc/shadow 文件解析(用来保存用户和密码的关系)

mysql:!:18493424:0:99999:7:::
user1:$6$9JTohwDk$baTsdfsVJRRfSds6PCdF0xBQlqslTekjWK9xT7/yIoTTUv45raWwtZRpwtMn5mNwjULCvL2XRJ9Nj3kFhekJBsjgBfq.:18511:0:99999:7:::

# 用户名/加密后的密码

# 相同的密码加密后是不同的

/etc/group 文件解析(用户组文件)

mysql:x:116:
user1:x:1002:

# 用户组名称/是否需要密码/gid/其他组设置(一个用户可以属于多个组)

文件权限

文件权限格式

ls -l

-rwx------+   8 xx  staff      256 Mar  6  2020 Movies
drwx------+  10 xx  staff      320 Mar  6  2020 Music

# 第一位,表示文件类型
# 后面接着的9位 rwx------ 表示权限,每三个字符为一组,分别表示:用户对该文件的权限、该组对文件的权限和其他用户的权限
# xx :用户
# staff: 用户组

文件类型

-:普通文件

d:目录文件

b:块特殊文件

c:字符特殊文件

l:符号链接

f:命令管道

s:套接字文件

文件权限的表示方法

数字权限的表示方法

r=4

w=2

x=1

目录权限的表示方法

x:可以进入目录

rx:显示目录内的文件名

wx:修改目录内的文件名

修改文件属主和属组的方法

修改属主

chown user1 /test

修改属组

chgrp :user1 /test

修改权限

u:属主

g:属组

o:其他用户

a:包括上述三种

+:增加权限

-:减少权限

=:设置权限

# 为test的属主设置w权限
chmod u+w ./test

# 为属主、属组合其他用户设置只有wr权限
chmod a=wr ./test

linux中默认的文件权限是644,是666-umask(022)=644,既rw-r--r--

如果属主权限和属组权限冲突,则以属主权限为主

特殊权限

SUID:用户可执行的二进制文件,执行命令时获取文件属主的权限

root@master:~# ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 59640 Mar 23  2019 /usr/bin/passwd

SGID:用于目录,在该目录下新建的文件和目录,权限自动更改为该目录的属组,常用于共享文件

SBIT:用户目录,在该目录下新建的文件和目录,只有root和自己可以删除

ls -l /
drwxrwxrwt  13 root root       4096 Sep  7 18:21 tmp

网络管理

网络状态查看工具

  1. net-tools(centos 7 之前推荐的工具)

    • ifconfig
    • route
    • netstat
    ifconfig
    • eth0 第一块网卡(根据网卡接入方式不同,名称也会不同)
  2. iproute2(centos 7 之后推荐的工具)

    • ip
    • ss

修改网卡名称为eth0

网卡命名规则受biosdevnamenet.ifnames两个参数影响

  1. 编辑etc/default/grub文件,增加biosdevname=0net.ifnames=0

    GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"
  2. 更新grub

    grub2-mkconfig -o /boot/grub2/grub.cfg
  3. 重启(reboot)

查看网卡物理连接情况

mii-tool eth0

查看网关

route -n

使用-n参数不解析主机名

网络故障排除命令

ping:网络主机是否畅通

traceroute:如果网络通畅,但是还是访问不通,可以通过该命令查看路由信息

mtr:如果网络主机通畅,但是还是访问不通,可以查看是否有数据包丢失了

nslookup:查看域名对应的ip

telnet:如果主机没有问题,可以查看端口是否开放

tcpdump:如果主机和端口都ok,则需要抓包进行分析

netstatss:检测服务监听的地址是否正确

网络服务管理(centos)

可以分为两种:SysVsystemd

网络配置文件:ifcfg-eth0,会随着网卡的不同文件名也会不同

比如/etc/sysconfig/network-scripts/ifcfg-ens3,在这个里面可以配置dhcp,ip等信息

进程管理

调整优先级

nice:范围从-20到19,值越小优先级越高,抢占的资源就越多

renice:重新设置优先级

# 在启动前设置某一个程序的优先级
nice -n 10 ./a.sh

# 在程序启动后重新设置一个程序的优先级
renice -n 15 pid

进程的作业控制

&:将任务放到后台执行

./a.bash &

jobs:查看后台任务

jobs

将前台任务停止并放到后台

ctrl + z

将后台任务放到前台执行

fg jobsID

将前台任务放到后台执行

bg jobsID

进程间通信

查看信号

[root@848e7f64efd8 /]# 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

常用信号

ctrl + == SIGINT

# 立即终止,不收阻塞,信号是SIGKILL
kill -9 pid

守护进程(daemon)

让程序脱离当前终端执行:

  1. nohup
  2. 守护进程
  3. screen或者tmux

nohup可以让一个命令脱离终端执行,但他不是守护进程

随着系统启动而启动,不用用户手动的去执行

每个进程的依赖的环境都在/proc/pid的文件夹中

cd /proc/123

# 进程执行的位置
ls -l cwd

# out
 cwd -> /

# 进程的输出
ls -l fd

# out
lrwx------ 1 root root 64 Sep 14 05:15 0 -> /dev/pts/4
lrwx------ 1 root root 64 Sep 14 05:15 1 -> /dev/pts/4
lrwx------ 1 root root 64 Sep 14 05:15 2 -> /dev/pts/4
lrwx------ 1 root root 64 Sep 14 12:32 255 -> /dev/pts/4

# 0是标准输入
# 1,2是标准输出

服务管理工具-systemctl

常用操作:

systemctl start|stop|restart|reload|enable|disable 服务名称

SELinux

安全增强版本的Linux,以前的linux是利用用户和文件的权限来进行安全控制既DAC(自主访问控制)

MAC(强制访问控制):会给用户、进程和文件都打上标签,如果三者标签不一致则不允许执行

SElinux是一个内核模块,也是Linux的一个安全子系统。SELinux可是设置DAC或者是MAC。需要注意的是开启SELinux会消耗服务器的性能,所以一般在生产环境下都是关闭的

# 查看SELinux状态
getenforce

内存和磁盘管理

内存和磁盘使用率查看

内存:

  • free

    [root@hadoop3 ~]# free -m
                  total        used        free      shared  buff/cache   available
    Mem:          64264       51686        2089         140       10488       11807
    Swap:             0           0           0
    [root@hadoop3 ~]# free -g
                  total        used        free      shared  buff/cache   available
    Mem:             62          50           2           0          10          11
    Swap:             0           0           0
  • top

磁盘:

  • fdisk

    [root@hadoop3 ~]# fdisk -l
    
    Disk /dev/vda: 53.7 GB, 53687091200 bytes, 104857600 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk label type: dos
    Disk identifier: 0x0009ac89
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/vda1   *        2048   104857566    52427759+  83  Linux
    
    Disk /dev/vdb: 214.7 GB, 214748364800 bytes, 419430400 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes

    如上图所示,共有两个磁盘:/dev/vda、/dev/vdb

    其中/dev/vda是分区了,因为有/dev/vda1

  • df

    df -h
    
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/vda1        50G   16G   32G  34% /
    devtmpfs         32G     0   32G   0% /dev
    tmpfs            32G   24K   32G   1% /dev/shm
    tmpfs            32G  1.5M   32G   1% /run
    tmpfs            32G     0   32G   0% /sys/fs/cgroup
    /dev/vdb        197G   55G  134G  29% /data
    tmpfs           6.3G     0  6.3G   0% /run/user/0

    常常用来查看磁盘是否满了

  • du

    [root@hadoop3 elasticsearch]# du -h docker-compose.yaml
    4.0K    docker-compose.yaml

    du -hls -lh区别是,du是实际占用的空间,而ls -lh是包含空洞空间的,其中磁盘有些位置是空的,只是声明了文件存储的位置,并没有实际存储数据

Linux文件系统管理

Linux常见的文件系统:

  • ext4
  • xfs
  • NTFS(需要安全额外的软件)

硬链接

多个文件其实都是链接到同一个数据块,修改一个文件,其余的文件都会同步变化。

硬链接是不允许跨文件系统的。

创建硬链接的方式:ln afile bfile

[root@VM-0-16-centos test]# cat base
aaaa
[root@VM-0-16-centos test]# ln base yin
[root@VM-0-16-centos test]# ls -li
# inode号是相同的,他们指向同一个inode块
131106 -rw-r--r-- 2 root root 5 Nov 25 09:56 base
131106 -rw-r--r-- 2 root root 5 Nov 25 09:56 yin
[root@VM-0-16-centos test]# rm base
rm: remove regular file ‘base’? y
[root@VM-0-16-centos test]# cat yin
aaaa

软链接

克服了硬链接不能跨文件系统的问题。

但是实现上是不同的,软链接是创建了完全不同的一个文件,当系统读取这个文件时会发现这个文件是个链接文件,所以就会读取它链接的那个原文件。

对软链接文件设置权限并不会改变该文件的权限,而是改变的是原文件。

创建软链接的方式:ln -s afile bfile

[root@VM-0-16-centos test]# cat base
aaaa
[root@VM-0-16-centos test]# ln -s base ruan
[root@VM-0-16-centos test]# ls -li
# inode号不同
131103 -rw-r--r-- 1 root root 5 Nov 25 09:59 base
131104 lrwxrwxrwx 1 root root 4 Nov 25 10:00 ruan -> base
[root@VM-0-16-centos test]# cat ruan
aaaa
[root@VM-0-16-centos test]# rm base
[root@VM-0-16-centos test]# ls -li
total 0
131104 lrwxrwxrwx 1 root root 4 Nov 25 10:00 ruan -> base
[root@VM-0-16-centos test]# cat ruan
# 当删除了原始文件,因为软连接是指向的原始文件,并没有指向inode号,所以访问不到原始文件
cat: ruan: No such file or directory
[root@VM-0-16-centos test]# echo dddd >> ruan
[root@VM-0-16-centos test]# ls -li
# 向软连接里写内容,就相当于在原始文件里写内容,所以原始文件就重新出现了
131103 -rw-r--r-- 1 root root 5 Nov 25 10:00 base
131104 lrwxrwxrwx 1 root root 4 Nov 25 10:00 ruan -> base
[root@VM-0-16-centos test]# cat base
dddd

硬盘分区与挂载

硬盘分区:fdisk /dev/vdb,如果是2T以上的硬盘需要用parted命令

格式化设置分区文件系统:mkfs.文件系统 /dev/vdb

分区挂载到目录下:mount /dev/vdb /xx

这样挂载只是将数据写到了内存中,如果想要重启后还是挂载到该目录,需要修改文件 /etc/fstab

root@max-master:~# cat /etc/fstab
UUID=e1d5f0dc-9df2-421e-a87b-f761f5db8947 / ext4 defaults 0 0
###/swap.img    none    swap    sw    0    0
max-master:gfs-configs    /var/cache/zoomeye-max    glusterfs    defaults,_netdev    0    0
/dev/vdb1 /xx ext4 defaults 0 0

Shell 编程

Shell 脚本的不同运行方式

内建命令不需要创建子进程

内建命令对当前shell生效

bash 1.sh
# 不用给1.sh赋予执行权限,bash脚本执行完后会回到当前目录
# 会产生新的子进程

./1.sh
# 必须要可执行权限,bash脚本执行完后会回到当前目录
# 会产生新的子进程

source 1.sh 和 . 1.sh
# 必须要可执行权限,bash脚本执行完后不会回到当前目录
# 不会创建新的子进程

管道与重定向

管道和信号是一样的,也是进程通信的方式之一

# 输入重定向
<

# 输出重定向
>

# 追加模式
>>

# 将a.txt文件内容赋值给变量ss
read ss < a.txt

# 将ss变量内容写入到文件中
echo $ss > a.txt

# 将ss变量内容追加到文件中
echo $ss >> a.txt

# 将错误信息重定向到文件中
xxx 2> a.txt

# 将输出信息全部重定向到文件中
xxx &> a.txt

变量的赋值

shell中不区分变量类型

变量复制等号两边不允许有空格

将命令的值赋值给变量,使用$()和````

a=$(ls -l /etc)

变量的作用范围

声明的变量只在当前的shell中生效,在子进程、父进程和bash xx.sh中都是不生效的,要想使得变量在bash xx.sh中生效,需要执行source xx.sh或者. xx.sh,因为这两种方式都不会创建新的子进程

使用export xx,可以使该变量在子进程中可用

使用unset xx,删除变量

环境变量、预定义变量和位置变量

  • 环境变量:每个shell打开都可以获取到的变量
    • env:查看环境变量
    • set:查看环境变量、预定义变量和位置变量
    • PATH:该变量定义了命令查找的路径,我们需要添加路径时可以PATH=$PATH:xx,该变量修改后可以在子进程和别的shell中生效,因为被export了
    • PS1:设置shell中提示
  • 预定义变量
    • $?:上一条命令是否执行成功,成功的话返回0
    • $$:返回当前shell的PID
    • $0:当前执行的程序
  • 位置变量
    • $1….$n:特别注意的是当大于等于10时,必须要写成${10}...${xx}
    • 如果想要给位置变量设置默认值可以用${1-xx}xx就是设置的默认值

环境变量配置文件

所有用户都可用的环境变量保存在:

  • /etc/profile
  • /etc/profile.d
  • /etc/bashrc

用户自定义的环境变量:

  • ~/.bashrc
  • ~/.bash_profile

数组

  • 定义数组
    • IPTS=(1 2 3 4)
  • 显示所有元素
    • echo ${IPTS[@]}
  • 显示长度
    • echo ${#IPTS[@]}
  • 获取第一个元素
    • echo ${IPTS[0]}

转义与引用

注意:单引号`是不对特殊字符进行解释,双引号”会对特殊字符进行解释

echo '$a'
$aecho "$a"
1

反引号`可以获取命令执行的结果

➜ num1=`expr 4 + 5`echo $num1
9

运算符

  • 复制运算符
  • 算数运算符
    • expr 4 + 5:只能支持整数
    • ((4+5)),((a=9)),((a++)):是let的简化方式

特殊符号大全

  • $()和反引号的作用一样,里面包含需要执行的命令

  • ()会创建一个新的shell

  • []test命令的简写

    [[ 5 < 4 ]]echo $?
    1
  • {}输出范围和快速操作

    echo {0..9}
    0 1 2 3 4 5 6 7 8 9
    
    # mv 1.sh 1.sh.bakmv 1.sh{,.bak}
  • ;会确保上一条命令执行完在执行下一条

  • :类似于python中的pass

test命令

  • 退出程序命令
    • exit:会返回上一条命令的成功与否
    • exit 10:返回值10,非0则是不正常退出
  • test命令可以用来检查文件或者比较值
    • test可以做一下测试
      • 文件测试
      • 整数比较测试
      • 字符串测试
    • test测试语句可以简化为[]符号
    • []还有扩展写法[[]]支持&&、||等

if else

if [[ "$1" == "start" ]] ; then
    echo "$0 start..."
elif [[ "$1" == "stop" ]] ; then
    echo "$0 stop..."
else
    echo "Usage: $0 {start|stop}"
fi

case

case "$1" in 
    "start" | "START")
        echo "$0 start..."
    ;;

    "stop")
        echo "$0 stop..."
    ;;

    *)
        echo "Usage: $0 {start|stop}"
    ;;
esac

for

#!/bin/bash

for filename in $(ls *.mp3) ; do
    mv $filename $(basename $filename .mp3).mp4
done

for (( i=1; i<=10; i++ )) ; do
    echo $i
done

while

#!/bin/bash

n=1
# [[ $n < 10 ]] 不能用于条件判断
while [  $n -lt 10 ]
do
    echo $n
    ((n++))

done

嵌套

#!/bin/bash

for filename in $(ls *.mp4) ; do
    if [ -x $filename ]; then
        echo $filename ; break
    fi
done

循环处理位置参数

$#:位置参数的数量

$*:所有的位置参数

$0:脚本名称

#!/bin/bash

# for
for args in $* ; do
    if [ "$args" = "help" ] ; then
        echo "$args" "$args"
    fi
done

# while
while [ "$#" -ge 1 ] ; do
    if [ "$1" = "help" ] ; then
        echo "$1" "$1"
    fi
    shift
done

自定义函数

local:声明函数内变量

#!/bin/bash

function checkpid() {
    local i

    for i in $* ; do
        [ -d "/proc/$i" ] && return 0
    done

    return 1
}

脚本控制

fork炸弹

.(){.|.&};.

普通用户创建的线程数是收到控制的,可以通过ulimit -a控制

捕获信号

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

trap "echo 15" 15

echo $$

while : ; do
    :
done

计划任务

单次任务用at,多次任务用crontab

文件加锁

# 加锁
flock -xn "/tmp/f.lock" -c "/tmp/1.sh"

# 另外一个地方执行该脚本时就会直接退出
flock -xn "/tmp/f.lock" -c "/tmp/1.sh"

文本操作

元字符

grep 后面可以接正则元字符

grep sdf.*$

find演示

find /etc -name pa*

find /etc -regex .*wd$

find *.txt -exec rm {} \;

Sed 替换

sed默认只替换每行的第一个

sed的基本工作方式:

  • 将文件按行读取到内存中
  • 使用sed的每个脚本对该行进行操作
  • 处理完成后输出改行
sed 'a/lod/new/' filename

# 如果要替换/,可以使用别的分隔符
sed 's!/!abc!' filename

# 执行多个命令
sed -e 's/a/aa/' -e 's/aa/bb/' afil
sed 's/a/aa/;s/aa/bb/' afile

# 将替换后的内容写入到原始文件
sed -i 's/a/aa/;s/aa/bb/' afile

# 支持元字符
head -5 /etc/passwd | sed 's/s*bin//'

# 支持回调,源文件内容:axyzb
# 扩展元字符使用 -r 参数
root@4ebe31ff7a18:/tmp# sed -r 's/(a.*b)/\1:\1/' cfile
axyzb:axyzb

sed替换指令加强版

标志位

s/old/new/标志位

# 全局替换
s/old/new/g

# 替换前两次
s/old/new/2

# 只输出替换成功的行, -n 不输出行, p 输出替换成功的行
sed -n 's/root/123/p'

# 将替换成功的行写入别的文件
sed -n 's/root/123/w a.txt'

寻址

/正则表达式/s/old/new/g

行号s/old/new/g

# 从1-6行进行替换
head -6 /etc/passwd | sed '1,6s/games/!!!!!!!!/'

# 匹配root行,进行替换
head -6 /etc/passwd | sed '/root/s/bash/!!!!!!!!/'

# 多条命令
sed /正则/{s/old/new/;s/old/new/}

脚本文件

文件里写正常的sed命令

sed -f sedscript filename

sed的其他常用命令

# 删除行,删除操作会改变模式空间,就和管道的作用一样,后面的命令会以删除后的文件内容为准
sed '/ab/d' bfile
sed '/ab/d;=' bfile

# 在上一行插入
sed '/ab/i hello' bfile

# 在下一行插入
sed '/ab/a hello' bfile

# 替换行
sed '/ab/c hello' bfile

# 合并两个文件
sed '/ab/r cfile' bfile

# 下一行命令 n
# 打印行号 =

# 打印匹配行,这个替换中的p不同,通常和-n参数配合只打印匹配到的行
sed -n '/ab/p' bfile

# 退出命令
sed 10q filename # 不会把文件全部读入
sed -n 1,10p filename

sed多行模式

N:将下一行加入到模式空间中

D:删除模式空间中的第一个字符到第一个换行符

P:打印模式空间中第一个字符到第一个换行符

root@4ebe31ff7a18:/tmp# cat dfile
hel
lo
root@4ebe31ff7a18:/tmp# sed 'N;s/hel\nlo/!!!/' dfile
!!!
root@4ebe31ff7a18:/tmp# sed 'N;s/hel.lo/!!!/' dfile
!!!

# 多行操作
root@4ebe31ff7a18:/tmp# cat b.txt
hell
o bash hel
lo bash
# 两行连起来操作
root@4ebe31ff7a18:/tmp# sed 'N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt
hello sed
 hello sed
# 三行连起来操作
sed 'N;N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt 

sed保持空间

image-20201019133011333

hH将模式空间内容存放到保持空间

gG将保持空间内容取出到模式空间

x交换模式空间和保持空间内容

在保持空间中不能对数据进行操作,只能取到模式空间中才可以

小写是覆盖模式,大写是追加模式

# 倒序输出,可以使用tac命令
root@4ebe31ff7a18:/tmp# cat efile
1
2
3
4
5
root@4ebe31ff7a18:/tmp# sed -n '1h;G;x;$p' efile
4
3
2
1
1

# 解决第一行重复输出的问题,是因为第一行放入到保持空间后又拿了出来,修改为当第一次执行时不从保持空间取出来
root@4ebe31ff7a18:/tmp# sed -n '1h;1!G;x;$p' efile
4
3
2
1

# 解决最后一行没有输出的问题
root@4ebe31ff7a18:/tmp# sed -n '1h;1!G;$!x;$p' efile
5
4
3
2
1

# 另外的解决方法
root@4ebe31ff7a18:/tmp# sed -n '1!G;h;$p' efile
5
4
3
2
1

认识AWK

  • awk更像是脚本语言
  • awk用于比较规范的文本处理,用于统计数量并输出指定字段
  • sed将不规范的文本,处理为比较规范的文本

AWK的字段

  • 每行称作AWK的记录
  • 使用空格、制表符分隔开的单词成为字段
  • 可以自己制定分隔的字段
awk -F "''" '/^menu/{ print x++, $2 }' /boot/grub2/grub.cfg
  • -F:指定分隔符
  • x++:打印行号
  • ^menu:匹配行

AWK表达式

系统变量

  • FS表示输入的内容用什么分隔,OFS表示输出用什么符号分隔
  • RS行分隔符
  • NR打印行号,如果文件变化了NR是不会重新排号,FNR则会重新排号
  • NF字段的数量
# 下面两行意义相同,BEGIN表示在输入内容之前的操作
head -n 6 /etc/passwd | awk 'BEGIN{FS=":"}{print $1}'
head -n 6 /etc/passwd | awk -F ':' '{print $1}'

# 设置输出分隔符
head -n 6 /etc/passwd | awk 'BEGIN{FS=":";OFS="-"}{print $1,$2}

# 改变内容行的分隔符,改为通过:来换行,$0是输出一行
head -n 6 /etc/passwd | awk 'BEGIN{RS=":"}{print $0}'

# 打印行号
root@709230c0b366:~# awk '{print NR, $0}' /etc/hosts /etc/hosts
1 127.0.0.1    localhost
2 ::1    localhost ip6-localhost ip6-loopback
3 fe00::0    ip6-localnet
4 ff00::0    ip6-mcastprefix
5 ff02::1    ip6-allnodes
6 ff02::2    ip6-allrouters
7 172.17.0.4    709230c0b366
8 127.0.0.1    localhost
9 ::1    localhost ip6-localhost ip6-loopback
10 fe00::0    ip6-localnet
11 ff00::0    ip6-mcastprefix
12 ff02::1    ip6-allnodes
13 ff02::2    ip6-allrouters
14 172.17.0.4    709230c0b366
root@709230c0b366:~# awk '{print FNR, $0}' /etc/hosts /etc/hosts
1 127.0.0.1    localhost
2 ::1    localhost ip6-localhost ip6-loopback
3 fe00::0    ip6-localnet
4 ff00::0    ip6-mcastprefix
5 ff02::1    ip6-allnodes
6 ff02::2    ip6-allrouters
7 172.17.0.4    709230c0b366
1 127.0.0.1    localhost
2 ::1    localhost ip6-localhost ip6-loopback
3 fe00::0    ip6-localnet
4 ff00::0    ip6-mcastprefix
5 ff02::1    ip6-allnodes
6 ff02::2    ip6-allrouters
7 172.17.0.4    709230c0b366

# 打印有多少个字段
head -n 6 /etc/passwd | awk 'BEGIN{FS=":"}{print NF}'

# 打印最后一个字段的值
head -n 6 /etc/passwd | awk 'BEGIN{FS=":"}{print $NF}'

AWK的判断和循环

root@7dc8bb7d5702:/tmp# cat a.txt
user1 34 54 23 12
user2 94 34 73 22
user3 99 45 12 49
root@7dc8bb7d5702:/tmp# awk '{ if($2>80) {print $1,$2} }' a.txt
user2 94
user3 99
root@7dc8bb7d5702:/tmp# awk '{ for(c=2;c<=NF;c++) print $c }' a.txt
34
54
23
12
94
34
73
22
99
45
12
49
root@7dc8bb7d5702:/tmp# awk '{ for(c=2;c<=NF;c++) sum+=$c; print sum}' a.txt
123
346
551

AWK数组

# END表示数据读入完毕
root@7dc8bb7d5702:/tmp# awk '{ sum=0; for(c=2;c<=NF;c++) sum+=$c; average[$1]=sum/(NF-1) }END{ for( user in average ) print user,average[user] }' a.txt
user1 30.75
user2 55.75
user3 51.25
root@7dc8bb7d5702:/tmp# cat a.txt
user1 34 54 23 12
user2 94 34 73 22
user3 99 45 12 49
root@7dc8bb7d5702:/tmp# awk '{ sum=0; for(c=2;c<=NF;c++) sum+=$c; average[$1]=sum/(NF-1) }END{ for( user in average ) print user,average[user] }' a.txt
user1 30.75
user2 55.75
user3 51.25
root@7dc8bb7d5702:/tmp# awk '{ sum=0; for(c=2;c<=NF;c++) sum+=$c; average[$1]=sum/(NF-1) }END{ for( user in average ) sum2+=average[user]; print sum2/NR }' a.txt
45.9167

AWK数组的应用

root@7dc8bb7d5702:/tmp# cat a.txt
user1 34 54 23 12
user2 94 34 73 22
user3 99 45 12 49
root@7dc8bb7d5702:/tmp# cat result.awk
{
sum = 0
for(c = 2; c <= NF; c++)
    sum += $c

average[$1] = sum / (NF - 1)
print $1, average[$1]

}
END{
for(user in average)
    sum_all += average[user]

avg_all = sum_all / NR

for(user in average)
    if (average[user] > avg_all)
        above++
    else
        below++

print "above", above
print "below", below

}
root@7dc8bb7d5702:/tmp# awk -f result.awk a.txt
user1 30.75
user2 55.75
user3 51.25
above 2
below 1

AWK函数

# 整数
root@7dc8bb7d5702:/tmp# awk 'BEGIN{pi=3.114; print int(pi)}'
3

# 随机数
root@7dc8bb7d5702:/tmp# awk 'BEGIN{srand(); print rand()}'
0.739691
root@7dc8bb7d5702:/tmp# awk 'BEGIN{srand(); print rand()}'
0.00276686
root@7dc8bb7d5702:/tmp# awk 'BEGIN{srand(); print rand()}'
0.134305

# 自定义函数
root@7dc8bb7d5702:/tmp# awk 'function double(str) {return str str} BEGIN{print double("hello")}'
hellohello

服务管理

防火墙概述

  • 软件防火墙,主要用来限制ip,过滤一些ip等
    • 包过滤防火墙,比如控制ip,iptables就是包过滤防火墙
    • 应用层防火墙,比如根据系统用户来控制
  • 硬件防火墙,用来放dos攻击等,也兼顾一些软件防火墙的功能

Centos 6默认使用的防火墙是iptables,Centos 7 是firewallD,但这两者底层都是内核中的netfilter来进行实际的控制

iptables的表和链

  • 规则表
    * filter,用来过滤
    * nat,地址空间转换
    * mangle
    * Raw
  • 规则链
    * INPUT
    * OUTPUT
    * FORWARD
    * PREROUTING,路由前
    * POSTROUTING,路由后

iptables filter表

  • iptales -t filter 命令 规则链 规则
# -v 显示更详细信息
# -n 不进行反向域名解析
# -L 显示iptables信息
[root@VM-0-16-centos ~]# iptables -t filter -vnL
Chain INPUT (policy ACCEPT 380 packets, 28982 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  *      *       10.0.0.1             0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 373 packets, 53029 bytes)
 pkts bytes target     prot opt in     out     source               destination

# 增加iptables规则
[root@VM-0-16-centos ~]# iptables -t filter -A INPUT -s 10.0.0.1 -j ACCEPT

# 查看nat规则
[root@VM-0-16-centos ~]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

iptables过滤规则的使用

规则是有顺序的,会按照顺序匹配,顺序在前的会生效

# -I 会在最前面插入,-A 会在尾部追加
iptables -I INPUT -s 10.0.0.3 -j DROP

# 下面默认规则都是ACCEPT,如果没有匹配到我们指定的规则,最后就会匹配默认规则
[root@VM-0-16-centos ~]# iptables -nvL
Chain INPUT (policy ACCEPT 16 packets, 1704 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       10.0.0.3             0.0.0.0/0
    0     0 ACCEPT     all  --  *      *       10.0.0.1             0.0.0.0/0
    0     0 ACCEPT     all  --  *      *       10.0.0.2             0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 14 packets, 2986 bytes)
 pkts bytes target     prot opt in     out     source               destination

 # 修改默认规则,input 为拒绝所有ipl连接
 iptables -P INPUT DROP

 # 清空所有自定义规则,不会修改默认规则
 iptables -F

 # 清空某个规则
 iptables -D 序列号

 # 多个规则
iptables -t filter -A INPUT -i eth0 -s 10.0.0.2 -p tcp --dport 80 -j ACCEPT

iptables nat表使用

iptables -t nat 命令 规则链 规则

  • PREROUTING 目的地址转换
  • POSTROUTING 源地址转换
# 修改目的地址,转发到10.0.0.1上
iptables -t nat -A PREROUTING -i eth0 -d 114.115.116.117 -p tcp -dport 80 -j DNAT --to-destination 10.0.0.1

# 修改源地址,将内网ip都改为出口IP地址
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth1 -j SNAT --to-source 111.112.113.114

iptables 自定义的规则默认是存在内存中的,需要持久化

可以直接在/etc/sysconfig/iptables中写数据,也可以下载工具将内存中的数据写到文件中yum install iptables-services

firewallD

firewallD的特点

  • 支持区域“zone”的概念,类似于iptables中的规则链
  • firewall-cmd
# 启动firewalld,iptables和firewalld只能运行一个
[xx@VM-0-16-centos ~]$ systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
[xx@VM-0-16-centos ~]$ systemctl start firewalld.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: root
Password:
==== AUTHENTICATION COMPLETE ===
[xx@VM-0-16-centos ~]$ systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-11-02 12:19:38 CST; 4s ago
     Docs: man:firewalld(1)
 Main PID: 8308 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─8308 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
[xx@VM-0-16-centos ~]$ iptables -nvL
iptables v1.4.21: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.

# 用firewall-cmd命令
[root@VM-0-16-centos ~]# firewall-cmd --state
running
[root@VM-0-16-centos ~]# firewall-cmd --list-all
public  # public是默认的区域,既zone
  target: default
  icmp-block-inversion: no
  interfaces: # 网卡
  sources:  # 运行访问的ip
  services: dhcpv6-client ssh # 运行访问的服务,如果服务用的是默认端口,则可以替代端口,否则不行
  ports: # 运行访问的端口
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

# 单独查看每个参数
  [root@VM-0-16-centos ~]# firewall-cmd --zone=public --list-services
dhcpv6-client ssh

# 查看有哪些区域
[root@VM-0-16-centos ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

# 查看默认使用的区域
[root@VM-0-16-centos ~]# firewall-cmd --get-default-zone
public

# 查看激活的区域
[root@VM-0-16-centos ~]# firewall-cmd --get-active-zone

# 添加规则
[root@VM-0-16-centos ~]# firewall-cmd --add-service=https
success
[root@VM-0-16-centos ~]# firewall-cmd --add-port=81/tcp
success
[root@VM-0-16-centos ~]# firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcpv6-client https ssh
  ports: 81/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

# 持久化到磁盘中, --permanent,用了该命令用--list-all是看不到,需要重新加载
[root@VM-0-16-centos ~]# firewall-cmd --add-port=82/tcp --permanent
success
# reload会删除临时的规则
[root@VM-0-16-centos ~]# firewall-cmd --reload
success
[root@VM-0-16-centos ~]# firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcpv6-client ssh
  ports: 82/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

# 删除规则
[root@VM-0-16-centos ~]# firewall-cmd --remove-service=https
success
[root@VM-0-16-centos ~]# firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcpv6-client ssh
  ports: 82/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

SSH介绍及Telnet明文漏洞

telenet是明文传输

# 将公钥拷贝到服务器上
ssh-copy-id -i /root/.ssh/id_ras.pub root@/xxx

FTP服务器vsftpd介绍与软件包安装

FTP协议分为两条连接,不同的信息要用不同连接传输

* 命令链路
* 数据链路
# 安装
yum install vsftpd ftp

# 启动
systemctl start vsftpd.service

# 开机自启动
systemctl enable vsftpd.service

# 访问,使用ftp账户,则是匿名模式,默认的目录是宿主机的/var/ftp目录。也可以用系统用户,目录则是用户根目录
[root@VM-0-16-centos ~]# ftp localhost
Trying ::1...
Connected to localhost (::1).
220 (vsFTPd 3.0.2)
Name (localhost:root): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||31008|).
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Apr 01  2020 pub
226 Directory send OK.

# 要开启ftp服务让别的主机访问,需要开放端口,最简单的用firewall-cmd --add-service ftp

# 下载和上传ftp 139.155.182.202
Connected to 139.155.182.202.
220 (vsFTPd 3.0.2)
Name (139.155.182.202:qq): xx
331 Please specify the password.
Password:
230 Login successful.
ftp> !ls # !可以执行本机命令
a.txt        get_product.py    ipv4        main.go        utils
aa.txt        go.mod        ipv6        result.txt    writefile.py
bfile        go.sum        knowledge.py    test
ftp> put a.txt # 上传文件,既在远程主机上写入文件
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
7500000 bytes sent in 0.926 seconds (7.72 Mbytes/s)
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 1000     1000      7500000 Nov 02 14:21 a.txt
drwxrwxr-x    2 1000     1000         4096 Nov 02 14:19 test
226 Directory send OK.
ftp> get aaaa.txt # 下载文件,既在本地主机上写入文件
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for aaaa.txt (7 bytes).
WARNING! 2 bare linefeeds received in ASCII mode
File may not have transferred correctly.
226 Transfer complete.
7 bytes received in 0.000211 seconds (32.4 kbytes/s)

samba和NFS服务

samba服务主要针对于windows系统

NFS主要针对的的是linux系统

Nginx基本配置文件

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。来自OpenResty®官网

# 下载
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
yum install openresty

# 配置文件
/usr/local/openresty/nginx/conf/nginx.conf

# 启动
service openresty start|stop|restart|reload

LNMP

LAMP: linux + Apache + MySQL + PHP

LNMP: linux + Nginx + MySQL + PHP




   转载规则


《Linux 学习笔记》 KaKa 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录