linux学习笔记2.0

ilinux学习笔记

Linux哲学思想

  • 一切都是一个文件(包括硬件)
  • **小型,单一用途的程序 **
  • **链接程序,共同完成复杂的任务 **
  • **避免令人困惑的用户界面 **
  • 配置数据存储在文本中

第一周linux基础入门

ps aux

1.查看当前终端设备

  • tty
[19:30:06 root@RC ~]#tty
/dev/pts/0

2.当前登录终端设备

  • who am i
[19:41:59 root@RC ~]#who am i
root     pts/0        2020-07-27 18:14 (10.0.0.1)

3.查看所有终端设备

  • who
[19:39:00 root@RC ~]#who
root     pts/0        2020-07-27 18:14 (10.0.0.1)
rc       tty2         2020-07-27 19:39 (tty2)
  • w #查看所有终端设备并显示用户操作
[19:46:08 root@RC ~]#w
 19:48:59 up  1:35,  3 users,  load average: 0.03, 0.42, 0.40
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    10.0.0.1         18:14    1.00s  0.53s  0.01s w
rc       tty2     tty2             19:39    1:34m 53.10s  0.06s /usr/libexec/g
root     pts/2    10.0.0.1         19:48    4.00s  0.02s  0.02s -bash

1.bash shell

GNU Bourne-Again Shell(bash)是GN90U计划中重要的工具软件之一,目前也是 Linux标准的shell,与 sh兼容

1.1显示当前使用的shell

[19:29:18 root@RC ~]#echo $SHELL
/bin/bash
[19:29:24 root@RC ~]#echo ${SHELL}
/bin/bash

1.2显示当前系统使用的所有shell

[19:48:59 root@RC ~]#cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/usr/bin/tmux
/bin/tmux

2.hostname设置主机名

#显示当前主机名
[20:09:09 root@RC ~]#hostname
RC
#临时修改
hostname 	NAME 
#永久保存,因为是一个子进程,需要exit退出保存
hostnamectl set-hostname  NAME 
#修改文件以设置主机名
vim   /ect/hostname             

注意:主机名不支持使用下划线,但是支持横线。可使用字母,横线或数字组合

3.命令提示符

#为管理员

$为普通用户

提示符可以被修改,查uid。uid=0为管理员,uid>1000为普通用户

[14:09:38 root@RC profile.d]#id -u
0
[09:54:14 root@RC ~]#id root
uid=0(root) gid=0(root) groups=0(root)
[09:55:41 root@RC ~]#id rc
uid=1000(rc) gid=1000(rc) groups=1000(rc)

3.1 显示提示符格式

[09:55:48 root@RC ~]#echo $PS1
\[\e[1;31m\][\[\e[0m\]\t \[\e[1;32m\]\u\[\e[36m\]@\h\[\e[1;35m\] \W\[\e[1;31m\]]\[\e[0m\]\$

3.2 修改命令提示符

vim  /etc/profile.d/env.sh      #centos写入此文件可永久保存
:set paste                      #从Windows复制粘贴格式出错时使用
vim  ~/.bashrc                  #ubuntu写入此文件可永久保存

3.3提示符格式说明

在linux中,PS1是一个全局变量

  • \e:控制符\003

  • \u:当前用户的账户名称

  • \h:主机名简称

  • \H: 完整的主机名称

  • \d: 代表日期,格式为weekday month date,例如:“Mon Aug 1”

  • \w:当前工作目录

  • \t:显示时间为24小时格式,如:HH:MM:SS

  • \T:显示时间为12小时格式

  • \v: BASH的版本信息

  • !:命令历史数

  • #开机后命令历史数

    颜色表

    前景背景颜色
    3040黑色
    3041红色
    3242绿色
    3343黄色
    3444蓝色
    3545紫红色
    3646青蓝色
    3747白色

其他
0 OFF
1 高亮显示
4 underline
7 反白显示
8 不可见

4.执行命令

4.1 shell可执行命令分两类:

内部命令:由shell自带,而且通过某命令形式提供

外部命令:在文件系统路径下有对用的可执行程序文件

区分内部命令还是外部命令

type 	  COMMAND
[12:51:09 rc@rc ~]$type echo
echo is a shell builtin

type  -a  COMMAND
[13:05:20 rc@rc ~]$type -a echo
echo is a shell builtin
echo is /bin/echo

4.2 内部命令相关

help 内部命令列表

enable 管理内部命令

  • enable cmd 启用内部命令
  • enable -n cmd 禁用内部命令
  • enable -n 查看所有禁用的内部命令

4.3外部命令

查看外部命令路径

  • which
[15:49:18 root@RC ~]#which date
/usr/bin/date
which -a date
  • whereis
[15:49:27 root@RC ~]#whereis date
date: /usr/bin/date /usr/share/man/man1/date.1.gz /usr/share/man/man1p/date.1p.gz

Hash缓存表

系统初始hash表为空,但外部命令执行时, 默认会从PATH路径下寻找命令,找到后会将这条命令的路径保记录到hash表中,当再次使用该命令时shell解释器首先会查看hash表,存在将执行之,如果不存在,将会去PATH路径下寻找,利用hash缓存表可大大提高命令的调用问速率。

常见用法

  • hash 显示hash缓存
  • hash -l 显示hash缓存,可作为输入使用
  • hash -p path name 将命令全路径path起别名为name
  • hash -t name 打印缓存中name的路径
  • hash -d name 清除name缓存
  • hash -r 清除缓存

4.4命令的执行过程

  • 1别名
  • 2内部
  • 3hash
  • 4$PASH
  • 5command not found

5.命令别名

将较长的命令定义成较短的命令,以方便执行

5.1显示当前shell进程所有可用的命名别名

alias

5.2定义别名NAME,其相当于执行命令VALUE

`alias   name= ’value‘`

优先级:别名>内部命令>外部命令

如果别名同原命令同名,如果要执行原命令,可使用

\ALIASNAME
“ALIASNAME”
‘ALIASNAME’
command ALIASNAME
/path/commmand

范例:

[10:22:00 root@RC data]#alias c='cd'
[10:22:28 root@RC data]#c ~
[10:22:36 root@RC ~]#

5.3撤销别名 unalias

unalibs       #取消别名
unalias -a    #取消所有别名

注意 : 在命令行中定义的别名。仅对当前shell进程有用

如果想永久有效,要定义在配置文件中

  • 仅对当前用户: ~/.bashrc
  • 对所有用户有效:/etc/bashrc

编辑配置给出的新配置不会立即生效,bash进程重新读取配置文件

 source /path/to/config_file 
 . /path/to/config_file 

5.4命令格式

 COMMAND [OPTIONS...] [ARGUMENTS...] 

选项:用于启用或关闭命令的某个或某些功能

  • 短选项:UNIX 风格选项,-c 例如:-l, -h
  • 长选项:GNU风格选项,–word 例如:–all, --human
  • BSD风格选项: 一个字母,例如:a ;使用相对较少

注意:

  • 多个选项以及多参数和命令之间使用空白字符分隔
  • 取消和结束命令执行:Ctrl+c,Ctrl+d
  • 多个命令可以用 “;” 符号分开
  • 一个命令可以用\分成多行

6.常见命令

查看硬件信息

6.1查看cpu lscpu

  • lscpu
[10:34:53 root@RC ~]#lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              2
On-line CPU(s) list: 0,1
Thread(s) per core:  1
Core(s) per socket:  1
Socket(s):           2
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
  • cat /proc/cpuinfo
[10:40:06 root@RC ~]#cat   /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 78
model name	: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
stepping	: 3
microcode	: 0xcc
cpu MHz		: 2592.003
cache size	: 4096 KB

6.2查看硬盘和分区情况 lsblk / df

  • lsblk
[10:35:00 root@RC ~]#lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  200G  0 disk 
├─sda1   8:1    0    1G  0 part /boot
├─sda2   8:2    0  100G  df 0 part /
├─sda3   8:3    0    2G  0 part [SWAP]
├─sda4   8:4    0    1K  0 part 
└─sda5   8:5    0   50G  0 part /data
sr0     11:0    1 1024M  0 rom  
  • cat /proc/partitions
[10:50:19 root@RC ~]#cat   /proc/partitions
major minor  #blocks  name

   8        0  209715200 sda
   8        1    1048576 sda1
   8        2  104857600 sda2
   8        3    2097152 sda3
   8        4          1 sda4
   8        5   52428800 sda5
  11        0    1048575 sr0

6.3查看内核版本 uname -r

  • uname -r
[10:50:31 root@RC ~]#uname -r
4.18.0-80.el8.x86_64

6.4查看操作系统发行版本

  • cat /etc /os-release
16:28:35 rc@RC data]$cat  /etc/os-release
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
  • cat /etc/redhat-release
[10:52:17 root@RC ~]#cat   /etc/redhat-release
CentOS Linux release 8.0.1905 (Core) 

6.5时间和日期

Linux的两种时钟

  • 系统时钟:由Linux内核通过CPU的工作频率进行的
  • 硬件时钟:主板

相关命令

date 显示或修改时间

[10:53:09 root@RC ~]#date +%F_%T
2020-07-25_10:58:48
显示前n天的时间
[19:35:39 root@centos8 ~]#date -d '-1 day' +%F
2020-07-28
[19:36:46 root@centos8 ~]#date -d '-3 day' +%F
2020-07-26
修改系统时间
date -s '-1 day' +%F

clock,hwclock: 显示硬件时钟

  • -s, --hctosys 以硬件时钟为准,校正系统时钟
  • -w, --systohc 以系统 时钟为准,校正硬件时钟
timedatectl set-timezones  州/地点    #修改时区

显示日历

[11:02:04 root@RC ~]#cal -y

时区

/ect/localtime
[14:08:57 root@RC ~]#ll /etc/localtime
lrwxrwxrwx. 1 root root 35 Jul 15 10:53 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

6.6关机和重启

关机

  • halt
  • poweroff
  • init 0

重启

reboot

  • -f: 强制,不调用shutdown
  • -p: 切断电源

关机或重启:shutdown -r now 0

  • -r: reboot
  • -h: halt
  • -c:cancel TIME:无指定,默认相当于+1(CentOS7)
  • now: 立刻,相当于+0
  • +#:相对时间表示法,几分钟之后;例如 +3 hh:mm: 绝对时间表示,指明具体时间

6.7用户登录信息查看命令

  • whoami 显示当前登录有效用户
  • who 系统当前所有的登录会话
  • w 系统当前登录的所有会话及所做的操作

6.8文本编辑

  • nano 工具可以实现文本的编辑,上手容易,适合初学者
  • gedit 工具是图形工具
  • vi vim

6.9会话管理

命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称"窗口"),在里面输入命 令。用户与计算机的这种临时的交互,称为一次"会话"(session) 会话的一个重要特点是,窗口与其 中启动的进程是连在一起的。打开窗口,会话开始;关闭窗口,会话结束,会话内部的进程也会随之终 止,不管有没有运行完 一个典型的例子就是,SSH 登录远程计算机,打开一个远程窗口执行命令。这 时,网络突然断线,再次登录的时候,是找不回上一次执行的命令的。因为上一次 SSH 会话已经终止 了,里面的进程也随之消失了。为了解决这个问题,会话与窗口可以"解绑":窗口关闭时,会话并不终 止,而是继续运行,等到以后需要的时候,再让会话"绑定"其他窗口 终端复用器软件就是会话与窗口的"解绑"工具,将它们彻底分离。 (1)它允许在单个窗口中,同时访 问多个会话。这对于同时运行多个命令行程序很有用。 (2) 它可以让新窗口"接入"已经存在的会话。 (3)它允许每个会话有多个连接窗口,因此可以多人实时共享会话。 (4)它还支持窗口任意的垂直 和水平拆分。 类似的终端复用器还有Screen,Tmux

6.9.1screen

利用screen可以实现会话管理,如新建会话,共享会话等

注意 :centOS7来自于base源,centOS8来自epel源

  • centOS7安装screen
[19:08:50 root@centos7 ~]#yum -y install screen
  • centOS8安装screen
[11:14:32 root@RC ~]#yum -y instal  screen

screen常见用法

  • 创建新screen会话 screen –S [SESSION]
  • 加入screen会话 screen –x [SESSION]
  • 退出并关闭screen会话 exit
  • 剥离当前screen会话 Ctrl+a,d
  • 显示所有已经打开的screen会话 screen -ls
  • 恢复某screen会话 screen -r [SESSION]
6.9.2 tmux
  • 安装
[11:14:32 root@RC ~]#yum install tmux
  • 启动与退出
[11:24:26 root@RC ~]#tmux
[exited]
[11:26:41 root@RC ~]#exit
logout

mux 窗口有大量的快捷键。所有快捷键都要通过前缀键唤起。默认的前缀键是 Ctrl+b ,即先按下 Ctrl+b ,快捷键才会生效。帮助命令的快捷键是 Ctrl+b ? 然后,按下 q 键,就可以退出帮助 新建会话 第一个启动的 Tmux 窗口,编号是0,第二个窗口的编号是1,以此类推。这些窗口对应的会 话,就是 0 号会话、1 号会话。使用编号区分会话,不太直观,更好的方法是为会话起名。

  • 新建一个指定名称的会话
tmux new -s <session-name>
  • tmux ls或Ctrl+b,s 可以查看当前所有的 Tmux 会话
tmux ls
tmux list-session
  • 分离会话 在 Tmux 窗口中,按下Ctrl+b d或者输入tmux detach命令,就会将当前会话与窗口分离
tmux detach
  • 接入会话 tmux attach 命令用于重新接入某个已存在的会话
tmux attach -t <session-name>
  • 杀死会话 tmux kill-session命令用于杀死某个会话
tmux kill-session -t <session-name>
  • 切换会话 tmux switch命令用于切换会话
tmux switch -t <session-name>
  • 可以将窗口分成多个窗格(pane),每个窗格运行不同的命令
    上下分窗格
tmux split-window
ctrl+b,"
  • 左右分窗格
tmux split-window -h
ctrl+b,%
  • 窗格快捷键
Ctrl+b %:划分左右两个窗格。

Ctrl+b ":划分上下两个窗格。 

Ctrl+b :光标切换到其他窗格。是指要切换到的窗格的方向键,比如切换到下方窗格,就按方向键↓。 

Ctrl+b ;:光标切换到上一个窗格。

Ctrl+b o:光标切换到下一个窗格。

Ctrl+b {:当前窗格左移。

Ctrl+b }:当前窗格右移。

Ctrl+b Ctrl+o:当前窗格上移。

Ctrl+b Alt+o:当前窗格下移。

Ctrl+b x:关闭当前窗格。 

Ctrl+b !:将当前窗格拆分为一个独立窗口。 

Ctrl+b z:当前窗格全屏显示,再使用一次会变回原来大小。

Ctrl+b Ctrl+:按箭头方向调整窗格大小。 

Ctrl+b q:显示窗格编号

窗口管理 除了将一个窗口划分成多个窗格,Tmux 也允许新建多个窗口

  • 新建窗口 tmux new-window命令用来创建新窗口
tmux new-window
  • 新建一个指定名称的窗口
tmux new-window -n <window-name>
  • 切换窗口 tmux select-window命令用来切换窗口
 tmux select-window -t <window-number>
  • 切换到指定名称的窗口
tmux select-window -t <window-name>
  • 窗口快捷键

Ctrl+b c:创建一个新窗口,状态栏会显示多个窗口的信息。

Ctrl+b p:切换到上一个窗口(按照状态栏上的顺序)。

Ctrl+b n:切换到下一个窗口。

Ctrl+b :切换到指定编号的窗口,其中的是状态栏上的窗口编号

Ctrl+b w:从列表中选择窗口

Ctrl+b ,:窗口重命

  • 列出所有快捷键,及其对应的 Tmux 命令
tmux list-keys
  • 列出所有 Tmux 命令及其参数
tmux list-commands

7.输出信息echo

echo 命令可以将后面跟的字符进行输出

功能:显示字符,echo会将输入的字符串送往标准输出。输出
的字符串间以空白字符隔开, 并在最后加上换行号 语法:

语法:

 echo   [-n,e,E]  [字符串]

选项:

  • -E (默认)不支持\解释功能
  • -n 不自动换行
  • -e 启用\字符串的解释功能

显示变量

echo   "SAVR_NAME "            #用变量值替换,弱引用
echo   ’SAVR_NAME ‘              #变量不会替换,强引用

启用命令选项-e,若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出

  • \a 发出警告声
  • \b 退格键
  • \c 最后不加上换行符号
  • \e escape,相当于\033
  • \n 换行且光标移至行首
  • \r 回车,即光标移至行首,但不换行
  • \t 插入tab
  • \ 插入\字符
  • \0nnn 插入nnn(八进制)所代表的ASCII字符
  • \xHH插入HH(十六进制)所代表的ASCII数字(man 7 ascii)

8.字符集和编码

许多场合下,字符集与编码这两个概念常被混为一谈,但两者是有差别的。字符集与字符集编码是两个不同层面的概念。 charset是character set的简写,即字符集。 encoding是charset encoding的简写,即字符集编码,简称编码

8.1 ASCII码

计算机内部,所有信息最终都是一个二进制值。上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定,即ASCII(American Standard Code for Information Interchange) 码
ASCII 码一共规定了128个字符的编码,占用了一个字节的后面7位,最前面的一位统一规定为0

8.2 Umicode

由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,即ASCII编码,但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。 全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码为了表示世界上所有语言中的所有字符。每一个符号都给予一个独一无二的编码数字,Unicode 是一个很大的集合,现在的规模可以容纳100多万个符号。Unicode 仅仅只是一个字符集,规定了每个字符对应的二进制代码,至于这个二进制代码如何存储则没有规定

Unicode编码方案:

  • UTF-8:变长,1到4个字节
  • UTF-16:变长,2或4个字节
  • UTF-32:固定长度,4个字节

9.命令行扩展和被括起来的集合

9.1 命令行扩展 : $ ( )和``

把一个命令的输出打印给另一个命令的参数

$(CMD)`CMD`

比较 “ ” ,‘ ’ ,``

[09:47:53 root@RC ~]#echo "echo $SHELL"
echo /bin/bash
[09:53:25 root@RC ~]#echo 'echo $SHELL'
echo $SHELL
[09:54:00 root@RC ~]#echo `echo $SHELL`
/bin/bash

双 引 号:不能识别命令,可以识别变量

单 引 号:六亲不认,变量和命令都不能识别 都当成普通字符串

反向单引号:B变量和命令都识别,并且会将反向单引号的内容当成命令执行后,在交给调用反向单引号的命令继续

9.2 括号扩展:{ }

{ } 可以实现打印重复字符串的简化形式

[09:58:22 root@RC ~]#echo {1..10}
1 2 3 4 5 6 7 8 9 10
[10:09:57 root@RC ~]#echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[10:11:47 root@RC ~]#echo {A..z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [  ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z
[10:10:43 root@RC ~]#echo {1,2,3}.txt
1.txt 2.txt 3.txt

9.3 双击tap键补全

tab键可以实现命令及路径等补全,提高输入效率,避免出错

  • command 2Tab 所有子命令或文件补全
  • string2Tab 以string开头命令
  • /2Tab 显示所有根目录下一级目录,包括隐藏目录
  • ./2Tab 当前目录下子目录,包括隐藏目录
  • *2Tab 当前目录下子目录,不包括隐藏目录
  • ~2Tab 所有用户列表
  • $2Tab 所有变量
  • @2Tab /etc/hosts记录 (centos7不支持)
  • =2Tab 相当于ls –A (centos7不支持)

9.4命令行历史

保存你输入的命令历史。可以用它来重复执行命令 登录shell时,会读取命令历史文件中记录下的命令 ~/.bash_history 登录进shell后新执行的命令只会记录在缓存中;这些命令会用户退出时“追加”至命令历 史文件中

命令:history

  • -c: 清空命令历史
  • -d offset: 删除历史中指定的第offset个命令
  • n: 显示最近的n条历史
  • -a: 追加本次会话新执行的命令历史列表至历史文件
  • -r: 读历史文件附加到历史列表
  • -w: 保存历史列表到指定的历史文件
  • -n: 读历史文件中未读过的行到历史列表
  • -p: 展开历史参数成多行,但不存在历史列表中
  • -s: 展开历史参数成一行,附加在历史列表后

命令历史相关环境变量

  • HISTSIZE:命令历史记录的条数
  • HISTFILE:指定历史文件,默认为~/.bash_history
  • HISTFILESIZE:命令历史文件记录历史的条数
  • HISTTIMEFORMAT="%F %T " 显示时间
  • HISTIGNORE=“str1:str2*:…” 忽略str1命令,str2开头的历史
  • HISTCONTROL:控制命令历史的记录方式 ignoredups 是默认值,可忽略重复的命令,连续且相 同为“重复” ignorespace 忽略所有以空白开头的命令 ignoreboth 相当于ignoredups, ignorespace 的组合 erasedups 删除重复命令

持久保存变量

  • 以上变量可以 export 变量名=“值” 形式存放在 /etc/profile 或 ~/.bash_profile

调用历史命令行

#重复前一个命令方法
重复前一个命令使用上方向键,并回车执行
按 !! 并回车执行
输入 !-1 并回车执行
按 Ctrl+p 并回车执行

!:0     执行前一条命令(去参数)
!-n     执行history历史中倒数第n个命令
!string 重复前一个以“string”开头的命令
!?string 重复前一个包含string的命令
!string:p 仅打印命令历史,而不执行
!$:p打印输出 !$ (上一条命令的最后一个参数)的内容
!*:p 打印输出 !*(上一条命令的所有参数)的内容
^string 删除上一条命令中的第一个string
^string1^string2 将上一条命令中的第一个string1替换为string2
!:gs/string1/string2 将上一条命令中所有的string1都替换为 string2
使用up(向上)和down(向下)键来上下浏览从前输入的命令
ctrl-r来在命令历史中搜索命令
(reverse-i-search)`’:
Ctrl+g:从历史搜索模式退出
#要重新调用前一个命令中最后一个参数
!$       表示
Esc , . 点击Esc键后松开,然后点击 . 键
Alt+ . 按住Alt键的同时点击 .command !^   利用上一个命令的第一个参数做cmd的参数
command !$   利用上一个命令的最后一个参数做cmd的参数
command !*   利用上一个命令的全部参数做cmd的参数
command !:n  利用上一个命令的第n个参数做cmd的参数
command !n:^ 调用第n条命令的第一个参数
command !n:$ 调用第n条命令的最后一个参数
command !n:m 调用第n条命令的第m个参数
command !n:* 调用第n条命令的所有参数
command !string:^ 从命令历史中搜索以 string 开头的命令,并获取它的第一个参数
command !string:$ 从命令历史中搜索以 string 开头的命令,并获取它的最后一个参数
command !string:n 从命令历史中搜索以 string 开头的命令,并获取它的第n个参数
command !string:* 从命令历史中搜索以 string 开头的命令,并获取它的所有参数执行前一条命令(去除参数

9.5 bash快捷键

Ctrl + l 	清屏,相当于clear命令 

Ctrl + o 	执行当前命令,并重新显示本命令 

Ctrl + s 	阻止屏幕输出,锁定 

Ctrl + q 	允许屏幕输出 

Ctrl + c 	终止命令 

Ctrl + z 	挂起命令 

Ctrl + a 	光标移到命令行首,相当于Home 

Ctrl + e 	光标移到命令行尾,相当于End 

Ctrl + f 	光标向右移动一个字符 

Ctrl + b 	光标向左移动一个字符 

Alt + f 	光标向右移动一个单词尾 

Alt + b 	光标向左移动一个单词首 

Ctrl + xx 	光标在命令行首和光标之间移动 

Ctrl + u	从光标处删除至命令行首 

Ctrl + k 	从光标处删除至命令行尾 

Alt + r 	删除当前整行 

Ctrl + w 	从光标处向左删除至单词首 

Alt + d 	从光标处向右删除至单词尾 

Ctrl + d 	删除光标处的一个字符 

Ctrl + h 	删除光标前的一个字符 

Ctrl + y 	将删除的字符粘贴至光标后 

Alt + c 	从光标处开始向右更改为首字母大写 的单词 

Alt + u 	从光标处开始,将右边一个单词更改为大写 

Alt + l 	从光标处开始,将右边一个单词更改 为小写 

Ctrl + t 	交换光标处和之前的字符位置 

Alt + t 	交换光标处和之前的单词位置 

Alt + # 提示输入指 定字符后,重复显示该字符#次 

注意:Alt组合快捷键经常和其它软件冲突

10.获得帮助

多层次的帮助

  • whatis
  • command --help
  • man and info
  • /usr/share/doc/
  • Red Hat documentation
  • 其它网站和搜索

whatis command

whatis 使用数据库来显示命令的简短描述 刚安装后不可立即使用,需要制作数据库

#CentOS 7 版本以后
mandb
#CentOS 6 版本之前
makewhatis

10.1查看命令的帮助

内部命令:

  • help COMMAND
[19:57:33 root@centos8 ~]#type cd
cd is a shell builtin
[19:57:43 root@centos8 ~]#help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
    Change the shell working directory.
    
    Change the current directory to DIR.  The default DIR is the value of the
    HOME shell variable.
  • man bash

外部命令和软件帮助:

  • COMMAND --help 或 COMMAND -h
  • 使用手册(manual) man COMMAND
  • 信息页 info COMMAND
  • 程序自身的帮助文档 :README, INSTALL, ChangeLog
  • 程序官方文档
  • 相关网站,技术论坛
  • Google

10.2 --help或-h选项

显示用法总结和参数列表,大多数命令使用,但并非所有的

[15:36:48 root@RC ~]#date --help
Usage: date [OPTION]... [+FORMAT]
  or:  date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Display the current time in the given FORMAT, or set the system date.
[20:05:53 root@centos8 ~]#cd --help
cd: cd [-L|[-P [-e]] [-@]] [dir]
    Change the shell working directory.
    
    Change the current directory to DIR.  The default DIR is the value of the
    HOME shell variable.

格式说明:

  • [ ]表示可选项

  • CAPS或 <> 表示变化的数据

  • … 表示一个列表

  • x |y| z 的意思是“ x 或 y 或 z ”

  • -abc的 意思是-a -b –c

  • { } 表示分组

10.3 man命令

man 提供命令帮助的文件,手册页存放在/usr/share/man

几乎每个命令都有man的“页面”

中文man需安装包

  • man-pages
  • man-pages-zh-CN

man页面分组为不同的“章节”,统称为Linux手册,man 1 man

  • 1:用户命令
  • 2:系统调用
  • 3:C库调用
  • 4:设备文件及特殊文件
  • 5:配置文件格式
  • 6:游戏
  • 7:杂项
  • 8:管理类的命令
  • 9:Linux 内核API

man命令的配置文件:

#centos6之前版man的配置文件
/etc/man.config
#centos7之后版man的配置文件
/etc/man_db.conf
#ubuntu	man 的配置文件
/etc/manpath.config

查看man 手册页

man [OPTION...] [SECTION] PAGE..
man [章节] keyword

man帮助段落说明

  • NAME 名称及简要说明
  • SYNOPSIS 用法格式说明
  • 可选内容
  • <> 必选内容
  • a|b 二选一
  • { } 分组
  • … 同一内容可出现多次
  • DESCRIPTION 详细说明
  • OPTIONS 选项说明
  • EXAMPLES 示例
  • FILES 相关文件
  • AUTHOR 作者
  • COPYRIGHT 版本信息
  • REPORTING BUGS bug信息
  • SEE ALSO 其它帮助参考

man命令的操作方法:使用less命令实现

  • space, ^v, ^f, ^F: 向文件尾翻屏

  • b, ^b: 向文件首部翻屏

  • d, ^d: 向文件尾部翻半屏

  • u, ^u: 向文件首部翻半屏

  • RETURN, ^N, e, ^E or j or ^J: 向文件尾部翻一行

  • y or ^Y or ^P or k or ^K:向文件首部翻一行

  • q: 退出

  • #:跳转至第#行

  • 1G: 回到文件首部

  • G:翻至文件尾部

  • /KEYWORD 以KEYWORD指定的字符串为关键字,从当前位置向文件尾部搜索;不区分字符大小写

    n: 下一个

    N:上一个

  • ?KEYWORD 以KEYWORD指定的字符串为关键字,从当前位置向文件首部搜索;不区分字符大小写

    n: 跟搜索命令同方向,下一个

    N:跟搜索命令反方向,上一个

常用选项

  • 列出所有帮助
man -a keyword
  • 相当于whatis
man  -f keyword

10.4系统及第三方应用官方文档

1.通过在线文档获取帮助

http://httpd.apache.org

http://www.nginx.org

https://mariadb.com/kb/en

https://dev.mysql.com/doc/

http://tomcat.apache.org

http://www.python.org

2.红帽知识库和官方在线文档

通过发行版官方的文档光盘或网站可以获得安装指南、部署指南、虚拟化指南等
http://kbase.redhat.com

http://www.redhat.com/docs

http://access.redhat.com

https://help.ubuntu.com/lts/serverguide/index.html

3.红帽全球技术支持服务

rhn.redhat.com或者本地卫星服务器/代理服务器

RHN账户为及其注册和基于网络管理的RHN用户

sosreport 收集所有系统上的日志信息的工具,并自动打成压缩包,方便技术支持人员和红帽全球支持提供分析问题依据

4.网站和搜索

http://tldp.org

http://www.slideshare.net

http://www.google.com

第一周文件管理和IO重定向

1.文件系统目录结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vHJ3t1LH-1596963218103)(C:\Users\RC\Pictures\Saved Pictures\QQ截图20200807115935.png)]

  • 文件和目录被组织成一个单根倒置树结构

  • 文件系统从根目录下开始,用“/”表示

  • 根文件系统(rootfs):root filesystem

  • 标准Linux文件系统(如ext4),文件名称大小写敏感,例如:MAIL, Mail, mail, mAiL

  • 以.开头的文件为隐藏文件

  • 路径分隔的 /

  • 文件名最长255个字节

  • 包括路径在内文件名称最长4095个字节

  • 蓝色–>目录 绿色–>可执行文件 红色–>压缩文件 浅蓝色–>链接文件 灰色–>其他文件

  • 除了斜杠和NUL,所有字符都有效.但使用特殊字符的目录名和文件不推荐使用,有些字符需要用引号来引用

  • 每个文件都有两类相关数据:
    元数据:metadata
    数据:data

    Linux的文件系统分层结构:FHS Filesystem Hierarchy Standard

1.2常见的文件系统目录功能

  • /boot:引导文件存放目录,内核文件(vmlinuz)、引导加载器(bootloader, grub)都存放于此目录

  • /bin:所有用户使用的基本命令;不能关联至独立分区,OS启动即会用到的程序

  • /sbin:管理类的基本命令;不能关联至独立分区,OS启动即会用到的程序

  • /lib:启动时程序依赖的基本共享库文件以及内核模块文件(/lib/modules)

  • /lib64:专用于x86_64系统上的辅助共享库文件存放位置

  • /etc:配置文件目录

  • /home/USERNAME:普通用户家目录

  • /root:管理员的家目录

  • /media:便携式移动设备挂载点

  • /mnt:临时文件系统挂载点

  • /dev:设备文件及特殊文件存储位置

    ​ b: block device,随机访问

    ​ c: character device,线性访问

  • /opt:第三方应用程序的安装位置

  • /srv:系统上运行的服务用到的数据

  • /tmp:临时文件存储位置

  • /usr: universal shared, read-only data

    ​ bin: 保证系统拥有完整功能而提供的应用程序

    ​ sbin:

    ​ lib:32位使用

    ​ lib64:只存在64位系统

    ​ include: C程序的头文件(header files)

    ​ share:结构化独立的数据,例如doc, man等

        		  local:第三方应用程序的安装位置
    

    ​ bin, sbin, lib, lib64, etc, share

  • /var: variable data files

    ​ cache: 应用程序缓存数据目录

    ​ lib: 应用程序状态信息数据

    ​ local:专用于为/usr/local下的应用程序存储可变数据

    ​ lock: 锁文件

    ​ log: 日志目录及文件

    ​ opt: 专用于为/opt下的应用程序存储可变数据

    ​ run: 运行中的进程相关数据,通常用于存储进程pid文件

    ​ spool: 应用程序数据池

    ​ tmp: 保存系统两次重启之间产生的临时数据

  • /proc: 用于输出内核与进程信息相关的虚拟文件系统

  • /sys:用于输出当前系统上硬件设备相关信息虚拟文件系统

  • /selinux: security enhanced Linux,selinux相关的安全策略等信息的存储位置

CentOS 7 以后版本目录结构变化

  • /bin 和 /usr/bin

  • /sbin 和 /usr/sbin

  • /lib 和/usr/lib

  • /lib64 和 /usr/lib64

1.3 应用程序的组成部分

二进制程序:/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
库文件:/lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64
配置文件:/etc, /etc/DIRECTORY, /usr/local/etc
帮助文件:/usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc

1.4 Linux下的文件类型(7种)

  • -普通文件
  • d 目录文件directory
  • b 块设备black
  • c 字符设备character
  • l 符号链接文件link
  • p 管道文件pipe
  • s 套接字文件socket

2.文件操作命令

2.1显示当前工作目录

每个shell和系统进程都有一个当前的工作目录 CWD:current work directory
显示当前shell CWD的绝对路径

pwd命令: printing working directory

  • -P 显示真实物理路径
  • -L 显示链接路径(默认)

2.2绝对路径和相对路径

  • 绝对路径
    以正斜杠开始
    完整的文件的位置路径
    可用于任何想指定一个文件名的时候

  • 相对路径名

    不以斜线开始
    一般情况下,指定相对于当前工作目录或某目录的位置。特殊情况下,是相对于某目录的位置
    可以作为一个简短的形式指定一个文件名

    基名:basename,只取文件名而不要路径
    目录名:dirname,只取路径,不要文件名

2.3更改目录

命令 cd : change directory 改变目录
选项:-P 切换至物理路径,而非软链接目录

可以使用绝对或相对路径

  • 切换至父目录: cd …
  • 切换至当前用户主目录: cd
  • 切换至以前的工作目录: cd -

相关的环境变量:

  • PWD:当前目录路径
  • OLDPWD:上一次目录路径

2.4列出目录内容

ls 命令可以列出当前目录的内容或指定目录

常见选项:

  • -a 包含隐藏文件
  • -l 显示额外的信息
  • -R 目录递归
  • -ld 目录和符号链接信息
  • -1 文件分行显示
  • -S 按从大到小排序
  • -t 按mtime排序
  • -u 配合-t选项,显示并按atime从新到旧排序
  • -U 按目录存放顺序显示
  • -X 按文件后缀排序
  • -d 查看文件夹自身的属性

2.5查看文件的状态stat

文件相关信息:metadata (元数据,文件属性信息), data(数据本身)

每个文件有三个时间戳:

  • access time 访问时间,atime,读取文件内容
  • modify time 修改时间,mtime,改变文件内容(数据)
  • change time 改变时间,ctime,元数据发生改变
[14:45:06 root@centos8 ~]#stat anaconda-ks.cfg 
  File: anaconda-ks.cfg
  Size: 1535      	Blocks: 8          IO Block: 4096   regular file
Device: 802h/2050d	Inode: 201720846   Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:admin_home_t:s0
Access: 2020-07-29 10:40:51.028884220 +0800
Modify: 2020-07-29 10:40:51.112886162 +0800
Change: 2020-07-29 10:40:51.112886162 +0800
 Birth: -

2.6确定文件内容

文件可以包含多种类型的数据,使用file命令检查文件的类型,然后确定适当的打开命令或应用程序使用

file [OPTION...] [FILE...]

常用选项:

  • -b 列出文件辨识结果时,不显示文件名称
  • -f filelist 列出文件filelist中文件名的文件类型
  • -F 使用指定分隔符号替换输出文件名后默认的”:”分隔符
  • -L 查看对应软链接对应文件的文件类型
  • –help 显示命令在线帮助

2.7文件通配符模式

文件通配符可以用来匹配符合条件的多个文件,方便批理管理文件
通配符采有特定的符号,表示特定的含义,此特符号称为元字符

常见的通配符如下:

* 			匹配零个或多个字符
? 			匹配任何单个字符
~ 			当前用户家目录
~mage		用户mage家目录
~+和. 	   当前工作目录
~- 			前一个工作目录
[0-9]		匹配数字范围
[a-z]		字母
[A-Z] 		字母
[wang]		匹配列表中的任何的一个字符
[^wang]     匹配列表中的所有字符以外的字符
[15:39:53 root@centos8 data]#ls f[a-c].txt
fa.txt  fA.txt  fb.txt  fB.txt  fc.txt
[15:40:53 root@centos8 data]#ls f[a-C].txt
fa.txt  fA.txt  fb.txt  fB.txt  fc.txt  fC.txt

别外还有在Linux系统中预定义的字符类:man 7 glob

[:digit:]:任意数字,相当于0-9
[:lower:]:任意小写字母,表示 a-z
[:upper:]: 任意大写字母,表示 A-Z
[:alpha:]: 任意大小写字母
[:alnum:]:任意数字或字母
[:blank:]:水平空白字符
[:space:]:水平或垂直空白字符
[:punct:]:标点符号
[:print:]:可打印字符
[:cntrl:]:控制(非打印)字符
[:graph:]:图形字符
[:xdigit:]:十六进制字符

2.8 创建空文件和刷新时间

touch命令可以用来创建空文件或刷新文件的时间

touch [OPTION]... FILE...

选项说明:

  • -a 仅改变 atime和ctime
  • -m 仅改变 mtime和ctime
  • -t [[CC]YY]MMDDhhmm[.ss] 指定atime和mtime的时间戳
  • -c 如果文件不存在,则不予创建

2.9复制文件和目录

cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...

常用选项

  • -i 覆盖前提示

  • -n不覆盖,注意两者顺序

  • -r, -R 递归复制目录及内部的所有内容

  • -a 归档,相当于-dR --preserv=all,常用于备份

  • -d --no-dereference --preserv=links 不复制原文件,只复制链接名

  • –preserv[=ATTR_LIST]

    mode: 权限 
    
    ownership: 属主属组 
    
    timestamp: 
    

    links

    xattr

    context

    all

  • -p (保留属性,权限所有者)等同–preserv=mode, ownership, timestamp

  • -v --verbose (详细过程)

  • -f --force

  • -u --update 只复制源比目标更新文件或目标不存在的文件

  • -b 目标存在,覆盖前先备份,形式为 filename~

  • –backup=numbered 目标存在,覆盖前先备份加数字后缀

2.10 移动和重命名文件

mv 命令可以实现文件或目录的移动和改名
同一分区移动数据,速度很快:数据位置没有变化
不同分区移动数据,速度相对慢:数据位置发生了变化

mv [OPTION]... [-T] SOURCE DEST
mv [OPTION]... SOURCE... DIRECTORY
mv [OPTION]... -t DIRECTORY SOURCE...

常用选项:

  • -i 交互式

  • -f 强制

  • -b 目标存在,覆盖前先备份

    利用rename 可以批量修改文件名

rename [options] <expression> <replacement> <file>...
#为所有的conf文件加上.bak后缀:
rename 'conf' 'conf.bak' f*
#去掉所有的bak后缀:
rename '.bak' '' *.bak

2.11删除文件

使用rm 命令可以删除文件

rm [OPTION]... [FILE]...

常用选项:

  • -i 交互式
  • -f 强制删除
  • -r 递归
  • –no-preserve-root 删除/

rm虽然删除了文件,但是被删除的文件仍然可能被恢复,在安全要求较高的场景下,可以使用shred安全删除文件

格式

shred [OPTION]... FILE...

常见选项

  • -z 最后一次覆盖添加0,以隐藏覆盖操作
  • -v 能够显示操作进度
  • -u 覆盖后截断并删除文件
  • -n # 指定覆盖文件内容的次数(默认值是3次)
[20:24:49 root@centos8 data]#shred -zvun 4  df.txt 
shred: df.txt: pass 1/5 (random)...
shred: df.txt: pass 2/5 (ffffff)...
shred: df.txt: pass 3/5 (000000)...
shred: df.txt: pass 4/5 (random)...
shred: df.txt: pass 5/5 (000000)...
shred: df.txt: removing
shred: df.txt: renamed to 000000
shred: 000000: renamed to 00000
shred: 00000: renamed to 0000
shred: 0000: renamed to 000
shred: 000: renamed to 00
shred: 00: renamed to 0
shred: df.txt: removed

2.12目录操作

2.12.1 显示目录树 tree
  • 常见选项:

  • -d: 只显示目录

  • -L level:指定显示的层级数目

  • -P pattern: 只显示由指定wild-card pattern匹配到的路径

    2.12.2 创建目录mkdir
  • 常见选项:

  • -p: 存在于不报错,且可自动创建所需的各目录

  • -v: 显示详细信息

  • -m MODE: 创建目录时直接指定权限

    2.11.3 删除空目录rmdir
  • 常见选项:

  • -p 递归删除父空目录

  • -v 显示详细信息

    注意:rmdir只能删除空目录,如果想删除非空目录,可以使用rm -r 命令,递归删除目录树

练习

(1) 如何创建/testdir/dir1/x, /testdir/dir1/y, /testdir/dir1/x/a, /testdir/dir1/x/b, /testdir/dir1/y/a, /testdir/dir1/y/b

[20:37:12 root@centos8 data]#mkdir -p testdir/dir1/{x/{a,b},y/{a,b}}
[20:38:10 root@centos8 data]#tree testdir
testdir
└── dir1
    ├── x
    │   ├── a
    │   └── b
    └── y
        ├── a
        └── b

(2) 如何创建/testdir/dir2/x, /testdir/dir2/y, /testdir/dir2/x/a, /testdir/dir2/x/b

[20:46:32 root@centos8 data]#mkdir -p testdir/dir2/{x/{a,b},y}
[20:46:45 root@centos8 data]#tree testdir/
testdir/
├── dir1
│   ├── x
│   │   ├── a
│   │   └── b
│   └── y
│       ├── a
│       └── b
└── dir2
    ├── x
    │   ├── a
    │   └── b
    └── y

(3) 如何创建/testdir/dir3, /testdir/dir4, /testdir/dir5, /testdir/dir5/dir6, /testdir/dir5/dir7

[21:00:58 root@centos8 data]#mkdir -p testdir/dir{3,4,5/dir{6,7}}
[21:01:37 root@centos8 data]#tree testdir/
testdir/
├── dir1
│   ├── x
│   │   ├── a
│   │   └── b
│   └── y
│       ├── a
│       └── b
├── dir2
│   ├── x
│   │   ├── a
│   │   └── b
│   └── y
├── dir3
├── dir4
└── dir5
    ├── dir6
    └── dir7

3.文件元数据和节点表结构

3.1 inode表结构

每个文件的属性信息,比如:文件的大小,时间,类型等,称为文件的元数据(meta data)。这此元数据是存放在inode(index node)表中。node 表中有很多条记录组成,第一条记录对应的存放了一个文件的元数据信息
第一个node表记录对应的保存了以下信息

  • inode number 节点号
  • 文件类型
  • 权限
  • UID
  • GID
  • 链接数(指向这个文件名路径名称个数)
  • 该文件的大小和不同的时间戳
  • 指向磁盘上文件的数据块指针
  • 有关文件的其他数据

目录
目录是个特殊文件,文件内容保存了目录中文件的列表及inode number

  • 文件引用一个是 inode号
  • 人是通过文件名来引用一个文件
  • 一个目录是目录下的文件名和文件inode号之间的映射

cp和inode

cp 命令:

  • 分配一个空闲的inode号,在inode表中生成新条目
  • 在目录中创建一个目录项,将名称与inode编号关联
  • 拷贝数据生成新的文件
    rm和inode

rm 命令

  • 链接数递减,从而释放的inode号可以被重用
  • 把数据块放在空闲列表中
  • 删除目录项
  • 数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖

mv和inode

  • 如果mv命令的目标和源在相同的文件系统,作为mv 命令
    用新的文件名创建对应新的目录项
    删除旧目录条目对应的旧的文件名
    不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动!
  • 如果目标和源在一个不同的文件系统, mv相当于cp和rm

3.2 硬链接 ln

硬链接本质上就给一个文件起一个新的名称,实质是同一个文件
硬链接特性

  • 创建硬链接会增加额外的记录项以引用文件
  • 对应于同一文件系统上一个物理文件
  • 每个目录引用相同的inode号
  • 创建时链接数递增
  • 删除文件时:rm命令递减计数的链接,文件要存在,至少有一个链接数,当链接数为零时,该文件被删除
  • 不能跨越驱动器或分区
  • 不支持对目录创建硬链接

格式

ln filename [linkname ]

3.3 符号(或软)链接

一个符号链接指向另一个文件,就像windows中快捷方式,软链接文件和原文件本质上不是同一个文件

软链接特点

  • 一个符号链接的内容是它引用文件的名称
  • 可以对目录创建软链接
  • 可以跨分区的文件实现
  • 指向的是另一个文件的路径;其大小为指向的路径字符串的长度;不增加或减少目标文件inode的 引用计数
  • 软链接如果使用相对路径,是相对于原文件的路径,而非相对于当前目录

格式:

ln  -s filename [linkname ]

3.4硬链接和软链接区别总结

硬链接软链接
本质本质是同一个文件本质不是同一个文件
跨设备不支持支持
inode相同不同
链接数创建新的硬链接,链接数会增加,删除硬链接,链接数会减少创建或删除,链接数不会变化
文件夹不支持支持
相对路径原始文件相对路径是相对于当前工作目录原始文件相对路径是相对于链接文件的相对路径
删除文件源只是链接数减一,但链接文件的访问不受影响链接文件将无法访问
文件类型和源文件相同链接文件,和源文件无关
文件大小和源文件相同源文件的路径的长度

案例1:提示空间满 NO space left on device ,但是df可以看到空间很多,为什么?

答:节点编号用光了

案例2:提示空间快满,使用rm删除了很大的无用文件后,df仍然看到空间不足,为什么?如何解决?

答:被删除文件被某个进程打开或使用。可以通过kill命令将进程杀掉从而释放空间

4. IO重定向

4.1标准输入和输出

程序:指令加数据

读入数据:Input
输出数据:Output

打开的文件都有一个fd: file descriptor (文件描述符)

Linux给程序提供三种 I/O 设备

  • 标准输入(STDIN) -0 默认接受来自终端窗口的输入
  • 标准输出(STDOUT) -1 默认输出到终端窗口
  • 标准错误(STDERR) -2 默认输出到终端窗口

4.2 I/O重定向redirect

I/O重定向:将默认的输入,输出或错误对应的设备改变,指向新的目标

4.2.1标准输出和错误重新定向

STDOUT和STDERR可以被重定向到指定文件,而非默认的当前终端

  • 格式:
命令	操作符号	文件名
  • 支持的操作符号包括:
1>> 把STDOUT重定向到文件
>| 强制覆盖
2> 把STDERR重定向到文件
&> 把所有输出重定向到文件
以上如果文件已存在,文件内容会被覆盖

以上如果文件已存在,文件内容会被覆盖

set -C 禁止将内容覆盖已有文件,但可追加
set +C 允许覆盖
  • 追加
>> 可以在原有内容基础上,追加内容
把输出和错误重新定向追加到文件

>> 追加标准输出重定向至文件
2>> 追加标准错误重定向至文件
  • 标准输出和错误输出各自定向至不同位置
COMMAND > /path/to/file.out 2> /path/to/error.out
  • 合并标准输出和错误输出为同一个数据流进行重定向
    &> 覆盖重定向
    &>> 追加重定向

COMMAND > /path/to/file.out 2>&1 (顺序很重要)
COMMAND >> /path/to/file.out 2>&1

  • 合并多个程序

(CMD1,CMD2…)或者{CMD1,CMD2…} 合并多个程序的STDOUT

范例

4.3 标准输入重定向

从文件中导入STDIN,代替当前终端的输入设备,使用 < 来重定向标准输入 某些命令能够接受从文件中导入的STDIN

4.3.1 tr命令

tr转换或删除字符

tr [OPTION]... SET1 [SET2]

选项:

-c –C --complement:取字符集的补集
-d    --delete:删除所有属于第一字符集的字符
-s    --squeeze-repeats:把连续重复的字符以单独一个字符表示,即去重
-t    --truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符
[:alnum:]:字母和数字
[:alpha:]:字母
[:digit:]:数字
[:lower:]:小写字母
[:upper:]:大写字母
[:space:]:空白字符
[:print:]:可打印字符
[:punct:]:标点符号
[:graph:]:图形字符
[:cntrl:]:控制(非打印)字符
[:xdigit:]:十六进制字符

#范例:把/etc/os-release文件中的小写字母转换为大写字母转换
[20:50:17 root@centos8 data]#tr [a-z] [A-Z] < /etc/os-release 
NAME="CENTOS LINUX"
VERSION="8 (CORE)"
ID="CENTOS"
ID_LIKE="RHEL FEDORA"
VERSION_ID="8"
PLATFORM_ID="PLATFORM:EL8"
PRETTY_NAME="CENTOS LINUX 8 (CORE)"
ANSI_COLOR="0;31"
CPE_NAME="CPE:/O:CENTOS:CENTOS:8"
HOME_URL="HTTPS://WWW.CENTOS.ORG/"
BUG_REPORT_URL="HTTPS://BUGS.CENTOS.ORG/"

CENTOS_MANTISBT_PROJECT="CENTOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="CENTOS"
REDHAT_SUPPORT_PRODUCT_VERSION="8"
范例:压缩df.txt文件里重复的空格
[16:35:03 root@centos8 data]#cat df.txt 
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          910244       0    910244   0% /dev
tmpfs             924700       0    924700   0% /dev/shm
tmpfs             924700    8852    915848   1% /run
tmpfs             924700       0    924700   0% /sys/fs/cgroup
/dev/sda2      104806400 2091232 102715168   2% /
/dev/sda5       52403200  398592  52004608   1% /data
/dev/sda1         999320  122172    808336  14% /boot
tmpfs             184940       0    184940   0% /run/user/0
[16:35:09 root@centos8 data]#tr -s ' ' < df.txt 
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 910244 0 910244 0% /dev
tmpfs 924700 0 924700 0% /dev/shm
tmpfs 924700 8852 915848 1% /run
tmpfs 924700 0 924700 0% /sys/fs/cgroup
/dev/sda2 104806400 2091232 102715168 2% /
/dev/sda5 52403200 398592 52004608 1% /data
/dev/sda1 999320 122172 808336 14% /boot
tmpfs 184940 0 184940 0% /run/user/0
4.3.2多行重定向

使用 “<<终止词” 命令从键盘把多行重导向给STDIN,直到终止词位置之前的所有文本都发送给STDIN,有时被称为就地文本(here documents)
其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File),magedu等,其中EOF
比较常用

3.管道

3.1管道

管道(使用符号“|”表示)用来连接多个命令

格式:

命令1 | 命令2 | 命令3 |

功能说明:

  • 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN

  • 所有命令会在当前shell进程的子shell进程中执行

  • 组合多种工具的功能

    注意:STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现,格式如下

命令1 2>&1 | 命令2
命令1 |& 命令2

3.2tee命令

利用tee命令可以重定向到多个目标,经常配合管道符一起使用

格式:

命令1 | tee [-a ] 文件名 | 命令2

以上可以把命令1的STDOUT保存在文件中,做为命令2的输入
选项:
-a 追加
功能:

  • 保存不同阶段的输出
  • 复杂管道的故障排除
  • 同时查看和记录输出

第二周 用户组合权限管理

1.linux安全模型

资源分派:

  • Authentication:认证,验证用户身份

  • Authorization:授权,不同的用户设置不同权限

  • Accouting|Audition:审计

    当用户登录时,系统会自动分配令牌token,包括用户标识和组成员等信息

1.1 用户

Linux中每个用户是通过User Id (UID)来唯一标识的。

  • 管理员:root, 0

  • 普通用户:1-60000 自动分配

    ​ 系统用户:1-499 (CentOS 6以前), 1-999 (CentOS7以后)
    ​ 对守护进程获取资源进行权限分配
    ​ 登录用户:500+ (CentOS6以前), 1000+(CentOS7以后)
    ​ 给用户进行交互式登录使用

1.2 用户组

Linux中可以将一个或多个用户加入用户组中,用户组是通过Group ID(GID) 来唯一标识的。

  • 管理员组:root, 0
  • 普通组:
    系统组:1-499(CentOS 6以前), 1-999(CentOS7以后), 对守护进程获取资源进行权限分

    普通组:500+(CentOS 6以前), 1000+(CentOS7以后), 给用户使用

1.3 用户和组的关系

  • 用户的主要组(primary group):用户必须属于一个且只有一个主组,默认创建用户时会自动创建和用户名同名的组,做为用户的主要组,由于此组中只有一个用户,又称为私有组
  • 用户的附加组(supplementary group): 一个用户可以属于零个或多个辅助组

1.4安全上下文

Linux安全上下文Context:运行中的程序,即进程 (process),以进程发起者的身份运行,进程所能够访问资源的权限取决于进程的运行者的身份

比如:root 身份运行/bin/cat /etc/shadow和 wang的身份运行/bin/cat /etc/shadow ,得到的结果是不同的,shadow能否能被访问是由运行者的身份决定,非程序本身

2 用户和组的配置文件

2.1 用户和组的主要配置文件

  • /etc/passwd:用户及其属性信息(名称、UID、主组ID等)
  • /etc/shadow:用户密码及其相关属性
  • /etc/group:组及其属性信息
  • /etc/gshadow:组密码及其相关属性

2.2 passwd文件格式

login name:登录用名(wang)
passwd:密码 (x)
UID:用户身份编号 (1000)
GID:登录默认所在组编号 (1000)
GECOS:用户全名或注释
home directory:用户主目录 (/home/wang)
shell:用户默认使用shell (/bin/bash)

2.3 shadow文件格式

登录用名
用户密码:一般用sha512加密
从1970年1月1日起到密码最近一次被更改的时间
密码再过几天可以被变更(0表示随时可被变更)
密码再过几天必须被变更(99999表示永不过期)
密码过期前几天系统提醒用户(默认为一周)
密码过期几天后帐号会被锁定
从1970年1月1日算起,多少天后帐号失效

更改密码加密算法:

authconfig --passalgo=sha256 --update

密码的安全策略

  • 足够长
  • 使用数字、大写字母、小写字母及特殊字符中至少3种
  • 使用随机密码
  • 定期更换,不要使用最近曾经使用过的密码

2.4 group文件格式

群组名称:就是群组名称
群组密码:通常不需要设定,密码是被记录在 /etc/gshadow
GID:就是群组的 ID
以当前组为附加组的用户列表(分隔符为逗号)

2.5 gshdow文件格式

群组名称:就是群的名称
群组密码:
组管理员列表:组管理员的列表,更改组密码和成员
以当前组为附加组的用户列表:多个用户间用逗号分隔

2.6 文件操作

  • vipw和vigr
  • pwck和grpck

3 用户和组管理命令

用户管理命令

  • useradd
  • usermod
  • userdel

组帐号维护命令

  • groupadd
  • groupmod
  • groupdel

3.1 用户创建

useradd 命令可以创建新的Linux用户

格式:

useradd [options] LOGIN

常见选项:

-u UID
-o 配合-u 选项,不检查UID的唯一性
-g GID 指明用户所属基本组,可为组名,也可以GID
-c "COMMENT“ 用户的注释信息
-d HOME_DIR 以指定的路径(不存在)为家目录
-s SHELL 指明用户的默认shell程序,可用列表在/etc/shells文件中
-G GROUP1[,GROUP2,...] 为用户指明附加组,组须事先存在
-N 不创建私用组做主组,使用users组做主组
-r 创建系统用户 CentOS 6之前: ID<500,CentOS 7以后: ID<1000
-m 创建家目录,用于系统用户
-M 不创建家目录,用于非系统用户

显示或更改默认设置

useradd -D
useradd –D -s SHELL
useradd –D –b BASE_DIR
useradd –D –g GROUP

新建用户的相关文件

  • /etc/default/useradd
  • /etc/skel/*
  • /etc/login.defs

批量创建用户

newusers passwd格式文件

批量修改用户口令

echo username:passwd | chpasswd

3.2 用户属性修改

usermod 命令可以修改用户属性

格式:

usermod [OPTION] login

常见选项:

-u UID: 新UID
-g GID: 新主组
-G GROUP1[,GROUP2,...[,GROUPN]]]:新附加组,原来的附加组将会被覆盖;若保留原有,则要同时使用-a选项
-s SHELL:新的默认SHELL
-c 'COMMENT':新的注释信息
-d HOME: 新家目录不会自动创建;若要创建新家目录并移动原家数据,同时使用-m选项
-l login_name: 新的名字
-L: lock指定用户,在/etc/shadow 密码栏的增加 !
-U: unlock指定用户,将 /etc/shadow 密码栏的 ! 拿掉
-e YYYY-MM-DD: 指明用户账号过期日期
-f INACTIVE: 设定非活动期限

3.3删除用户

userdel可以删除linux用户

格式:

userdel [OPTION]... Login

常见选项

f, --force 强制
-r, --remove 删除用户家目录和邮箱

3.4查看用户相关的ID信息

id命令可以查看用户的UID,GID等相关信息

id [OPTION]... [USER]

常见选项:

-u: 显示UID
-g: 显示GID
-G: 显示用户所属的组的ID
-n: 显示名称,需配合ugG使用

3.5切换用户或以其它用户身份执行命令

su: 即switch user,命令可以切换用户身份,并且以指定用户的身份执行命令

格式:

su [options...] [-] [user [args...]]

切换用户的方式:

  • su UserName:非登录式切换,即不会读取目标用户的配置文件,不改变当前工作目录
  • su - UserName:登录式切换,会读取目标用户的配置文件,切换至家目录,完全切换

说明:root su至其他用户无须密码;非root用户切换时需要密码

换个身份执行命令:

su [-] UserName -c 'COMMAND
常见选项:
-l --login su -l UserName 相当于 su - UserName

3.6设置密码

passwd可以修改用户密码

格式:

passwd [OPTIONS] UserName
常用选项:
-d:删除指定用户密码
-l:锁定指定用户
-u:解锁指定用户
-e:强制用户下次登录修改密码
-f:强制操作
-n mindays:指定最短使用期限
-x maxdays:最大使用期限
-w warndays:提前多少天开始警告
-i inactivedays:非活动期限
--stdin:从标准输入接收用户密码

3.7修改用户密码策略

chage可以修改用户密码策略

格式:

chage [OPTION]... LOGIN
常见选项:
-d LAST_DAY
-m --mindays MIN_DAYS
-M --maxdays MAX_DAYS
-W --warndays WARN_DAYS
-I --inactive INACTIVE 密码过期后的宽限期
-E --expiredate EXPIRE_DATE 用户的有效期
-l 显示密码策略

3.8用户相关的其他命令

  • chfn 指定个人信息
  • chsh 指定shell
  • finger 可看用户个人信息

3.9创建组

groupadd实现创建组

格式:

groupadd [OPTION]... group_name
常见选项:
-g GID 指明GID号;[GID_MIN, GID_MAX]
-r 创建系统组,CentOS 6之前: ID<500,CentOS 7以后: ID<1000

3.10修改组

组属性修改:groupmod

格式:

groupmod [OPTION]... group
常见选项:
-n group_name: 新名字
-g GID: 新的GID

3.11删除组

groupctl可以删除组

格式:

groupdel [options] GROUP
常见选项:
 -f, --force 强制删除,即使是用户的主组也强制删除组

3.12更改组密码

组密码:passwd

格式:

gpasswd [OPTION] GROUP
常见选项:
-a user 将user添加至指定组中
-d user 从指定组中移除用户user
-A user1,user2,... 设置有管理权限的用户列表

3.13临时切换主组

newgrp命令可以临时切换主组, 如果用户本不属于此组,则需要组密码

格式:

newgrp [-] [group]
如果使用 - 选项,可以初始化用户环境

3.14更改和查看组成员

groupmems可以管理组成员关系

格式:

groupmems [options] [action]
常见选项:
-g, --group groupname 更改为指定组 (只有root)
actions:
-a, --add username 指定用户加入组
-d, --delete username 从组中删除用户
-p, --purge 从组中清除所有成员
 -l, --list 显示组成员列表

groups 可查看用户组关系

格式

#查看用户所属组列表
groups [OPTION].[USERNAME]...

4.文件权限管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C4ZfBXov-1596963218107)(C:\Users\12550\Pictures\Camera Roll\45.png)]

4.1文件所有者和属组属性操作

  • 设置文件的所有者chown

chown 命令可以修改文件的属主,也可以修改文件属组

格式:

chown [OPTION]... [OWNER][:[GROUP]] FILE...
chown [OPTION]... --reference=RFILE FILE...

用法说明:

OWNER 只修改所有者
OWNER:GROUP 同时修改所有者和属组
:GROUP 只修改属组,冒号也可用 . 替换
-R: 递归 
--reference=RFILE 参考指定的的属性,来修改 
  • 设置文件的属组信息chgrp

chgrp 命令可以只修改文件的属组

格式:

chgrp [OPTION]... GROUP FILE...
chgrp [OPTION]... --reference=RFILE FILE...
-R递归

4.2文件权限

  • 文件权限说明

文件的权限主要针对三类对象进行定义

owner 属主, u
group 属组, g
other 其他, o

注意:用户的最终权限是从左向右顺序匹配的,即,所有者,所属组,其他人,一旦匹配权限立即生效,不再向右查看其权限

每个文件针对每类访问者都定义了三种权限

  • 对文件的权限
r Readable        #可使用文件查看类工具,比如cat可以查看其内容
w Writable 		  #可修改其内容
x eXcutable       #可以把此文件提请内核启动为一个进程,即可以执行(运行)此文件(此文件的内容必须是可执行的)
  • 对目录的权限说明
r	可以使用ls查看此目录中文件列表
w 	可在此目录中创建文件,也可删除此目录中的文件
x 	可以使用ls -l查看此目录中文件元数据(须配合r),可以cd进入此目录
X 	只给目录x权限,不给无执行权限的文件x权限
  • 数字法的权限

八进制数字

--- 000 0
--x 001 1
-w- 010 2
-wx 011 3
r-- 100 4
r-x 101 5
rw- 110 6
rwx 111 7
  • 修改文件权限chmod

格式:

chmod [OPTION]... MODE[,MODE]... FILE...
chmod [OPTION]... OCTAL-MODE FILE...
chmod [OPTION]... --reference=RFILE FILE...

说明:

MODE:who opt permission
who=u,g,o,a
opt:+,-,=
permission:r,w,x

修改一类用户的所有权限
u= g= o= ug= a= u=,g=

修改一类用户某位或某些位权限
u+ u- g+ g- o+ o- a+ a- + -

-R: 递归修改权限

4.3新建文件和目录的默认权限

umask的值可以用来保留在创建文件权限

实现方式:

  • 新建文件的默认权限: 666-umask,如果所得结果某位存在执行(奇数)权限,则将其权限+1,偶数不变
  • 新建目录的默认权限: 777-umask
  • 非特权用户umask默认是 002
  • root的umask 默认是 022

查看umask

umask		#模式方式显示
umask -S	#输出可被调用
umask -p

修改umask

umask #

持久保存umask

  • 全局设置:/etc/bashrc
  • 用户设置:~/.bashrc

4.4linux系统上的特殊权限

前面介绍了三种常见的权限:r, w, x 还有三种特殊权限:SUID, SGID, Sticky

4.4.1 特殊权限SUID

前提:进程有属主和属组;文件有属主和属组

  • 任何一个可执行程序文件能不能启动为进程,取决发起者对程序文件是否拥有执行权限
  • 启动为进程之后,其进程的属主为发起者,进程的属组为发起者所属的组
  • 进程访问文件时的权限,取决于进程的发起者
    (a) 进程的发起者,同文件的属主:则应用文件属主权限
    (b) 进程的发起者,属于文件属组;则应用文件属组权限
    © 应用文件“其它”权限

二进制的可执行文件上SUID权限功能:

  • 任何一个可执行程序文件能不能启动为进程:取决发起者对程序文件是否拥有执行权限
  • 启动为进程之后,其进程的属主为原程序文件的属主
  • SUID只对二进制可执行程序有效
  • SUID设置在目录上无意义

SUID权限设定:

chmod u+s FILE...
chmod 6xxx FILE
chmod u-s FILE...
4.4.2 特殊权限SGID

二进制的可执行文件上SGID权限功能:

  • 任何一个可执行程序文件能不能启动为进程:取决发起者对程序文件是否拥有执行权限
  • 启动为进程之后,其进程的属组为原程序文件的属组

SGID权限设定:

chmod g+s FILE...
chmod 2xxx FILE
chmod g-s FILE...

目录上的SGID权限功能:

默认情况下,用户创建文件时,其属组为此用户所属的主组,一旦某目录被设定了SGID,则对此目录有写权限的用户在此目录中创建的文件所属的组为此目录的属组,通常用于创建一个协作目录

4.4.3 特殊权限 Sticky 位

具有写权限的目录通常用户可以删除该目录中的任何文件,无论该文件的权限或拥有权
在目录设置Sticky 位,只有文件的所有者或root可以删除该文件
sticky 设置在文件上无意义

Sticky权限设定:

chmod o+t DIR...
chmod 1xxx DIR
chmod o-t DIR.
4.4.4 特殊权限数字法

SUID SGID STICKY
000 0
001 1
010 2
011 3
100 4
101 5
110 6
111 7

范例;

chmod 4777 /tmp/a.txt

权限位映射
SUID: user,占据属主的执行权限位

  • s:属主拥有x权限
  • S:属主没有x权限

SGID: group,占据属组的执行权限位

  • s: group拥有x权限
  • S:group没有x权限

Sticky: other,占据other的执行权限位

  • t:other拥有x权限
  • T:other没有x权限

4.5设置文件的特殊属性

设置文件的特殊属性,可以防止root用户误操作删除或修改文件

不能删除,改名。更改

chattr +i

只能追加内容,不能删除,改名

chattr +a

显示特定属性

lsattr

4.6访问控制列表

  • ALC权限功能

ACL:Access Control List,实现灵活的权限管理
除了文件的所有者,所属组和其它人,可以对更多的用户设置权限
CentOS7 默认创建的xfs和ext4文件系统具有ACL功能
CentOS7 之前版本,默认手工创建的ext4文件系统无ACL功能,需手动增加

tune2fs –o acl /dev/sdb1
mount –o acl /dev/sdb1 /mnt/test

ACL生效顺序:
所有者,自定义用户,所属组|自定义组,其他人

ACL相关命令

setfacl 可以设置ACL权限
getfacl 可查看设置的ACL权限

mask 权限

  • mask只影响除所有者和other的之外的人和组的最大权限
  • mask需要与用户的权限进行逻辑与运算后,才能变成有限的权限(Effective Permission)
  • 用户或组的设置必须存在于mask权限设定范围内才会生效

备份和还原ACL

主要的文件操作命令cp和mv都支持ACL,只是cp命令需要加上-p 参数。但是tar等常见的备份工具是不会保留目录和文件的ACL信息

第二周文本处理工具和正则表达式

1.文本编辑工具之神VIM

1.1使用vim初步

vim命令格式

vim [OPTION]... FILE...

常用选项:
+# 打开文件后,让光标处于第#行的行首,+默认行尾
+/PATTERN 让光标处于第一个被PATTERN匹配到的行行首
-b file 二进制方式打开文件
-d file1 file2… 比较多个文件,相当于 vimdiff
-m file 只读打开文件
-e file 直接进入ex模式,相当于执行ex file 
-y file Easy mode (like “evim”,modeless),直接可以操作文件,ctrl+o;wq|q! 保存和不保存退出

说明:

  • 如果该文件存在,文件被打开并显示内容
  • 如果该文件不存在,当编辑后第一次存盘时创建它

三种主要模式和切换

三种常见模式:

  • 命令或普通(Normal)模式:默认模式,可以实现移动光标,剪切/粘贴文本
  • 插入(Insert)或编辑模式:用于修改文本
  • 扩展命令(extended command )或命令(末)行模式:保存,退出等

模式转换

  • 命令模式 --> 插入模式
    i insert, 在光标所在处输入
    I 在当前光标所在行的行首输入
    a append, 在光标所在处后面输入
    A 在当前光标所在行的行尾输入
    o 在当前光标所在行的下方打开一个新行
    O 在当前光标所在行的上方打开一个新行
  • 插入模式 — ESC-----> 命令模式
  • 命令模式 ---- : ----> 扩展命令模式
  • 扩展命令模式 ----ESC,enter----> 命令模式

1.2扩展命令模式

1.2.1扩展命令模式基本命令
w 			写(存)磁盘文件
wq 			写入并退出
x 			写入并退出
X   		加密
q 			退出
q! 	   	   不存盘退出,即使更改都将丢失
r     		filename 读文件内容到当前文件中
w   	  	filename 将当前文件内容写入另一个文件
!command 	执行命令
r!command 	读入命令的输出
1.2.2地址定界

格式:

:start_pos,end_pos cmd

#		# 具体第#行,例如2表示第2行
#,# 	从左侧#表示起始行,到右侧#表示结尾行
#,+# 	从左侧#表示的起始行,加上右侧#表示的行数,范例:2,+3 表示2到5行
.   	当前行
$ 		最后一行
.,$-1   当前行到倒数第二行
%     	全文, 相当于1,$

/pattern/       从当前行向下查找,直到匹配pattern的第一行,即:正则表达式
/pat1/,/pat2/   从第一次被pat1模式匹配到的行开始,一直到第一次被pat2匹配到的行结束
#,/pat/         从指定行开始,一直找到第一个匹配patttern的行结束
/pat/,$         向下找到第一个匹配patttern的行到整个文件的结尾的所有行

地址定界后跟一个编辑命令
d       删除
y       复制
w file: 将范围内的行另存至指定文件中
r file:在指定位置插入指定文件中的所有内容
1.2.3查找并替换

格式:

s/要查找的内容/替换为的内容/修饰符

要查找的内容:可使用正则表达式模式
替换为的内容:不能使用模式,但可以使用\1, \2, …等后向引用符号;还可以使用“&”引用前面查找时查找到的整个内容

修饰符:
i 		#忽略大小写
g 		#全局替换,默认情况下,每一行只替换第一次出现
gc 		#全局替换,每次替换前询问

说明:查找替换中的分隔符/可替换为其它字符,如:#,@

1.2.4定制vim的工作特性

扩展命令模式的配置只是对当前vim进程有效,可以将配置存放在文件中持久保存

  • 配置文件:
/etc/vimrc		#全局
~/.vimrc		#个人
  • 行号

    显示:set number,简写 set nu
    取消显示:set nonumber, 简写 set nonu

  • 忽略字符的大小写

    启用:set ignorecase,简写 set ic
    不忽略:set noic

  • 自动缩进

    启用:set autoindent,简写 set ai
    禁用:set noai

  • 复制保留格式

    启用:set paste
    禁用:set nopaste

  • 显示Tab和换行符 ^I 和$显示

    启用:set list
    禁用:set nolist

  • 高亮搜索

    启用:set hlsearch
    禁用:set nohlsearch

  • 语法高亮

    启用:syntax on
    禁用:syntax off

  • 文件格式

    启用windows格式:set fileformat=dos
    启用unix格式:set fileformat=unix
    简写 set ff=dos|unix

  • 设置文本宽度

    set textwidth=65 (vim only)
    set wrapmargin=15

  • 设置光标所在行的标识线

    启用:set cursorline,简写 set cul
    禁用:set nocursorline

  • 加密

    启用: set key=password
    禁用: set key=

  • 了解更多

    set 帮助
    :help option-list
    :set or :set all

1.3命令模式

命令模式功能强大,只是按键时,看不到输入,所以需要大量的记忆才能更好的使用。

1.31退出VIM

​ ZZ 保存退出
​ ZQ 不保存退出

1.3.2 光标跳转
  • 字符间跳转:
    h: 左 L: 右 j: 下 k: 上
    #COMMAND:跳转由#指定的个数的字符

  • 单词间跳转:

    w:下一个单词的词首
    e:当前或下一单词的词尾
    b:当前或前一个单词的词首
    #COMMAND:由#指定一次跳转的单词数

  • 当前页跳转:

    H:页首 M:页中间行 L:页底
    zt:将光标所在当前行移到屏幕顶端
    zz:将光标所在当前行移到屏幕中间
    zb:将光标所在当前行移到屏幕底端

  • 行首行尾跳转:

    ^ 跳转至行首的第一个非空白字符
    0 跳转至行首
    $ 跳转至行尾

  • 行间移动:
    #G 或者扩展命令模式下:# 跳转至由第#行
    G 最后一行
    1G, gg 第一行

  • 句间移动:

    ) 下一句 ( 上一句

  • 段落间移动:

    } 下一段 { 上一段

  • 命令模式翻屏操作

    Ctrl+f 向文件尾部翻一屏
    Ctrl+b 向文件首部翻一屏
    Ctrl+d 向文件尾部翻半屏
    Ctrl+u 向文件首部翻半屏

1.4.3 字符编辑

x 删除光标处的字符
#x 删除光标处起始的#个字符
xp 交换光标所在处的字符及其后面字符的位置
~ 转换大小写
J 删除当前行后的换行符

1.3.4 替换命令(replace)

r 替换光标所在处的字符
R 切换成REPLACE模式(在末行出现–REPLACE–提示),按ESC回到命令模式

1.3.5 删除命令(delete)

d 删除命令,可结合光标跳转字符,实现范围删除

d$ 删除到行尾

d^ 删除到非空行首

d0 删除到行首

dw

de

db

#COMMAND

#dd 多行删除

D:从当前光标位置一

直删除到行尾,等同于d$

1.3.6 复制命令(yank)

y 复制,行为相似于d命令
y$
y0
y^
ye
yw
yb
#COMMAND
yy:复制行
#yy 复制多行
Y:复制整行

1.3.7 信息粘贴命令(paste)

p 缓冲区存的如果为整行,则粘贴当前光标所在行的下方;否则,则粘贴至当前光标所在处的后面
P 缓冲区存的如果为整行,则粘贴当前光标所在行的上方;否则,则粘贴至当前光标所在处的前面

1.3.8 改变命令(change)

c: 删除后切换成插入模式
c$
c^
c0
cb
ce
cw
#COMMAND

cc:删除当前行并输入新内容,相当于S
#cc
C:删除当前光标到行尾,并切换成插入模式,相当于c$

1.3.9查找

/PATTERN:从当前光标所在处向文件尾部查找
?PATTERN:从当前光标所在处向文件首部查找
n:与命令同方向
N:与命令反方向

1.3.10 撤销更改

u 撤销最近的更改
#u 撤销之前多次更改
U 撤消光标落在这行后所有此行的更改
Ctrl - r 重做最后的“撤消”更改
. 重复前一个操作
#. 重复前一个操作#次

1.3.11 高级用法
<start position><command><end position>

常见Command:y 复制、d 删除、gU 变大写、gu 变小写

范例:

0y$ 命令
0 → 先到行头
y → 从这里开始拷贝
$ → 拷贝到本行最后一个字符

di" 光标在”“之间,则删除”“之间的内容
yi( 光标在()之间,则复制()之间的内容
vi[ 光标在[]之间,则选中[]之间的内容
dtx 删除字符直到遇见光标之后的第一个 x 字符
ytx 复制字符直到遇见光标之后的第一个 x 字符

1.4可视化模式

允许选择的文本块

  • v 面向字符
  • V 面向整行
  • ctrl-v 面向块

可视化键可用于与移动键结合使用
w ) } 箭头等
突出显示的文字可被删除,复制,变更,过滤,搜索,替换等

范例:

输入ctrl+v 进入可视化模式
输入 G 跳到最后1行,选中第一行
输入 I 切换至插入模式
输入 #
按 ESC 键

1.5多文件模式

vim FILE1 FILE2 FILE3 …
:next 下一个
:prev 前一个
:first 第一个
:last 最后一个
:wall 保存所有
:qall 不保存退出所有
:wqall保存退出所有

1.6 多窗口模式

  • 多文件分割

    vim -o|-O FILE1 FILE2 …
    -o: 水平或上下分割
    -O: 垂直或左右分割(vim only)
    在窗口间切换:Ctrl+w, Arrow

  • 单文件窗口分割

    Ctrl+w,s:split, 水平分割
    Ctrl+w,v:vertical, 垂直分割
    ctrl+w,q:取消相邻窗口
    ctrl+w,o:取消全部窗口
    :wqall 退出

1.7vim的寄存器

有26个命名寄存器和1个无命名寄存器,常存放不同的剪贴版内容,可以不同会话间共享
寄存器名称a,b,…,z,格式:“寄存器 放在数字和命令之间

范例

3"tyy 表示复制3行到t寄存器中
"tp 表示将t寄存器内容粘贴

未指定,将使用无命名寄存器

有10个数字寄存器,用0,1,…,9表示,0存放最近复制内容,1存放最近删除内容。当新的文本变更
和删除时,1转存到2,2转存到3,以此类推。数字寄存器不能在不同会话间共享

1.8 标记和宏(macro)

ma 将当前位置标记为a,26个字母均可做标记, mb 、 mc 等等
'a 跳转到a标记的位置,实用的文档内标记方法,文档中跳跃编辑时很有用
qa 录制宏 a,a为宏的名称
q 停止录制宏
@a 执行宏 a
@@ 重新执行上次执行的宏

1.9编辑二进制文件

#以二进制方式打开文件
vim -b binaryfile
#扩展命令模式下,利用xxd命令转换为可读的十六进制
:%!xxd
#插入模式下,编辑二进制文件
#扩展命令模式下,利用xxd命令转换回二进制
:%!xxd -r
#保存退出

1.10帮助

:help
:help topic
Use :q to exit help
vimtutor

2.文本常见处理工具

2.1文件内容查看命令

  • 查看文本文件内容 cat
格式:
cat [OPTION]... [FILE]...

常见选项
-E:显示行结束符$
-A:显示所有控制符
-n:对显示出的每一行进行编号
-b:非空行编号
-s:压缩连续的空行成一行

nl 显示行号,相当于cat -b

tac 逆向显示文本内容

rev 将同一行的内容逆向显示

  • 查看非文本内容

    hexdump

    od 即dump files in octal and other formats

    xxd

2.2分页查看文件内容

more 可以实现分页查看文件,可以配合管道实现输出信息的分页

格式:
more [options] file...
选项:
-d: 显示翻页及退出提示
less 也可以实现分页查看文件或STDIN输出

查看时有用的命令包括:
/文本 搜索 文本
n/N 跳到下一个 或 上一个匹配
less 命令是man命令使用的分页器

2.3显示文本前或后行内容

head 可以显示文件或标准输入的前面行

格式:
head [OPTION]... [FILE]...
选项:
-c 		# 指定获取前#字节
-n 		# 指定获取前#行
-# 		同上

tail 和head 相反,查看文件或标准输入的倒数行

格式:
tail [OPTION]... [FILE]...
选项:
-c # 指定获取后#字节
-n # 指定获取后#行
-# 同上
-f 跟踪显示文件fd新追加的内容,常用日志监控,相当于 --follow=descriptor,当文件删除再新建同名文
件,将无法继续跟踪文件
-F 跟踪文件名,相当于--follow=name --retry,当文件删除再新建同名文件,将可以继续跟踪文件
tailf 类似tail –f,当文件不增长时并不访问文件

2.4 按列抽取文本

cut 命令可以提取文本文件或STDIN数据的指定列

格式:
cut [OPTION]... [FILE]...
选项:
-d DELIMITER: 指明分隔符,默认tab
 -f FILEDS:
 			#: 第#个字段,例如:3
 			#,#[,#]:离散的多个字段,例如:1,3,6
 			#-#:连续的多个字段, 例如:1-6
 			混合使用:1-3,7
-c 按字符切割
--output-delimiter=STRING指定输出分隔符

2.5合并多个文件

paste 合并多个文件同行号的列到一行

格式:
paste [OPTION]... [FILE]...
选项:
d 分隔符:指定分隔符,默认用TAB
-s : 所有行合成一行显示

2.6分析文本的工具

文本数据统计:wc
整理文本:sort
比较文件:difpatch

2.6.1 收集文本统计数据

wc 命令可用于统计文件的行总数、单词总数、字节总数和字符总数 可以对文件或STDIN中的数据统计

常用选项 :

-l 只计数行数
-w 只计数单词总数
-c 只计数字节总数
-m 只计数字符总数
-L 显示文件中最长行的长度
2.6.2文本排序sort

把整理过的文本显示在STDOUT,不改变原始文件

格式:
sort [options] file(s)
常用选项:
 r 		执行反方向(由上至下)整理
-R 		随机排序
-n 		执行按数字大小整理
-f 		选项忽略(fold)字符串中的字符大小写
-u 		选项(独特,unique)删除输出中的重复行
-t c 	选项使用c做为字段界定符
-k # 	选项按照使用c字符分隔的 # 列来整理能够使用多次
2.6.3去重uniq

uniq命令从输入中删除前后相接的重复的行

格式:
uniq [OPTION]... [FILE]...
常见选项:
-c: 显示每行重复出现的次数
-d: 仅显示重复过的行
-u: 仅显示不曾重复的行

uniq常和sort 命令一起配合使用:
2.6.4比较文本

diff 命令比较两个文件之间的区别

3.正则表达式

REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)
不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能
正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等
正则表达式分两类:
基本正则表达式:BRE
扩展正则表达式:ERE

正则表达式引擎:
采用不同算法,检查处理正则表达式的软件模块,如:PCRE(Perl Compatible Regular
Expressions)
正则表达式的元字符分类:字符匹配、匹配次数、位置锚定、分组
帮助:man 7 regex

3.1基本正则表达式元字符

3.1.1字符匹配
.   		匹配任意单个字符
[]   		匹配指定范围内的任意单个字符,示例:[wang]   [0-9]   [a-z]   [a-zA-Z]
[^] 		匹配指定范围外的任意单个字符,示例:[^wang]

[:alnum:] 	字母和数字
[:alpha:] 	代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 	小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 	大写字母
[:blank:] 	空白字符(空格和制表符)
[:space:] 	水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 	不可打印的控制字符(退格、删除、警铃...)
[:digit:] 	十进制数字
[:xdigit:]	十六进制数字
[:graph:] 	可打印的非空白字符
[:print:] 	可打印字符
[:punct:] 	标点符号
3.1.2匹配次数

用在要指定次数的字符后面,用于指定前面的字符要出现的次数

* 		匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 		任意长度的任意字符
\? 		匹配其前面的字符0或1次,即:可有可无
\+ 		匹配其前面的字符至少1次,即:肯定有
\{n\} 	匹配前面的字符n次
\{m,n\} 匹配前面的字符至少m次,至多n次
\{,n\} 	匹配前面的字符至多n次
\{n,\} 	匹配前面的字符至少n次

3.1.3位置锚定

位置锚定可以用于定位出现的位置

^ 			行首锚定,用于模式的最左侧
$ 			行尾锚定,用于模式的最右侧
^PATTERN$ 	用于模式匹配整行
^$ 			空行
^[[:space:]]*$ 空白行
\< 或 \b 	词首锚定,用于单词模式的左侧
\> 或 \b 	词尾锚定,用于单词模式的右侧
\<PATTERN\>  匹配整个单词

范例:


3.1.4分组其它

分组:() 将一个或多个字符捆绑在一起,当作一个整体处理,如:(root)+ 分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, …

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身

或者:\

3.2扩展正则表达式

3.2.1字符匹配元字符
. 			任意单个字符
[wang] 		指定范围的字符
[^wang] 	不在指定范围的字符
[:alnum:] 	字母和数字
[:alpha:] 	代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 	小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 	大写字母
[:blank:] 	空白字符(空格和制表符)
[:space:] 	水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 	不可打印的控制字符(退格、删除、警铃...)
[:digit:] 	十进制数字
[:xdigit:]	十六进制数字
[:graph:] 	可打印的非空白字符
[:print:] 	可打印字符
[:punct:] 	标点符号
3.2.2次数匹配
*    	匹配前面字符任意次
? 		0或1次
+ 		1次或多次
{n} 	匹配n次
{m,n} 	至少m,至多n次
3.2.3位置锚定
^ 行首
$ 行尾
\<, \b 语首
\>, \b 语尾
3.2.4分组其它
() 			分组
后向引用:	\1, \2, ...
| 			或者
a|b 		#a或b
C|cat 		#C或cat
(C|c)at 	#Cat或cat

扩展正则表达式练习

1、显示三个用户root、mage、wang的UID和默认shell

2、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行

3、使用egrep取出/etc/rc.d/init.d/functions中其基名

4、使用egrep取出上面路径的目录名

5、统计last命令中以root登录的每个主机IP地址登录次数

6、利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255

7、显示ifconfig命令结果中所有IPv4地址

8、将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前面

4.文本处理三剑客

grep 命令主要对文本的(正则表达式)行基于模式进行过滤

sed:stream editor,文本编辑工具

awk:Linux上的实现gawk,文本报告生成器

4.1文本处理三剑客之grep

grep: Global search REgular expression and Print out the line

作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行

模式:由正则表达式字符及文本字符所编写的过滤条件

格式:
grep [OPTIONS] PATTERN [FILE...]

常见选项:
--color=auto 对匹配到的文本着色显示
-m # 匹配#次后停止
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息
-A # after, 后#行
-B # before, 前#行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系,如:grep –e ‘cat ’ -e ‘dog’ file
-w 匹配整个单词
-E 使用ERE,相当于egrep
-F 相当于fgrep,不支持正则表达式
-f file 根据模式文件处理
-r 递归目录,但不处理软链接
-R 递归目录,但处理软链接

范例:

SHELL脚本编程

1.编程基础

1.1程序组成

  • 程序:算法+数据结构
  • 数据:是程序的核心
  • 数据结构:数据在计算机中的类型和组织方式
  • 算法:处理数据的方式

1.2程序编程风格

面向过程语言

  • 做一件事,排出个步骤,第一步干什么,第二步干什么,如果出现情况A,做什么处理,如果出现情况B,做什么处理
  • 问题规模小,可以步骤化,按部就班处理
  • 一直指令为中心,数据服务于指令
  • C,shell

面向对象语言

  • 一种认识世界、分析世界的方法论。将万事万物抽象为各种对象
  • 类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合
  • 对象是类的具象,是一个实体
  • 问题规模大,是一个实体
  • 以数据为中心,指令服务于数据
  • java,c#,python,golang等

1.3编程语言

计算机:运行二进制指令

编程语言:人与计算机之间交互的语言。分为两种:低级语言和高级语言

  • 低级编程语言:

    机器:二进制的0和1的序列,称为机器指令。与自然语言差异太大,难懂、难写
    汇编:用一些助记符号替代机器指令,称为汇编语言
    如:ADD A,B 将寄存器A的数与寄存器B的数相加得到的数放到寄存器A中
    汇编语言写好的程序需要汇编程序转换成机器指令
    汇编语言稍微好理解,即机器指令对应的助记符,助记符更接近自然语言

  • 高级编程语言:

    编译:高级语言–>编译器–>机器代码文件–>执行,如:C,C++
    解释:高级语言–>执行–>解释器–>机器代码,如:shell,python,php,JavaScript,perl

1.4编程逻辑处理方式

三种逻辑处理方式

  • 顺序执行:程序从上到下顺序执行
  • 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
  • 循环执行:程序执行过程中需要重复执行多次某段语句

2.shell脚本语言的基础用法

2.1shell脚本的用途

  • 将简单的命令组合完成复杂的工作,自动化执行命令,提高工作效率
  • 减少手工命令的重复输入,一定程度上避免人为错误
  • 将软件或应用的安装及配置实现标准化
  • 用于实现日常性的、重复性的运维工作,如:文件打包压缩备份,监控系统运行状态并实现告警

2.2shell脚本基本结构

shell脚本编程:是基于过程式、解释执行的语言

编程语言的基本结构:

  • 各种系统命令的组合
  • 数据存储、变量、数组
  • 表达式:a+b
  • 控制语句: if

shell脚本:包含一些命令或声明,并符合一定格式的文本文件

格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl 

2.2创建shell脚本的过程

第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列:#!
示例:

#!/bin/bash 

添加注释,注释以#开头

第二步:加执行权限

给予执行权限,在命令行上指定脚本的绝对或相对路径

第三步:运行脚本

直接运行解释器,将脚本作为解释器程序的参数运行

2.3脚本注释规范

1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息
6、该程序的作用,及注意事项
7、最后是各版本的更新简要说明

2.4shell脚本调试

只检测脚本中的语法错误,但无法检查出错误命令,但不真正执行脚本

bash -n /path/to/some_script

t调试并执行

bash -x /path/to/some_script

脚本常见的三种错误:

语法错误:会导致后续的命令不继续执行,可以用bash -n检查错误,提示的出错行不一定是准确的

命令错误:默认后续的命令还会继续执行,用bash -n无法检查出来,可以使用bash -x进行观察

逻辑错误:只能使用bash -x进行观察

第一个脚本:备份etc文件

[17:30:42 root@centos8 data ]$cat backup.sh 
#!/bin/bash
COLOR='echo -e \e[1;33m'
END='\e[0m'
SRC=/etc
BACKUP=backup
DATE=`date +%F_%T`

${COLOR}starting backup....$END
 sleep 2

cp -av $SRC	/data${SRC}_${BACKUP}_${DATE}

${COLOR}backup is finished$END

2.5变量

变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据

2.5.1 变量类型

**变量类型:**普通变量,内置变量,环境变量,位置变量,只读变量

  • 内置变量,如:PS1,PATH,HISTSIZE
  • 用户自定义变量

不同的变量存放的数据不同,决定了以下

  1. 数据存储方式
  2. 参与的运算
  3. 表示的数据范围

变量数据类型:

  • 字符
  • 数值:整型、浮点型,bash 不支持浮点数
2.5.2 编程语言分类

静态和动态语言

  • 静态编译语言:使用变量前,先声明变量类型,之后类型不能改变,在编译时检查,如:java,c
  • 动态编译语言:不用事先声明,可随时改变类型2.5.3,如:bash,Python

强类型和弱类型语言

  • 强类型语言:不同类型数据操作,必须经过强制转换才同一类型才能运算,如java , c# ,python
    如:以下python代码
    print(‘magedu’+ 10) 提示出错,不会自动转换类型
    print(‘magedu’+str(10)) 结果为magedu10,需要显示转换类型
  • 弱类型语言:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会
    自动进行隐式类型转换;变量无须事先定义可直接调用
    如:bash ,php,javascript
2.5.3shell中变量命名法则
  • 不能使程序中的保留字:如:if, for
  • 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”
  • 见名知义,用英文名字,并体现出实际作用
  • 统一命名规则:驼峰命名法, studentname,大驼峰StudentName 小驼峰studentName
  • 变量名大写
  • 局部变量小写
  • 函数名小写
2.5.4变量定义和引用

变量的生效范围等标准划分变量类型

  • 普通变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效
  • 环境变量:生效范围为当前shell进程及其子进程
  • 本地变量:生效范围为当前shell进程中某代码片断,通常指函数

变量赋值

name='value'

value可以是以下多种形式

直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)

变量引用:

$name
${name}

弱引用和强引用

  • "$name " 弱引用,其中的变量引用会被替换为变量值
  • '$name ’ 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

范例:变量的赋值方法和引用

[10:39:37 root@centos8 ~ ]$NAME=rc
[10:45:20 root@centos8 ~ ]$echo $NAME
rc
[10:45:32 root@centos8 ~ ]$echo I am $NAME
I am rc
[10:45:55 root@centos8 ~ ]$echo  "I am $NAME"
I am rc
[10:46:07 root@centos8 ~ ]$echo  'I am $NAME'
I am $NAME

[10:46:19 root@centos8 ~ ]$NAME=$USER
[10:48:11 root@centos8 ~ ]$echo $NAME
root

[10:49:34 root@centos8 ~ ]$seq 10
1
2
3
4
5
6
7
8
9
10
[10:51:02 root@centos8 ~ ]$NUM=`seq 10`
[10:51:13 root@centos8 ~ ]$echo $NUM
1 2 3 4 5 6 7 8 9 10
[10:51:15 root@centos8 ~ ]$echo "$NUM"
1
2
3
4
5
6
7
8
9
10
[10:52:46 root@centos8 ~ ]$NAME="
> rc
> ruchao
> "
[10:54:01 root@centos8 ~ ]$echo $NAME
rc ruchao
[10:54:10 root@centos8 ~ ]$echo "$NAME"

rc
ruchao

范例:变量引用

[10:54:23 root@centos8 ~ ]$NAME=RC
[11:11:16 root@centos8 ~ ]$AGE=24
[11:11:29 root@centos8 ~ ]$echo $NAME
RC
[11:11:36 root@centos8 ~ ]$echo $AGE
24
[11:11:42 root@centos8 ~ ]$echo $NAME $AGE
RC 24
[11:11:54 root@centos8 ~ ]$echo $NAME$AGE
RC24
[11:12:02 root@centos8 ~ ]$echo $NAME_$AGE
24
[11:12:09 root@centos8 ~ ]$echo ${NAME}_$AGE
RC_24

范例:变量追加赋值

[11:12:16 root@centos8 ~ ]$echo $NAME
RC
[11:14:44 root@centos8 ~ ]$NAME+=:CEO
[11:15:21 root@centos8 ~ ]$echo $NAME
RC:CEO

范例:利用变量实现动态命令

[11:16:23 root@centos8 ~ ]$CMD=hostname
[11:16:39 root@centos8 ~ ]$$CMD
centos8
[11:17:12 root@centos8 ~ ]$echo `$CMD`
centos8

显示已定义的所有变量:

set
删除变量
unset name
2.5.5 环境变量

环境变量:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量
  • 一般子进程修改从父进程继承的变量,会将新的值床底给子进程的变量
  • 一般只在系统配置文件中使用,在脚本中较少使用
#观察进程的父子关系
pstree -p
#查看当前所在shell
echo $BASHPID
#取代当前进程
exec CDM

变量声明和赋值

#声明和赋值
export name=VALUE
declare -x name=VALUE

#或者分两步实现
name=VALUE
expot name

变量引用

$name
${name}

显示所有环境变量

env
printenv
export
declare -x

删除变量:

unset name

bash内建的环境变量:

PATH
SHELL
USER
UID
HOME
PWD
SHLVL
LANG
MAIL
HOSTNAME
HISTSIZE
_   下划线 表示前一命令的最后一个参数
2.5.6 只读变量

只读变量:只能声明定义,但后续不能修改和删除

声明只读变量:

readonly name
declare  -r name

查看只读变量:

readonly [-p]
declare -r
2.5.7位置变量

位置变量:在bash shell中内置的变量, 在脚本代码中调用通过命令行传递给脚本的参数

$1, $2, ... 对应第1个、第2个等参数,shift [n]换位置
$0 命令本身,包括路径
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
注意:$@ $* 只在被双引号包起来的时候才会有差异

清空所有位置变量

set --
2.5.8退出状态码变量

进程执行后,将使用变量 ? 保 存 状 态 码 的 相 关 数 字 , 不 同 的 值 反 应 成 功 或 失 败 , ? 保存状态码的相关数字,不同的值反应成功或失败, ??取值范例 0-255

$?的值为0 代表成功
$?的值是1到255   代表失败

用户可以在脚本中使用以下命令自定义退出状态码

exit [n]

注意:

  • 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
  • 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
2.5.9展开命令行

展开命令执行顺序

把命令行分成单个命令词
展开别名
展开大括号的声明({})
展开波浪符声明(~)
命令替换$() 和 ``
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/0重导向(<>)
运行命令

防止扩展

反斜线(\)会使随后的字符按原意解释

加引号来防止扩展

单引号(’’)防止所有扩展
双引号(”“)也可防止扩展,但是以下情况例外:$(美元符号)

变量扩展

`` : 反引号,命令替换
\:反斜线,禁止单个字符扩展
!:叹号,历史命令替换
2.5.10脚本安全和set

set 命令:可以用来定制shell环境
$- 变量

  • h:hashall,打开选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
  • i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的
  • m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等
  • B:braceexpand,大括号扩展
  • H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令

set 命令实现脚本安全

  • -u 在扩展一个没有设置的变量时,显示错误信息, 等同set -o nounset

  • -e 如果一个命令返回一个非0退出状态值(失败)就退出, 等同set -o errexit

  • -o option 显示,打开或者关闭选项
    显示选项:set -o
    打开选项:set -o 选项
    关闭选项:set +o 选项

  • -x 当执行命令时,打印命令及其参数,类似 bash -x

2.6格式化输出printf

格式:

printf "指定的格式" "文本1" ”文本2“……

常用格式替换符

替换符功能
%s字符串
%f浮点格式
%b相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转 义
%cASCII字符,即显示对应参数的第一个字符
%d,%i十进制整数
%o八进制值
%u不带正负号的十进制值
%x十六进制值(a-f)
%X十六进制值(A-F)
%%表示%本身

说明:%s 中的数字代表此替换符中的输出字符宽度,不足补空格,默认是右对齐,%-10s表示10个字 符宽,- 表示左对齐

常用转义字符

转义符功能
\a警告字符,通常为ASCII的BEL字符
\b后退
\f换页
\n换行
\r回车
\t水平制表符
\v垂直制表符
\表示\本身

2.7算术运算

shell允许在某些情况下对算数表达式进行求值,比如:le和declare内置命令,(())复合命令和算数扩展。

注意:bash只支持整数,不支持小数

bash中的算术运算:
+, -, *, /, %取模(取余), **(乘方)
乘法符号有些场景中需要转义

实现算术运算:

(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 ...)
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc 

内建的随机数生成器变量

$RANDOM   取值范围:0-32767

范例:

#生成0-49之间的随机数
[16:20:22 root@centos8 ~ ]$echo [RANDOM%50]
[4533%50]
[16:20:37 root@centos8 ~ ]$echo $[RANDOM%50]
31

#随机颜色
[16:42:30 root@centos8 ~ ]$echo -e "\e[1;$[RANDOM%7+31]mRC\e[0m"
RC
[16:42:32 root@centos8 ~ ]$echo -e "\e[1;$[RANDOM%7+31]mRC\e[0m"
RC

增强型赋值

+= i+=10 相当于 i=i+10
-= i-=j   相当于 i=i-j
*=
/=
%=
++ i++,++i   相当于 i=i+1
-- i--,--i   相当于 i=i-1
#格式:
let varOPERvalue
#范例:
[18:38:50 root@centos8 ~ ]$let i=10*2
[19:16:47 root@centos8 ~ ]$echo $i
20
[19:16:59 root@centos8 ~ ]$((j=i+10))
[19:17:25 root@centos8 ~ ]$echo $j
30
#范例:自加,自减
[08:53:21 root@centos8 ~ ]$unset  i j;i=1;let j=i++;echo "i=$i j=$j"
i=2 j=1
[09:06:19 root@centos8 ~ ]$unset  i j;i=1;let j=++i;echo "i=$i j=$j"
i=2 j=2

2.8 逻辑运算

true ,false

1,真
0,假

**与:&:**和0相与,结果为0,和1相与,结果保留原值

1 与 1 = 1
1 与 0 = 0
0 与 1 = 0
0 与 0 = 0

**或:|:**和1相或,结果为1 ,和0相或,结果保留原值

1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0

非:!

!1 = 0
!0 =1

异或:^

相同为假,不同为真

两个数字X、Y异或得到结果Z,Z再和任意两者之一异或,将得到另外一个值

1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0

范例:
[09:56:33 root@centos8 ~ ]#vi /etc/profile.d/env.sh 
[10:06:13 root@centos8 ~ ]#x=110
[10:06:59 root@centos8 ~ ]#y=120
[10:07:02 root@centos8 ~ ]#temp=$x
[10:07:14 root@centos8 ~ ]#x=$y
[10:08:13 root@centos8 ~ ]#y=$temp
[10:08:57 root@centos8 ~ ]#echo $x
120
[10:09:03 root@centos8 ~ ]#echo $y
110
范例:
[10:13:38 root@centos8 ~ ]#x=110 y=120;let x=$[x^y];let y=$[x^y];let x=$[x^y];echo x=$x y=$y
x=120 y=110
短路运算
  • 短路与&&

     CMD1 短路与 CMD2
     
    第一个CMD1结果为 0 (),总的结果必定为0,因此不需要执行CMD2
    第一个CMD1结果为 1 (),第二个CMD2必须要参与运算,才能得到最终的结果
    
  • 短路或 ||

    CMD1 短路或 CMD2
    
    第一个CMD1结果为1 (),总的结果必定为1,因此不需要执行CMD2
    第一个CMD1结果为0 (),第二个CMD2 必须要参与运算,,才能得到最终的结果
    

2.9条件测试命令

条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程

评估布尔声明,以便用在条件性执行中

若真,则状态码变量 $?返回 0

若假,则 状态码变量$?返回 1

条件测试命令

  • test EXPRESSIO
  • [ EXPRESSION ] #和test等价,建议使用[ ]
  • [[ EXPRESSION ]] 增强版[ ] ,包含[ ]的功能,需要使用正则表达式或通配符的时候使用 [[ ]]

注意:EXPRESSION前后必须有空白字符

[10:16:29 root@centos8 ~ ]#help [
[: [ arg... ]
    Evaluate conditional expression.
    
    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.
[11:08:57 root@centos8 ~ ]#help \[\[
[[ ... ]]: [[ expression ]]
    Execute conditional command.
    
    Returns a status of 0 or 1 depending on the evaluation of the conditional
    expression EXPRESSION.  Expressions are composed of the same primaries used
    by the `test' builtin, and may be combined using the following operators:
    
      ( EXPRESSION )	Returns the value of EXPRESSION
      ! EXPRESSION		True if EXPRESSION is false; else false
      EXPR1 && EXPR2	True if both EXPR1 and EXPR2 are true; else false
      EXPR1 || EXPR2	True if either EXPR1 or EXPR2 is true; else false
    
    When the `==' and `!=' operators are used, the string to the right of
    the operator is used as a pattern and pattern matching is performed.
    When the `=~' operator is used, the string to the right of the operator
    is matched as a regular expression.
    
    The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to
    determine the expression's value.
    
    Exit Status:
    0 or 1 depending on value of EXPRESSION.    
2.9.1变量测试
#判断 NAME变量是否定义
[-v NAME]
3判断 NAME 变量是否定义并且是名称引用,bash4.4新特性
[-R NAME]
2.9.2数值测试
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
算数表达比较:
==  	相等
!=  	不相等
<=
>=
<
>
2.9.3 字符串测试
test和[ ]用法
-z STRING 	字符串是否为空,空为真,不空为假
-n STRING	字符串是否不空,不空为真,空为假
   STRING	同上
STRING1 = STRING2  是否等于,注意 = 前后有空格
STRING1 != STRING2  是否不等于
> 			ascii码是否大于ascii码
< 					是否小于
[[]]用法:
[[expression]]用法
== 左侧字符串是否和右侧的PATTERN相同
 	注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
 	注意: 此表达式用于[[ ]]中;扩展的正则表达式

建议:当使用正则表达式或通配符时使用[[ ]],其他情况一般使用[ ]

范例:在比较字符串时,建议将变量放在" "中

[12:25:48 root@centos8 ~ ]#NAME="I LOVE YOU"
[12:26:01 root@centos8 ~ ]#[ $NAME ]
-bash: [: LOVE: binary operator expected
[12:26:18 root@centos8 ~ ]#[ "$NAME" ]
[12:26:24 root@centos8 ~ ]#echo $?
0

范例:[[ ]]和通配符

[12:26:44 root@centos8 ~ ]#FILE=txt.log
[12:33:22 root@centos8 ~ ]#[[ $FILE=*.log ]]
[12:33:58 root@centos8 ~ ]#echo $?
0
[[ ]]中如果不想使用通配符*,只想表达*本身,可以用""引起来,也可以使用转义符\

范例:判断合理的考试成绩

[12:51:53 root@centos8 ~ ]#SCORE=101
[12:52:03 root@centos8 ~ ]#[[ $SCORE =~ ^(100|[0-9]{1,2})$ ]]
[12:52:09 root@centos8 ~ ]#echo $?
1
2.9.4文件测试

存在性测试

-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件

文件权限测试

-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

文件属性测试

-s FILE: 是否存在且非空
-t fd: fd 文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2

2.10 关于()和{ }

(CMD1;CMD2;…) 和 {CMD1;CMD2;…}都可以将多个命令组合在一起,批量执行

( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境, 帮助参看:man bash 搜索(list)
{ list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境, 帮助参看:man bash 搜索{ list; }

范例:

[12:17:23 root@centos8 ~ ]#name=mage;(echo $name;name=rc;echo $name);echo $name
mage
rc
mage
[12:17:33 root@centos8 ~ ]#name=mage;{ echo $name;name=rc;echo $name ;};echo $name
mage
rc
rc

2.11组合测试条件

第一种方式

[ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,结果才是真
[ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一个为真,结果 就为真
[ ! EXPRESSION ] 取反

说明:-a和-o需要使用测试命令进行,[[ ]]不支持

第二种方式

COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2
COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2
! COMMAND   非,取反

范例:

[15:46:36 root@centos8 data ]#[ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"
click

范例:

[15:49:03 root@centos8 data ]#cat ping.sh 
IP=172.16.0.123
ping -c1 -W1 $IP &> /dev/null && echo "$IP is up" || {  echo "$IP is
unreachable"; exit; }
echo "Script is finished"

范例:

[15:49:25 root@centos8 data ]#cat disk_check.sh 
USE=`df|grep '^/dev/sda'|tr -s ' ' %|cut -d% -f5|sort -nr|head -n1`
WARNING=10
(( USE > WARNING )) && echo disk warning | mail -s wawrning 1255090639@qq.com

2.12使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变 量,所有剩余单词都被分配给最后一个变量

格式:
read [options] [name ...]
常见选项:
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒

范例:

[16:37:24 root@centos8 data ]#read 
rc
[16:44:21 root@centos8 data ]#echo $REPLY
rc
[16:45:13 root@centos8 data ]#read X Y Z
a
[16:45:42 root@centos8 data ]#read X Y Z
a  b c
[16:45:56 root@centos8 data ]#echo $X
a
[16:46:02 root@centos8 data ]#echo $Y
b
[16:46:05 root@centos8 data ]#echo $Z
c
[16:48:02 root@centos8 data ]#read X Y Z <<<"I LOVE YOU"
[16:48:08 root@centos8 data ]#echo $X
I
[16:48:21 root@centos8 data ]#echo $Y
LOVE
[16:48:23 root@centos8 data ]#echo $Z
YOU

med.
When the `=~’ operator is used, the string to the right of the operator
is matched as a regular expression.

The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to
determine the expression's value.

Exit Status:
0 or 1 depending on value of EXPRESSION.    

#### 2.9.1变量测试

```bash
#判断 NAME变量是否定义
[-v NAME]
3判断 NAME 变量是否定义并且是名称引用,bash4.4新特性
[-R NAME]
2.9.2数值测试
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
算数表达比较:
==  	相等
!=  	不相等
<=
>=
<
>
2.9.3 字符串测试
test和[ ]用法
-z STRING 	字符串是否为空,空为真,不空为假
-n STRING	字符串是否不空,不空为真,空为假
   STRING	同上
STRING1 = STRING2  是否等于,注意 = 前后有空格
STRING1 != STRING2  是否不等于
> 			ascii码是否大于ascii码
< 					是否小于
[[]]用法:
[[expression]]用法
== 左侧字符串是否和右侧的PATTERN相同
 	注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
 	注意: 此表达式用于[[ ]]中;扩展的正则表达式

建议:当使用正则表达式或通配符时使用[[ ]],其他情况一般使用[ ]

范例:在比较字符串时,建议将变量放在" "中

[12:25:48 root@centos8 ~ ]#NAME="I LOVE YOU"
[12:26:01 root@centos8 ~ ]#[ $NAME ]
-bash: [: LOVE: binary operator expected
[12:26:18 root@centos8 ~ ]#[ "$NAME" ]
[12:26:24 root@centos8 ~ ]#echo $?
0

范例:[[ ]]和通配符

[12:26:44 root@centos8 ~ ]#FILE=txt.log
[12:33:22 root@centos8 ~ ]#[[ $FILE=*.log ]]
[12:33:58 root@centos8 ~ ]#echo $?
0
[[ ]]中如果不想使用通配符*,只想表达*本身,可以用""引起来,也可以使用转义符\

范例:判断合理的考试成绩

[12:51:53 root@centos8 ~ ]#SCORE=101
[12:52:03 root@centos8 ~ ]#[[ $SCORE =~ ^(100|[0-9]{1,2})$ ]]
[12:52:09 root@centos8 ~ ]#echo $?
1
2.9.4文件测试

存在性测试

-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件

文件权限测试

-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

文件属性测试

-s FILE: 是否存在且非空
-t fd: fd 文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2

2.10 关于()和{ }

(CMD1;CMD2;…) 和 {CMD1;CMD2;…}都可以将多个命令组合在一起,批量执行

( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境, 帮助参看:man bash 搜索(list)
{ list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境, 帮助参看:man bash 搜索{ list; }

范例:

[12:17:23 root@centos8 ~ ]#name=mage;(echo $name;name=rc;echo $name);echo $name
mage
rc
mage
[12:17:33 root@centos8 ~ ]#name=mage;{ echo $name;name=rc;echo $name ;};echo $name
mage
rc
rc

2.11组合测试条件

第一种方式

[ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,结果才是真
[ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一个为真,结果 就为真
[ ! EXPRESSION ] 取反

说明:-a和-o需要使用测试命令进行,[[ ]]不支持

第二种方式

COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2
COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2
! COMMAND   非,取反

范例:

[15:46:36 root@centos8 data ]#[ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"
click

范例:

[15:49:03 root@centos8 data ]#cat ping.sh 
IP=172.16.0.123
ping -c1 -W1 $IP &> /dev/null && echo "$IP is up" || {  echo "$IP is
unreachable"; exit; }
echo "Script is finished"

范例:

[15:49:25 root@centos8 data ]#cat disk_check.sh 
USE=`df|grep '^/dev/sda'|tr -s ' ' %|cut -d% -f5|sort -nr|head -n1`
WARNING=10
(( USE > WARNING )) && echo disk warning | mail -s wawrning 1255090639@qq.com

2.12使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变 量,所有剩余单词都被分配给最后一个变量

格式:
read [options] [name ...]
常见选项:
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒

范例:

[16:37:24 root@centos8 data ]#read 
rc
[16:44:21 root@centos8 data ]#echo $REPLY
rc
[16:45:13 root@centos8 data ]#read X Y Z
a
[16:45:42 root@centos8 data ]#read X Y Z
a  b c
[16:45:56 root@centos8 data ]#echo $X
a
[16:46:02 root@centos8 data ]#echo $Y
b
[16:46:05 root@centos8 data ]#echo $Z
c
[16:48:02 root@centos8 data ]#read X Y Z <<<"I LOVE YOU"
[16:48:08 root@centos8 data ]#echo $X
I
[16:48:21 root@centos8 data ]#echo $Y
LOVE
[16:48:23 root@centos8 data ]#echo $Z
YOU

3 bash配置文件

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值