更新记录
- 2024-04-29 把之前一部分笔记整合起来
引言
如何学习linux的操作,作为一个经常和服务器打交道的程序员,我认为linux的学习路线非常陡峭,所以我把我的学习笔记记录在这么一个超级文件里。
linux和shell的学习应该是什么样的?应该从shell语言的基本语法学习,比如变量的声明,数学运算,字符运算等,控制结构比如循环等开始了解。然后开始再了解一些比较高级的东西,比如一些工具,比如 awk, ps工具,history命令。
此外,自始至终,我们都应该知道的如何查找说明书和手册, 必须学会使用 man 命令。
linux的学习涉及的内容非常的多,所以,有必要认真组织一下。
本文长期更新,目标10万字,现在2万5千字,会不断的迭代优化,希望能够帮助到你。
>>终端相关
光标跳转
快捷键
删除一行, ctrl+ u zhidao.baidu.com/question/33… ctrl a ctrl e
修改ps1
ohmyzsh 修改ps1
在ohmyzsh指定主题里, %m表示机器名, %n表示用户名
PROMPT 变量就是 PS1
查看可用shell
more /etc/shells 可以看到本系统中可以使用哪些shell
安装ohmyzsh
sh -c "$(curl -fsSL https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh \
| sed 's|^REPO=.*|REPO=${REPO:-mirrors/oh-my-zsh}|g' \
| sed 's|^REMOTE=.*|REMOTE=${REMOTE:-https://gitee.com/${REPO}.git}|g')"
Ref
1 Linux改变shell命令行前缀shell前缀 改为# 天又热了的博客-CSDN博客 内容已经被删除
2 bash - How do I change my $PS1 on a Macbook for oh-my-zsh? - Stack Overflow
3 oh-my-zsh国内镜像安装 - VertexZzz - 博客园 (cnblogs.com) www.cnblogs.com/vertexz/p/1…
查看当前的shell
一定管用的
cat /etc/passwd
不一定管用的
echo $0
echo $SHELL
update-alternatives
sudo update-alternatives --config java
jdk - How do I uninstall Java 11 to be able to install Java 8 for Android Studio? - Ask Ubuntu
搜索历史
ctrl + r, and ctrl r again to search through the history
Ref
My top 10 terminal shortcuts for Linux | Enable Sysadmin (redhat.com)
用户管理和权限
1 Linux系统用户账号的管理
用户账号的管理工作主要涉及到用户账号的添加、修改和删除。
添加用户账号就是在系统中创建一个新账号,然后为新账号分配用户号、用户组、主目录和登录Shell等资源。刚添加的账号是被锁定的,无法使用。
添加新的用户账号使用useradd命令
useradd 选项 用户名
参数说明:
-
选项:
- -c comment 指定一段注释性描述。
- -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
- -g 用户组 指定用户所属的用户组。
- -G 用户组,用户组 指定用户所属的附加组。
- -s Shell文件 指定用户的登录Shell。
- -u 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。
-
用户名:
指定新账号的登录名。
实例1
useradd –d /home/sam -m sam # 必须要写 -d DIR -m 不能写 -dm DIR ,也不能写 -d -m DIR
此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录 /home/sam(/home为默认的用户主目录所在的父目录)。
-m -d
实例2
# useradd -s /bin/sh -g group –G adm,root gem
此命令新建了一个用户gem,该用户的登录Shell是 /bin/sh,它属于group用户组,同时又属于adm和root用户组,其中group用户组是其主组。
这里可能新建组:#groupadd group及groupadd adm
增加用户账号就是在/etc/passwd文件中为新用户增加一条记录,同时更新其他系统文件如/etc/shadow, /etc/group等。
Linux提供了集成的系统管理工具userconf,它可以用来对用户账号进行统一管理。
用户口令的管理
用户管理的一项重要内容是用户口令的管理。用户账号刚创建时没有口令,但是被系统锁定,无法使用,必须为其指定口令后才可以使用,即使是指定空口令。
指定和修改用户口令的Shell命令是passwd。超级用户可以为自己和其他用户指定口令,普通用户只能用它修改自己的口令。命令的格式为:
passwd 选项 用户名
可使用的选项:
- -l 锁定口令,即禁用账号。
- -u 口令解锁。
- -d 使账号无口令。
- -f 强迫用户下次登录时修改口令。
如果默认用户名,则修改当前用户的口令。
例如,假设当前用户是sam,则下面的命令修改该用户自己的口令:
$ passwd
Old password:******
New password:*******
Re-enter new password:*******
2 组管理
查看 /etc/group 法
3 增加 sudo
参考
[1]菜鸟教程,linux账户管理,www.runoob.com/linux/linux…
[2]查看组,learnku.com/articles/31…
3 增加sudo 用户名 不在 sudoers文件中,此事将被报告。weblogic 不在sudoers 文件中。 全速前行的博客-CSDN博客
Job
jobs -s
ref
1 Kill All Stopped Jobs Linux (linuxhint.com)
>> 文本操作有关
diff命令
diff命令的应用场景, 其实是很少的. 如果你把一个代码改了好几个版本, 那么diff就发挥作用了.
详情参见[17]。
一个需要记住的重要前提是,diff用于描述不同,在规定的上下文中,来说明如何改变第一个文件来与第二个文件相匹配。
diff -u 比较文件 基准文件。最常用的。
diff 可以通过提供目录名来比较2个目录
diff -y 并排显示
这里有一些需要注意的有用的diff选项:
| 参数 | 含义 |
|---|---|
| -b | 只改变空白的变化(spaces 或 tabs) |
| -w | 完全忽略空白 |
| -B | 计算差异时忽略空行 |
| -y | 以列显示输出 |
diff命令的应用场景, 其实是很少的.
diff -u 比较文件 基准文件
我们在平时工作的时候,经常要知道两个文件之间,以及同个文件不同版本之间有何异同点。在 Windows 下,有 beyond compare 这个好用的工具,而在 Linux 下,也有很多很强大的工具 包括diff,meld:
diff 命令所参考的不是第一个文件,而是第二个文件,它的输出信息有以下几种字符:
c : 表示必须做一些修改, a : 表示必须添加一些内容, d : 表示必须删除一些内容
字符前的数字表示第一个文件中的行数,字符后的内容表示第二个文件中的行数。
< 表示引用的第一个文件中的内容,而 > 表示引用的第一个文件中的内容
grep查找命令
如何查找多个文件中的关键词呢?
相当于跨文件查找, 一般我们在vscode, 或者其他重量级IDE里面都有用到跨文件查找, 但是一个简单的shell命令也可以办到.
这个关键字就是 grep, grep "关键字" -n(显示文件名和行号) file_name(接受正则表达式)
那么接下来, 如何递归的跨文件查找含有某个关键字的行呢? 下面会介绍, 请继续看.
grep命令也非常的简单, 它的基本用法是这样的, grep 关键字 文件名(支持正则表达式), 意思是, 去找匹配的文件里的含有关键字的那一行. grep 也支持管道用法, 但是有些不一样, grep作为管道的下游,则必须直接读取内容. 例如 ps -ef | grep python
例外是, ls | grep python 那就不行了. 我们的意思是, 根据ls查找到的文件, 去查阅里面还有 "python" 的行,其实 ls 得到的都是文件名, 自然就没有结果了.(如果这个文件夹里没有名字叫 python 的文件夹). 但是如果加上一个 xargs 命令, 就达到我们的目的了, ls | xargs grep python.
1.主要参数
[options]主要参数:
-c:只输出匹配行的计数。
-i:不区分大小写
-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-n:显示匹配行及行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。
pattern正则表达式主要参数:
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
<:从匹配正则表达 式的行开始。
>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
.:所有的单个字符。
- :有字符,长度可以为0。
2.实例
(1)grep 'test' d* #显示所有以d开头的文件中包含 test的行
(2)grep ‘test’ aa bb cc #显示在aa,bb,cc文件中包含test的行
(3)grep ‘[a-z]{5}’ aa #显示所有包含每行字符串至少有5个连续小写字符的字符串的行
(4)grep magic /usr/src #显示/usr/src目录下的文件(不含子目录)包含magic的行
(5)grep -r magic /usr/src #显示/usr/src目录下的文件(包含子目录)包含magic的行
(6)grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’)
find命令
find 命令,最常用的用法是 find 目录 -name "关键字", 如果使用正则表达式了,一律加上 双引号。*表示数量不限的通配符 因为find是不限制深度的, 会进入全部的子文件夹逐一搜索, 如果只想搜某一个层级, 使用 -d N 或者 --depth N 参数.
find命令的第一个参数指定搜索的地址,和一般的搜索优先指定关键字不一样,因此这里需要一个使用风格的转变。
使用find的时候,一般我们指定 -name 的时候,会遇到一个麻烦,就是文件名展开。会报这样的错误。unknown primary or operator。如果一个文件夹下的所有文件都没有空格或者其他特殊文件还好,如果有这样不规范的文件名,就会报这个错误。所以建议加上“”。
- 文件展开
find . -name *.txt
报错:unknown primary or operator
这是因为命令行执行前先要执行波浪号~展开,变量替换,文件替换。这个 *.txt就会文件替换。
ls *.txt crontab.txt log.txt out.txt svnlog.txt
使用双引号能避免文件替换。这样写就好了:find . -name "*.txt"
查找大文件
TODO
查找特定日期段的文件
find . -newermt '2022-06-09' | grep "DSC" | grep "ARW" | xargs zip ~/Pictures/graduate-arw-zip
找到最新的照片并且打包
find . -newermt '2022-06-09' | grep "DSC" | grep "ARW" | xargs zip graduate-arw-zip
find . -newermt '2022-06-09' | grep "DSC" | grep "JPG" | xargs zip graduate-jpg-zip
参考[15]使用.
-newermt:形式是 -newerXY,其中XY均为变量,主要是找到一些X属性比Y属性更新的文件。其中X指代find的目标文件属性,Y代表参照属性。X可选a,c,m; Y可选a,c,m,t。t代表客观绝对时间,只作为参照属性存在,格式为yyyy-MM-dd hh:mm:ss(必须是这个格式如果不是这个格式会报错)。
! -newermt ‘2019-01-22 14:40:00’:表示修改时间低于2019-01-22 14:40:00 find查找的时候,若有多个条件,如下所示,默认多个条件是and,可使用-a代替
find查找的时候,查找不满足条件的,使用 -not,或者用!
命令
基本格式:find path expression
1.按照文件名查找
(1)find / -name httpd.conf #在根目录下查找文件httpd.conf,表示在整个硬盘查找
(2)find /etc -name httpd.conf #在/etc目录下文件httpd.conf
(3)find /etc -name *srm*' #使用通配符*(0或者任意多个)。表示在/etc目录下查找文件名中含有字符串‘srm’的文件
(4)find . -name 'srm*' #表示当前目录下查找文件名开头是字符串‘srm’的文件
2.按照文件特征查找
a 访问, m 修改, c, 创建, -atime , time默认是天
(1)find / -amin -10 # 查找在系统中最后10分钟访问的文件(access time)
(2)find / -atime -2 # 查找在系统中最后48小时访问的文件
(3)find / -empty # 查找在系统中为空的文件或者文件夹
(4)find / -group cat # 查找在系统中属于 group为cat的文件
(5)find / -mmin -5 # 查找在系统中最后5分钟里修改过的文件(modify time)
(6)find / -mtime -1 #查找在系统中最后24小时里修改过的文件
(7)find / -user fred #查找在系统中属于fred这个用户的文件
(8)find / -size +10000c #查找出大于10000000字节的文件(c:字节,w:双字,k:KB,M:MB,G:GB)
(9)find / -size -1000k #查找出小于1000KB的文件
3.使用混合查找方式查找文件
参数有: !,-and(-a),-or(-o)。
(1)find /tmp -size +10000c -and -mmin -2 #在/tmp目录下查找大于10000字节并在最后2分钟内修改的文件
(2)find / -user fred -or -user george #在/目录下查找用户是fred或者george的文件文件
(3)find /tmp ! -user panda #在/tmp目录中查找所有不属于panda用户的文件
常见的Tests举例
-name; -perm; -type; -path; -size; 等
常见的Actions举例
-prune; -print; -exec; -delete;
常见的Operators举例
-o; -or; -a; -and; !; -not; 等
运算优先级:
! (-not) 高于 -a(-and) 高于 -o(-or)
find的举例及说明
$ find . -name foo.txt
含义: 在当前目录下, 查找名为foo.txt的文件.
这里面 . 是starting-point, -name foo.txt是Tests, 这条命令中没有Actions, 因此默认Actions就是-print. 即这条命令等同于
$ find . -name foo.txt -print 或
$ find . -name foo.txt -a -print
$ find /tmp -name core -type f -print
含义: 在/tmp目录中, 查找名为core, 同时类型为普通的文件.
这条命令中, /tmp是starting-point, -name core是Tests, -type f也是Tests, -print是Actions. 两个Tests之间没有任何Operator, 因此默认就是-a, 即这条命令等效于
$ find /tmp -name core -a -type f -print 或
$ find /tmp -name core -a -type f -a -print
$ find . -type f -exec file ‘{}’ ;
含义: 对当前目录, 查找类型为普通的文件(regular file), 并对每个文件, 执行 file操作 (file xxx表示 判定xxx是什么文件)
starting-point 是当前目录.
$ find /sbin /usr/sbin -executable ! -readable -print
含义: 找出/sbin, /usr/sbin中, 具有可执行权限, 但没有可读权限的文件, 并打印出来.
Starting-point是 /sbin, /usr/sbin
Tests是 -executable 和 -readable
Operator有两个, 一个是!, 跟 -readable结合, 表示不可读的, 还有一个省略的-a
Actions是-print
这条命令等效于
$ find /sbin /usr/sbin -executable -a ! -readable -print或
$ find /sbin /usr/sbin -executable -a ! -readable -a -print
参考
xargs命令
xargs命令怎么用呢? xargs 可以把左边的命令输出值存储起来, 然后转发给下一个命令。
echo "a b c" | xargs mkdir , 创建三个文件夹 a,b,c。
如果 echo "a b c" | mkdir,那么就会提示命令失败。
我们可以观察出xargs的作用其实是把管道的输出收集起来,然后逐一交给当前的工具(在这里指代 mkdir)。
在Linux中,管道|命令可以实现将左侧命令的标准输出转换为标准输入提供给右侧命令使用,但是有些命令不接受管道的传递方式,例如ls、echo等,其实有很多命令都不支持标准输入作为参数,只能在执行命令行时指定参数,这就导致不能使用管道|命令传递参数。而xargs命令的功能就是将标准输入进行处理,然后转化为命令行参数。
xargs不仅可以使后者接受管道数据,还可以改变原本接受管道的工具的行为,把管道穿过来的数据当做参数传进去 。比如 find . -name " .md" | xargs grep "关键字" , 其意义就是搜索后缀以 md 结尾的文件, 含有特定关键字的文件.
xargs默认把存储的内容放到新的命令的最后的位置,如果想要指定传参的位置,可以使用 -I 或者 -i 命令(仅限Linux系统)。
使用 -I 可以指定替换字符。
➜ ls | grep 1 | xargs -I xxx echo xxx # 在Linux下和Mac下都行
cmake-3.19.6-Linux-x86_64
test_lt114.cpp
查看进程命令 ps 命令
如何查看进程命令呢? 我们说,有经典的 ps -ef, 以 linux 标准格式显示进程情况,有 ps aux, 以 bsd(unix的一个子分支) 的形式显示进程情况. ps [选项]
下面对命令选项进行说明:
-e 显示所有进程。 -f 全格式。 -h 不显示标题。 -l 长格式。 -w 宽输出。 a 显示终端上的所有进程,包括其他用户的进程。 r 只显示正在运行的进程。 u 以用户为主的格式来显示程序状况。 x 显示所有程序,不以终端机来区分。
ps -ef 显示出的结果: 1.UID 用户ID 2.PID 进程ID 3.PPID 父进程ID 4.C CPU占用率 5.STIME 开始时间 6.TTY 开始此进程的TTY—-终端设备 7.TIME 此进程运行的总时间 8.CMD 命令名
awk命令
第一个场景 ps
经常使用 ps 命令, 我们可能想单独获取一个进程ID, 比如有人会丢给你一个这样的命令:
ps -ef | grep 进程名称关键字 | awk '{print $2}' // awk使用单引号??
为什么要用单引号,看看下面这个例子:
➜ ~ ps -ef | grep java | awk "{print $2}"
root 1159384 1159144 0 08:27 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox java
➜ ~ ps -ef | grep java | awk '{print $2}'
1159389
多个列号可以使用逗号隔开。
例如
dk ps| awk '{print 2}'
第二个场景 grep 命令
我想根据某一个关键字去查询哪些文档里有这个关键字, 我会写一个语句
find . -name “*.md” | xargs grep "关键字"
例如这样的命令:
➜ htmls find . -name "*.md" | xargs grep "cpp"
你会发现, 因为有的文件名称里面有空格, 所有导致 grep 命令取错了文件名, 我们需要给文件名左右加上双引号才能保证可靠.
这个时候, 我们就必须要 awk 命令了.
例子1
我们先来看一个例子,来自参考[1].
➜ htmls awk 'BEGIN { str1 = "你好,"; str2 = "简单教程"; str3 = str1 str2; print str3 }'
你好,简单教程
怎么解释呢? BEGIN 表示,从头开始, 忽略管道输入,或者不接受输入的文件名, 所以如果要和其他命令配合,就要把 BEGIN去掉
普通的awk命令是
awk 命令 文件名,表示按行处理. 每行按空格切分, 1表示第一个切分元素.
例子2
如果我们要输出一个双引号, 那么就要使用转义符 ``, 当然, 还要使用外面的双引号把本身的双引号括起来, 表示这个一个字符, 因为 awk 本身就是一个语言解释器, 就类似于 python 一样的东西. awk 一定要使用引号才能输出字符串
➜ htmls echo 11 > a.txt
➜ htmls awk '{print """}' a.txt
我们可以看到 awk 命令确实输出了双引号.
完成我们的目标
在第二个场景中, 我们想使用 grep 命令, 但是使用 grep命令,我想根据某一个关键字去查询哪些文档里有这个关键字, 我会写一个语句
find . -name "*.md" | xargs grep "关键字"
因为有的文件名称里面有空格, 所有导致 grep 命令取错了文件名, 我们需要给文件名左右加上双引号才能保证可靠.
所以, 我们现在就来改造这个命令.
find -L . -name "*.md" | awk '{a=""";print a $0 a}' | xargs grep 关键字
需要说明的是, awk命令的字符拼接, 就是用空格隔开就可以了, 类似于 Python中的+, 在这里我们使用 print a $0 a.
补充说明: 如果要获取每行记录的话, awk 不需要和xargs搭配, 例如
ls | awk ' {print "abc/" $0 }'表示给每一行加上abc
ps结合grep结合awk
查找 tomcat 进程,并且杀掉它
一个结合ps 和 xargs以及grep, awk的命令
ps -ef | grep tomcat | grep -v grep | awk '{print $2}' | xargs kill -9
grep -v 的命令是排除 grep 命令本身启动的进程
Linux下ps - ef和ps aux的区别
**ps -ef 是用标准的格式显示进程的、
其中各列的内容意思如下
-
UID //用户ID、但输出的是用户名
-
PID //进程的ID
-
PPID //父进程ID
-
C //进程占用CPU的百分比
-
STIME //进程启动到现在的时间
-
TTY //该进程在那个终端上运行,若与终端无关,则显示? 若为pts/0等,则表示由网络连接主机进程。
-
CMD //命令的名称和参数
**ps aux 是用BSD的格式来显示、
同ps -ef 不同的有列有
-
USER //用户名
-
%CPU //进程占用的CPU百分比
-
%MEM //占用内存的百分比
-
VSZ //该进程使用的虚拟內存量(KB)
-
RSS //该进程占用的固定內存量(KB)(驻留中页的数量)
-
STAT //进程的状态
-
START //该进程被触发启动时间
-
TIME //该进程实际使用CPU运行的时间
参考
[1] AWK 字符串拼接符 - 空格 ( ' ' )
[2] awk中如何输出单引号
[3] 运维日记 5分钟学会awk
一个综合的命令
查找 tomcat 进程,并且杀掉它 一个结合ps 和 xargs以及grep, awk的命令 ps -ef | grep tomcat | grep -v grep | awk '{print $2}' | xargs kill
grep -v 的命令是排除 grep 命令本身启动的进程
envsubst
ref
Linux envsubst Command with Examples | Baeldung on Linux
less
less command
Less command is a Linux utility that can be used to read the contents of a text file one page(one screen) at a time. It has faster access because if file is large it doesn’t access the complete file, but accesses it page by page.
For example, if it’s a large file and you are reading it using any text editor, then the complete file will be loaded to main memory. The less command doesn’t load the entire file, but loads it part by part which makes it faster.
Syntax :
less filename
mostly used Options :
-E : causes less to automatically exit the first time it reaches end of file. -f : forces non-regular file to open. -F : causes less to exit if entire file can be displayed on first screen -g : highlight the string which was found by last search command -G : suppresses all highlighting of strings found by search commands -i : cause searches to ignore case -n : suppresses line numbers -p pattern : it tells less to start at the first occurrence of pattern in the file -s : causes consecutive blank lines to be squeezed into a single blank line
Ref
[1] less, www.geeksforgeeks.org/less-comman…
>>文件和硬盘相关
du命令
du命令显示文件或目录所占的磁盘空间,不要直接执行 du 命令,它会遍历并列出目录下的所有文件,你会被输出的结果所淹没。
du -d 1 -h 可以查看当前目录下所有的文件和文件夹的大小。
df命令
df命令检查磁盘空间占用情况(并不能查看某个目录占用的磁盘大小)[5]。
我使用df命令,可以看到如下输出
[root@lydccdb ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 16G 0 16G 0% /dev/shm
tmpfs 6.2G 8.7M 6.2G 1% /run
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/mapper/openeuler-root 475G 3.2G 448G 1% /
tmpfs 16G 0 16G 0% /tmp
/dev/vda1 974M 177M 730M 20% /boot
devtmpfs文件系统
在Linux系统中,df -h 命令用于显示文件系统的磁盘空间使用情况。当您使用这个命令时,您可能会看到 devtmpfs 文件系统列表中的一行。devtmpfs 是一个临时文件系统,通常挂载在 /dev 目录下,它用于存放设备文件。devtmpfs 的主要特点包括:
- 内存支持:
devtmpfs通常是基于内存的(尽管它也可以配置为使用交换空间),这意味着它的读写速度非常快。 - 自动创建:当系统启动时,
devtmpfs会自动创建,并且会根据内核的需要自动创建设备文件。 - 安全性:
devtmpfs可以配置为只允许特定的用户或组访问,这样可以提高系统的安全性。 - 动态大小:
devtmpfs的大小不是固定的,它会根据系统中设备文件的数量和大小自动调整。 在df -h的输出中,devtmpfs的尺寸通常不会显示为很大,因为它主要是用来存放临时的设备文件,而不是用来存储大量数据的。它的存在是为了方便内核和用户空间程序之间的交互,以及管理设备文件。 例如,df -h的输出可能包含如下行:
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.9G 0 3.9G 0% /dev
这表明 devtmpfs 文件系统在这个系统上占用大约 3.9 GB 的内存空间,并且还没有使用任何空间。
devtmpfs 文件系统是Linux内核自动挂载的,通常用于临时存储设备文件,如 /dev/null、/dev/random 等。由于它是系统正常运行所必需的,不建议也不允许用户手动删除它。 devtmpfs 是基于内存的文件系统,它会在系统启动时自动创建,并在系统关闭时自动清理。它的存在是为了提供一种快速、临时的方式来管理设备文件,以及为了确保系统中的设备可以被正确地访问和使用。 如果您在 df -h 的输出中看到了 devtmpfs,这仅仅是显示了它的状态和占用情况,并不是说您可以像删除其他挂载的文件系统那样删除它。尝试删除 devtmpfs 或其挂载点 /dev 可能会导致系统不稳定或无法正常工作。因此,应该保留 devtmpfs 和它的挂载点,让系统管理它们。
tmpfs文件系统
tmpfs 是Linux内核提供的一种内存文件系统,它允许在虚拟内存中创建临时文件系统。tmpfs 通常被用来存储不需要持久化的临时数据,它的主要特点是:
- 内存速度:
tmpfs存储在内存中,因此它的读写速度非常快,接近于内存的速度。 - 临时存储:
tmpfs中的数据在系统重启后不会保留,因此在tmpfs上存储的数据是临时的。 - 动态大小:
tmpfs文件系统的大小可以根据需要动态变化,它可以使用物理内存(RAM)和交换空间(swap)。 - 安全性:
tmpfs可以配置为只允许特定的用户或组访问,提高系统的安全性。tmpfs的常见用途包括:
- /tmp 目录:许多系统将
/tmp挂载为tmpfs,以便提供快速的临时存储空间。 - 交换空间:当系统的物理内存不足时,
tmpfs可以用作额外的交换空间。 - 缓存:
tmpfs可以用作应用程序的缓存,例如浏览器缓存或应用程序临时数据。 - 进程间通信:
tmpfs可以用作进程间通信(IPC)的共享内存段。 由于tmpfs使用的是内存资源,因此使用时需要注意不要超出系统的物理内存和交换空间,否则可能会导致系统内存不足,从而影响系统的稳定性。
vda文件系统
在Linux系统中,/dev/vda1 通常是指第一个虚拟磁盘(vda)的第一个分区(1)。在Linux的设备命名规则中,vd 表示这是一个虚拟磁盘,a 表示这是第一个虚拟磁盘,1 表示这是该磁盘上的第一个分区。 在物理服务器上,您可能会看到类似 /dev/sda1 的命名,其中 sd 表示 SCSI、SATA 或 IDE 磁盘,a 同样表示第一个磁盘,1 表示第一个分区。而在虚拟化环境中,如使用 KVM、Xen 或其他虚拟化技术时,磁盘通常会被命名为 vd 开头。 /dev/vda1 通常会被用作操作系统的根文件系统(/),存储着Linux系统的核心文件和目录。在系统启动时,内核会挂载这个分区,以便能够访问必要的文件和执行程序。 如果您想查看 /dev/vda1 的详细信息,可以使用 lsblk、fdisk -l 或 blkid 等命令。例如:
lsblk /dev/vda1
# 或者
fdisk -l /dev/vda1
# 或者
blkid /dev/vda1
这些命令会显示关于分区的大小、文件系统类型、UUID 等信息。
逻辑卷设备映射
在Linux系统中,/dev/mapper/openeuler-root 表示一个逻辑卷映射到的设备。这里的各个部分含义如下:
/dev/mapper/:这是一个设备映射器目录,用于表示通过Linux的设备映射器子系统创建的设备。设备映射器允许你创建逻辑卷管理(LVM)卷、软件RAID卷等。openeuler:这通常是LVM卷组(Volume Group)的名称。LVM卷组是一组物理卷(Physical Volumes,PVs)的集合,它们被组合在一起形成一个大的逻辑存储池。-root:这表示这个逻辑卷(Logical Volume,LV)是作为根文件系统(/)使用的。在Linux系统中,根文件系统是启动时挂载的第一个文件系统,它包含了操作系统的核心文件和目录。 因此,/dev/mapper/openeuler-root表示在名为openeuler的LVM卷组中创建的一个逻辑卷,这个逻辑卷被用作根文件系统。这通常是在使用LVM进行磁盘管理的Linux系统上看到的,比如OpenEuler操作系统。 如果你想查看更多关于这个逻辑卷的信息,可以使用lvdisplay命令:
lvdisplay /dev/mapper/openeuler-root
这个命令会显示逻辑卷的大小、状态、路径、布局和属性等信息。
mount 命令
这个命令一直没用过。
zip命令
zip命令特别简单, zip 目标名 被压缩的列表
链接 ln
硬链接只能对单个文件 链接的目录必须是绝对路径,不能是相对路径, 这个说法是错的 软链接, ln -s FROM TO ; 相当于 Windows 里面的快捷方式.
在linux中,进入一个软链接文件夹不会把 pwd 切换到源目录里去。 还是把软链接当做一个目录对待 但是软链接不可以移动, 否则就会失效. 这一点不像 windows 里的快捷方式.
磁盘分区管理
逻辑分区在计算机存储管理中具有重要的意义,尤其是在使用复杂存储系统的环境中。以下是逻辑分区(在Linux环境中通常指的是LVM逻辑卷)的一些主要意义:
-
灵活的存储管理:
- 逻辑分区允许在不改变物理硬盘布局的情况下调整分区大小。这意味着可以根据需要增加或减少分区的大小,而不必担心重新分配磁盘空间或丢失数据。
-
动态存储池:
- 通过将多个物理硬盘组合成一个逻辑存储池(卷组),逻辑分区可以跨越多个物理设备。这允许存储空间在物理硬盘之间动态分配和重新分配。
-
简化备份和恢复:
- 逻辑分区可以轻松地创建快照,这为备份和恢复提供了便利。快照是一个只读的分区副本,它可以在不中断系统运行的情况下创建。
-
提高数据冗余和可靠性:
- 逻辑分区可以配置为镜像,这意味着数据可以同时写入多个物理硬盘。如果其中一个硬盘失败,其他硬盘仍然可以提供数据访问,从而提高了数据的可靠性和系统的冗余性。
-
优化资源利用率:
- 逻辑分区可以帮助优化存储资源的利用率,因为可以更精细地控制存储空间的使用,减少空间的浪费。
-
支持大型存储环境:
- 对于需要处理大量数据的企业级应用,逻辑分区可以支持超过单个硬盘容量限制的大型存储卷。
-
方便的存储迁移:
- 逻辑分区可以更容易地迁移到不同的硬件或系统,因为它们与底层的物理硬件是抽象的。
-
提高性能:
- 在某些情况下,逻辑分区可以通过条带化(striping)来提高I/O性能,条带化是将数据分散存储在多个硬盘上,从而可以并行读写数据,提高吞吐量。 总之,逻辑分区提供了一种更高级、更灵活的存储管理方式,它允许系统管理员以更细粒度的方式控制存储资源,从而提高系统的可扩展性、可靠性和效率。
COMMAND
- 创建别名, 同义词 短名 alias a='xxxx xxx xxx'
>>内核
查看版本信息
一、查看Linux内核版本命令(两种方法): 1、cat /proc/version 2、uname -a
二、查看Linux发行系统版本的命令(3种方法):
1、lsb_release -a,即可列出所有版本信息:
这个命令适用于所有的Linux发行版,包括RedHat、SUSE、Debian…等发行版。
2、cat /etc/redhat-release,这种方法只适合Redhat系的Linux:
查看版本
cat /etc/redhat-release
参考
[1]查看centos版本,www.cnblogs.com/chentiao/p/…
>>进程相关
定时任务crontab
How to Start, Stop, and Restart Cron Jobs (airplane.dev)
crontab -e
* * * * * ls >> ~ls-output.log
一个做监控的工具,可以发送任务的工具
Crontab.guru - The cron schedule expression editor
启动、停掉
Red Hat / CentOS:
service crond start/stop
or
/etc/init.d/crond start/stop
Ubuntu:
sudo service cron start/stop
or
sudo /etc/init.d/cron start
top命令
top - 01:06:48 up 1:22, 1 user, load average: 0.06, 0.60, 0.48
Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 1.0% sy, 0.0% ni, 98.7% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 191272k total, 173656k used, 17616k free, 22052k buffers
Swap: 192772k total, 0k used, 192772k free, 123988k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1379 root 16 0 7976 2456 1980 S 0.7 1.3 0:11.03 sshd
14704 root 16 0 2128 980 796 R 0.7 0.5 0:02.72 top
1 root 16 0 1992 632 544 S 0.0 0.3 0:00.90 init
2 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
统计信息区前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下:
01:06:48 当前时间
up 1:22 系统运行时间,格式为时:分
1 user 当前登录用户数
load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。
第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:
total 进程总数
running 正在运行的进程数
sleeping 睡眠的进程数
stopped 停止的进程数
zombie 僵尸进程数
Cpu(s):
0.3% us 用户空间占用CPU百分比
1.0% sy 内核空间占用CPU百分比
0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.7% id 空闲CPU百分比
0.0% wa 等待输入输出的CPU时间百分比
0.0%hi:硬件CPU中断占用百分比
0.0%si:软中断占用百分比
0.0%st:虚拟机占用百分比
最后两行为内存信息。内容如下:
Mem:
191272k total 物理内存总量
173656k used 使用的物理内存总量
17616k free 空闲内存总量
22052k buffers 用作内核缓存的内存量
Swap:
192772k total 交换区总量
0k used 使用的交换区总量
192772k free 空闲交换区总量
123988k cached 缓冲的交换区总量,内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小,相应的内存再次被换出时可不必再对交换区写入。
进程信息区统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。
序号 列名 含义
a PID 进程id
b PPID 父进程id
c RUSER Real user name
d UID 进程所有者的用户id
e USER 进程所有者的用户名
f GROUP 进程所有者的组名
g TTY 启动进程的终端名。不是从终端启动的进程则显示为 ?
h PR 优先级
i NI nice值。负值表示高优先级,正值表示低优先级
j P 最后使用的CPU,仅在多CPU环境下有意义
k %CPU 上次更新到现在的CPU时间占用百分比
l TIME 进程使用的CPU时间总计,单位秒
m TIME+ 进程使用的CPU时间总计,单位1/100秒
n %MEM 进程使用的物理内存百分比
o VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
p SWAP 进程使用的虚拟内存中,被换出的大小,单位kb。
q RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
r CODE 可执行代码占用的物理内存大小,单位kb
s DATA 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
t SHR 共享内存大小,单位kb
u nFLT 页面错误次数
v nDRT 最后一次写入到现在,被修改过的页面数。
w S 进程状态(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程)
x COMMAND 命令名/命令行
y WCHAN 若该进程在睡眠,则显示睡眠中的系统函数名
z Flags 任务标志,参考 sched.h
默认情况下仅显示比较重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通过下面的快捷键来更改显示内容。
更改显示内容通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或隐藏对应的列,最后按回车键确定。 按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z 可以将相应的列向左移动。最后按回车键确定。 按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的 R 键可以将当前的排序倒转。
查看 内存
大写的E切换,一定要是大写的E,切换GB、MB,KB等单位的显示。
很多中文博客只写E,没有强调是大写的E,让我有点迷惑!
小写的e只会调整每一行,但是不会修改整体的内存。
按 shift + W 会保存设置
其他键
- m:显示或隐藏内存状态信息
- c 显示完整的命令
- M 按物理内存使用排序
问题
上下箭头不知道会有什么?看明白了,每次下移一行。
Ref
1 linux - How to display meminfo in megabytes in top? - Unix & Linux Stack Exchange 第一个答案就很完美
2 top命令,top linux下的任务管理器 — Linux Tools Quick Tutorial (linuxtools-rst.readthedocs.io)
3 linux的top命令参数详解 - ggjucheng - 博客园 (cnblogs.com)
crontab
1 执行日志
把cron日志打开
vi /etc/rsyslog.d/50-default.conf
在文件中找到cron.*,把前面的#去掉,保存退出
service rsyslog restart
less -10 /var/log/cron.log
编辑定时任务
crontab -e
2 重启cron
service cron reload
是 cron 不是 crond 一定要记住!
在service 进程管理工具里, 注册的是 cron
3 一个例子
crontab -e
* * * * * date +%Y-%m-%d_%H:%M:%S > ~/crontest/time"$(date +%Y-%m-%d_%H:%M:%S)".txt
* * * * * bash /root/crontest/backup.sh
backup.sh
#!/usr/bin/env bash
cd /root/crontest
rmcount=`find . -mmin +30 -name "time2023*" | wc -l`
if [ $rmcount -gt 0 ]; then
echo "$(date +%Y-%m-%d_%H:%M:%S) find $rmcount files to remove " >> echo.log
find . -mmin +30 -name "time2023*" | sort | xargs -I % bash -c 'echo "remove " % ; echo "remove "% >> echo.log;rm -f %'
fi
参考
[1]开启crontab的日志,blog.csdn.net/k_young1997…
2 crontab 启动失败的方法,crontab定时任务不执行的一些原因总结 - 掘金 (juejin.cn)
service命令
service命令 是Redhat Linux兼容的发行版中用来控制系统服务的实用工具,它以启动、停止、重新启动和关闭系统服务,还可以显示所有系统服务的当前状态。
- 服务名:自动要控制的服务名,即
/etc/init.d目录下的脚本文件名; - 控制命令:系统服务脚本支持的控制命令。
类似的有systemctl命令,这个会在下面讲到。
Ref
1 service 命令,Linux service 命令详解:控制系统服务的实用工具 - Linux 命令搜索引擎 (wangchujiang.com)
key points:
- 服务名:自动要控制的服务名,即
/etc/init.d目录下的脚本文件名; - 控制命令:系统服务脚本支持的控制命令。
相似命令,执行命令“systemctl status 服务名.service”可查看服务的运行状态,其中服务名后的.service 可以省略,这是CenOS7以后采用systemd作为初始化进程后产生的变化。
systemctl status network.service
systemctl start network.service
systemctl命令
这个命令属于centos系列的
systemctl status network.service
ref
1 CentOS7 从查看、启动、停止服务说起systemctl - 我是属车的 - 博客园 (cnblogs.com)
查看进程启动
ps -ef | grep tomcat
单个进程启动之后会在 /proc下面有一个pid对应的路径 如PID为1521,到/proc/1521下,ls -l会看到类似如下信息:
-r--r--r-- 1 oracle oinstall 0 12月 29 18:58 cmdline
lrwxrwxrwx 1 oracle oinstall 0 12月 29 18:58 cwd -> /XXX/ultserver_aa
-r-------- 1 oracle oinstall 0 12月 29 18:58 environ
lrwxrwxrwx 1 oracle oinstall 0 12月 29 18:58 exe -> /usr/bin/python2.4
dr-x------ 2 oracle oinstall 0 12月 29 18:58 fd
-r-------- 1 oracle oinstall 0 12月 29 18:58 maps
-rw------- 1 oracle oinstall 0 12月 29 18:58 mem
-r--r--r-- 1 oracle oinstall 0 12月 29 18:58 mounts
lrwxrwxrwx 1 oracle oinstall 0 12月 29 18:58 root -> /
-r--r--r-- 1 oracle oinstall 0 12月 29 18:58 stat
-r--r--r-- 1 oracle oinstall 0 12月 29 18:58 statm
-r--r--r-- 1 oracle oinstall 0 12月 29 18:58 status
ref
1 Linux 查看进程启动路径 - 简书 (jianshu.com)
kill命令的理解和正确用法
相信很多程序员对于Linux系统都不陌生,即使自己的日常开发机器不是Linux,那么线上服务器也大部分都是的,所以,掌握常用的Linux命令也是程序员必备的技能。
但是,怕就怕很多人对于部分命令只是一知半解,使用不当就能导致线上故障。
前段时间,我们的线上应用报警,频繁FGC,需要紧急处理问题,于是有同事去线上重启机器(正常程序应该是先采集堆dump,然后再重启,方便排查是否存在内存泄露等问题)。
但是在重启过程中,同事发现正常的重启命令应用无反应,然后尝试使用kill命令"杀"掉Java进程,但是仍然无效。于是他私自决定使用 "kill -9"结束了进程的生命。
虽然应用进程被干掉了,但是随之而来带来了很多问题,首先是上游系统突然发生大量报警,对应开发找过来说调用我们的RPC服务无响应,频繁超时。
后来,我们又发现系统中存在部分脏数据,有些在同一个事务中需要完整更新的数据,只更新了一半…
为什么正常的kill无法"杀掉"进程,而kill -9就可以?为什么kill -9会引发这一连串连锁反应?正常的kill执行时,JVM会如何处理的呢?
要搞清楚这些问题,我们要先从kill命令说起。
kill 命令
我们都知道,想要在Linux中终止一个进程有两种方式,如果是前台进程可以使用Ctrl+C键进行终止;如果是后台进程,那么需要使用kill命令来终止。(其实Ctrl+C也是kill命令)
kill命令的格式是:
kill参数
如:
kill 21121
kill -9 21121
其中[参数]是可选的,进程号可以通过jps/ps/pidof/pstree/top等工具获取。
kill的命令参数有以下几种:
-l 信号,若果不加信号的编号参数,则使用“-l”参数会列出全部的信号名称
-a 当处理当前进程时,不限制命令名和进程号的对应关系
-p 指定kill 命令只打印相关进程的进程号,而不发送任何信号
-s 指定发送信号
-u 指定用户
通常情况下,我们使用的-l(信号)的时候比较多,如我们前文提到的kill -9中的9就是信号。
➜ ~ kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS
信号如果没有指定的话,默认会发出终止信号(15)。常用的信号如下:
HUP 1 终端断线
INT 2 中断(同 Ctrl + C)
QUIT 3 退出(同 Ctrl + \)
TERM 15 终止
KILL 9 强制终止
CONT 18 继续(与STOP相反, fg/bg命令)
STOP 19 暂停(同 Ctrl + Z)
比较常用的就是强制终止信号:9和终止信号:15,另外,中断信号:2其实就是我们前文提到的Ctrl + C结束前台进程。
那么,kill -9 和 kill -15到底有什么区别呢?该如何选择呢?
kill -9 和 kill -15的区别
kill命令默认的信号就是15,首先来说一下这个默认的kill -15信号。
当使用kill -15时,系统会发送一个SIGTERM的信号给对应的程序。当程序接收到该信号后,具体要如何处理是自己可以决定的。
这时候,应用程序可以选择:
1、立即停止程序
2、释放响应资源后停止程序
3、忽略该信号,继续执行程序
因为kill -15信号只是通知对应的进程要进行"安全、干净的退出",程序接到信号之后,退出前一般会进行一些"准备工作",如资源释放、临时文件清理等等,如果准备工作做完了,再进行程序的终止。
但是,如果在"准备工作"进行过程中,遇到阻塞或者其他问题导致无法成功,那么应用程序可以选择忽略该终止信号。
这也就是为什么我们有的时候使用kill命令是没办法"杀死"应用的原因,因为默认的kill信号是SIGTERM(15),而SIGTERM(15)的信号是可以被阻塞和忽略的。
和kill -15相比,kill -9就相对强硬一点,系统会发出SIGKILL信号,他要求接收到该信号的程序应该立即结束运行,不能被阻塞或者忽略。
所以,相比于kill -15命令,kill -9在执行时,应用程序是没有时间进行"准备工作"的,所以这通常会带来一些副作用,数据丢失或者终端无法恢复到正常状态等。
Java是如何处理SIGTERM(15)的
我们都知道,在Linux中,Java应用是作为一个独立进程运行的,Java程序的终止运行是基于JVM的关闭实现的,JVM关闭方式分为3种:
正常关闭:当最后一个非守护线程结束或者调用了System.exit或者通过其他特定平台的方法关闭(接收到SIGINT(2)、SIGTERM(15)信号等)
强制关闭:通过调用Runtime.halt方法或者是在操作系统中强制kill(接收到SIGKILL(9)信号)
异常关闭:运行中遇到RuntimeException异常等。
JVM进程在接收到kill -15信号通知的时候,是可以做一些清理动作的,比如删除临时文件等。
当然,开发者也是可以自定义做一些额外的事情的,比如让tomcat容器停止,让dubbo服务下线等。
而这种自定义JVM清理动作的方式,是通过JDK中提供的shutdown hook实现的。JDK提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子。
例子如下:
package com.hollis;
public class ShutdownHookTest {
public static void main(String[] args) {
boolean flag = true;
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("hook execute...");
}));
while (flag) {
// app is runing
}
System.out.println("main thread execute end...");
}
}
执行命令:
➜ jps
6520 ShutdownHookTest
6521 Jps
➜ kill 6520
控制台输出内容:
hook execute...
Process finished with exit code 143 (interrupted by signal 15: SIGTERM)
可以看到,当我们使用kill(默认kill -15)关闭进程的时候,程序会先执行我注册的shutdownHook,然后再退出,并且会给出一个提示:interrupted by signal 15: SIGTERM
如果我们执行命令kill -9:
➜ kill -9 6520
控制台输出内容:
Process finished with exit code 137 (interrupted by signal 9: SIGKILL)
可以看到,当我们使用kill -9 强制关闭进程的时候,程序并没有执行shutdownHook,而是直接退出了,并且会给出一个提示:interrupted by signal 9: SIGKILL
总结
kill命令用于终止Linux进程,默认情况下,如果不指定信号,kill 等价于kill -15。
kill -15执行时,系统向对应的程序发送SIGTERM(15)信号,该信号是可以被执行、阻塞和忽略的,所以应用程序接收到信号后,可以做一些准备工作,再进行程序终止。
有的时候,kill -15无法终止程序,因为他可能被忽略,这时候可以使用kill -9,系统会发出SIGKILL(9)信号,该信号不允许忽略和阻塞,所以应用程序会立即终止。
这也会带来很多副作用,如数据丢失等,所以,在非必要时,不要使用kill -9命令,尤其是那些web应用、提供RPC服务、执行定时任务、包含长事务等应用中,因为kill -9 没给spring容器、tomcat服务器、dubbo服务、流程引擎、状态机等足够的时间进行收尾。
>>网络相关
SSH
ref
1 强制ssh使用密码认证登陆服务器 - 暗无天日 (lujun9972.win) blog.lujun9972.win/blog/2017/0…
网络相关
4.1 端口监听
netstat -anpt | grep 端口号
4.2 Curl 工具
curl命令是个功能强大的网络工具,可用来请求 Web 服务器,支持FTP、FTPS、HTTP、HTTPS、SMTP、Telnet、TFTP等协议,底层使用的是 libcurl 库。可用于文件上传、下载,还可以用来模拟客户端请求,抓取网页、网络监控等。
详情见 curl 的用法指南 - 阮一峰的网络日志 (ruanyifeng.com)
例如
curl -SL github.com/docker/comp… -o /usr/local/bin/docker-compose
-d参数用于发送 POST 请求的数据体。
$ curl -d'login=emma&password=123'-X POST google.com/login
或者
$ curl -d 'login=emma' -d 'password=123' -X POST google.com/login 使用-d参数以后,HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法,因此可以省略-X POST。
-d参数可以读取本地文本文件的数据,向服务器发送。
$ curl -d '@data.txt' google.com/login
上面命令读取data.txt文件的内容,作为数据体向服务器发送。
nc
开始端口监听和从另一个端口发起连接
server side: nc -l listening-port
client side: nc server-ip port
查看主机基本情况
在Linux系统中,您可以使用以下shell命令来查看主机的CPU核数、内存和硬盘大小:
-
查看CPU核数:
nproc或grep -c ^processor /proc/cpuinfo命令可以显示CPU的核心数。cat /proc/cpuinfo命令可以显示更详细的CPU信息。
-
查看内存大小:
free -h命令可以显示内存的总量和使用情况,其中-h选项表示以人类可读的格式(如GB、MB)显示数据。
-
查看硬盘大小:
df -h命令可以显示文件系统的磁盘空间使用情况,包括已使用的空间和可用空间。lsblk命令可以列出所有可用的磁盘和分区以及它们的挂载点。 请记住,这些命令需要在具有相应权限的账户下运行,通常是root账户或使用sudo命令。 例如,如果您想查看CPU核数,可以使用以下命令之一:
nproc
# 或者
grep -c ^processor /proc/cpuinfo
要查看内存大小,可以使用:
free -h
要查看硬盘大小,可以使用:
df -h
# 或者
lsblk
这些命令会为您提供有关系统资源的基本信息,帮助您进行系统管理和监控。
相关工作
程序员小卡介绍了xargs命令的一些常用语法[2]。
小姐姐味道在他的文章里总结了一些常用的linux命令[3],特点是非常的全面,对各种命令进行分类总结,但是缺点是介绍侧重于分类,而没有做实质介绍,适合于速查而非了解。
实验楼在它的文章里列举了非常多的命令,排版需要改进,重点在于标题的级别没有设置,没有仔细的归类,只做了简单的介绍[4],但是比[3]更为详细。
sparkdev讲了Linux命令下df和du的区别,讲明白了df是全局磁盘空闲情况,而du则是某个目录或者文件的情况[5]。
sparkdev讲了Linux下mount命令的用法,但是没有讲原理[6]。他详细的介绍了查看一个系统支持的文件系统类型,如何把一个设备挂载到一个目录等等操作。
九派Linux在他的博客里简明清晰的讲解了挂载的概念和mount命令[7]。
Bash 是 Linux 和 Mac 的默认 Shell(命令行环境),系统管理和服务器开发都需要它。虽然不难,但是语法很怪异,比如计算字符串的长度要写成${#varname},根本记不住,需要查手册。阮一峰一共写了20节,Bash 脚本编程的主要语法,都包括在内了。参见博客[11]。
阮一峰在他的博客[12]中介绍了一些shell命令的优秀替代品。
参考
[1] ps -ef 的意思 blog.csdn.net/persever/ar…
[2]程序猿小卡, Linux基础:xargs命令, segmentfault.com/a/119000001…
[3]小姐姐味道, Linux上,最常用的一批命令解析(10年精选), juejin.cn/post/684490…
[4]实验楼,45 个常用Linux 命令, juejin.cn/post/684490…
[5]sparkdev,Linux的du和df命令,www.cnblogs.com/sparkdev/p/…
[6]sparkdev, Linux的mount命令,www.cnblogs.com/sparkdev/p/…
[7]九派Linux, Linux 文件系统挂载mount命令,segmentfault.com/a/119000002…
[8]阮一峰,xargs命令,www.ruanyifeng.com/blog/2019/0…
[9]Believer007,shell的无限循环,www.cnblogs.com/landhu/p/70…
[10]EasonJim, shell的循环,www.cnblogs.com/EasonJim/p/…
[11]阮一峰,bash教程,wangdoc.com/bash/variab…
[12]阮一峰,shell命令的优秀替代品,www.ruanyifeng.com/blog/2022/0…
[13]阮一峰,shell条件判断,wangdoc.com/bash/condit…
[14]阮一峰,curl的用法,www.ruanyifeng.com/blog/2019/0…
[15]永远不要矫情,Linux find查找具体时间范围内的文件并统计文件大小,blog.csdn.net/dingding_ti…
[16]CSDN网友,mtime-ctime的区别,blog.csdn.net/hongweigg/a…
[17]中道心,GNU diff,www.jianshu.com/p/fa84b5158…
[1] ps -ef 的意思
##shell编程##############
为什么要学Shell?
多一个本事多一条路。
很多人会说 Shell 编程属于运维方面的知识了,应该是运维人员来做,我们做后端开发的没必要学。我觉得这种说法大错特错,相比于专门做Linux运维的人员来说,我们对 Shell 编程掌握程度的要求要比他们低,但是shell编程也是我们必须要掌握的!
校招明文写着会shell加分!
什么是 Shell?
壳子,壳子,壳子。
操作系统暴露给程序员用户的交互界面(和暴露给普通用户的图像化界面为互补关系)。
写一个helloWorld?
echo "echo 'hello world'" >> hello.sh
chmod a+x hello.sh
./hello.sh
>>语法
shell中 # 符号表示注释。shell 的第一行比较特殊,一般都会以#!开始来指定使用的 shell 类型,我强调一下 #!后面不跟空格。在linux中,除了bash shell以外,还有很多版本的shell, 例如zsh、dash等等...不过bash shell还是我们使用最多的。但是我个人喜欢zsh。
[[ 和 [ 的区别
$type [ [[ test
[ is a shell builtin
[[ is a shell keyword
test is a shell builtin
案例:
x=1
y=1
$[ $x == 1 && $y == 1 ] && echo True || echo False
-bash: [: missing `]'
False
$[[ $x == 1 && $y == 1 ]] && echo True || echo False
True
$[ $x == 1 -a $y == 1 ] && echo True || echo False
True
在[[中使用&&和||表示逻辑与和逻辑或。[中使用-a 和-o 表示逻辑与和逻辑或。
[[ 兼容 [ 中的运算法。
使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中
奇葩的()的区别
(()) 只能用来执行数字运算并且返回数字值。
(())没有返回值,(())只能用来执行数字运算或者赋值,并且不能有任何返回值
$(x)只能用来执行命令并且返回值
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ if (( foo = 5 ));then echo "foo is $foo"; fi
foo is 5
看一些例子:
otfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ x=$((ls))
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ echo $x
0
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ echo $(x)
x: command not found
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ x=$(ls)
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ echo $x
10 10] LICENSE README.md alias.rc bin git.rc install.sh mac.rc other.rc path.rc test.sh
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ (1+2)
1+2: command not found
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ ((1+2))
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ echo ((1+2))
bash: syntax error near unexpected token `('
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ echo $((1+2))
3
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ echo ((1+2))
bash: syntax error near unexpected token `('
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ a=1
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ ((a+1))
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ (a+1)
Command 'a+1' not found, did you mean:
command 'a+' from deb aplus-fsf (4.22.1-10.1)
Try: sudo apt install <deb name>
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ ((1+2))
notfresh@DESKTOP-KO9EK8K:~/projects/zcommands$ $(1+2)
1+2: command not found
不换行
使用 \ 来表示不换行
for x in 1 2 3
do
echo x is $x \
2x is $((2 * x))
done
参考
Shell 中test 单中括号[] 双中括号的区别 - AndyBlog - 博客园 (cnblogs.com)
>>控制结构和基本结构
获取前一条命令的执行结果
echo $?
循环
for((i=1;i<10;i++))
for in 语句
for i in ${array[@]};do echo $i ;done # 遍历数组,输出: 1 3 4 5
for 变量 in 列表
do
command1
command2
...
commandN
done
或者
for var in list; do
i=1 for((;;)) do echo i if (( i > 3)); then break;fi; ((i=i+1)) # 或者 i=((i+1)) done
条件
条件判断 - Bash 脚本教程 - 网道 (wangdoc.com)
if 结构
if commands; then
commands
[elif commands; then
commands...]
[else
commands]
fi
[]表示可选。
例如:
if test $USER = "foo"; then
echo "Hello foo."
else
echo "You are not foo."
fi
if和then写在同一行时,需要分号分隔。分号是 Bash 的命令分隔符。它们也可以写成两行,这时不需要分号。
语法规则等同于Python,换行符或者分号作为一行的结束
if true
then
echo 'hello world'
fi
if false
then
echo 'it is false' # 本行不会执行
fi
除了多行的写法,if结构也可以写成单行。
$ if true; then echo 'hello world'; fi
hello world
$ if false; then echo "It's true."; fi
这么理解,if 和 then 是两个部分,必须用 分号隔开。
函数-定义和使用
使用函数不带(),第一个参数叫做 $1
shell中如何写一个函数呢? 这个问题, 首先说, shell中的函数, 在方法体里, 没有形参, 都是通过默认的特殊值获得的, 比如2, 参数的数量用. 而传参呢, 也是通过方法名后面跟参数来实现的. 数字是直接量,而"abc",即带引号的是字符串. 没有引号的字符串也是直接量.
返回值的读取
function func_return_value {
return 10
}
调用的时候,直接写函数名即可,后面的都是参数,用空格隔开
func_return_value
echo $?
一般来说,$? 表示执行结果。
参数的解析
linux-shell脚本中的参数解析 - Vincent-yuan - 博客园 (cnblogs.com)
>>类型系统和运算符
字符串
拼接不用+,注意了。
${}表示一个占位符, 放在单引号里无效。
Length
${#VARIBLE_NAME}
判断空
在书写linux shell 脚本我们经常会遇到,对一个字符串是否为空进行判断,下面我对几种常用的方法进行了一个总结:
1.-z判断
-z string
True if the length of string is zero.
if [ -z $i ]
then
echo "$i 是空字符串"
fi
2.加一个字符串再比较
if [ X$STR = "X" ]
then
echo "空字符串"
fi
3.直接使用变量判断
if [ "$variable" ]
then
echo "非空"
else
echo "空"
fi
注意:都要代双引号,否则有些命令会报错,在实际使用linux命令的时候,一定要记得注意这些符号,及语法的规则!
转义
对于某些运算符,还需要我们使用符号``进行转义,否则就会提示语法错误。比如乘号。
截取子字符串:
str="SnailClimb is a great man"
echo ${str:0:10} #输出:SnailClimb
数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
定义数组使用 (元素1 元素2)即可,中间用空格而非逗号隔开。
获取数组的长度:
length=${#array[@]}
echo ${array[2]} #输出:3
unset array[1] # 删除下标为1的元素也就是删除第二个元素
逻辑运算符
仅支持数字的
-eq, -lt -gt -ge -le, -ne
字符串运算符
= != -z
表达式运算符
$(())
`pwd` # 表示执行pwd并且返回结果
case
#!/bin/bash
if [ 1 -gt 2 ]
then echo 1
else echo 4
fi
echo "*****************************"
b="1234567890"
echo $b
echo ${b:1:3}
echo "b的长度是${#b}"
echo "*****************************"
echo "***************数组**************"
arr=(1 2 3 4 5)
echo "数组的长度是${#arr[@]}"
echo "数组的第二个元素是${arr[1]}"
echo "*****************************"
for i in ${arr[@]};
do
echo $i;
done
echo "*****************************"
for i in ${arr[*]};
do
echo $i;
done
c=`expr 1 + 2`
echo $c
#!/bin/bash
a=1
b=1
if [ $a -eq $b ]
then echo "a==b"
else echo "a!=b"
fi
echo "124"
if [ $a -eq $b -o $a -lt $b ]
then echo "1"
else echo "2"
fi
if [ !false ]
then echo "b"
fi
c=""
if [ ${#c}==0 ]
then echo "length is 0"
fi
>> 运行目录
从哪里启动脚本,哪里就是当前的运行目录
a.sh
b
s.sh
x.txt
如果在当前目录运行
>>数学运算
错误示范
read number
if [ $number -ge 2 && $number -ls 5 ]; then
echo"valid number"
break
else
echo"not valid number, try again"
fi
如果使用的是Bash,则最好使用算术表达式((...))以获得可读性和灵活性:
if ((number >= 2 && number <= 5));
then
do something as you like
fi
这里如此纠正:错误的:
if [ $number -ge 2 && $number -ls 5 ]; then
正确的:
if ["$number" -ge 2 ] && ["$number" -le 5 ]; then
此外,您还需要在脚本的第一行中添加一个shebang:#!/usr/bin/env bash
>>输入与输出
接受键盘输入
read a
read -p "提示语" a # mac系统不适用,没有 -p 参数
shell是一个糟糕的语言[至少它是一个语言]
0 不同shell的语法不一样
1 所有的变量都是字符串
2 if [ expression ];[ ] 是两个运算符,必须和 if 隔开。
source_bash_profile的解决方案
if [ -f ~/.bash_profile ]; then
source ~/.bash_profile
fi
从命令读取值
有两种方式可以将命令输出赋值给变量:
(1)反引号字符(`)
(2)$()格式
例如:
linuxidc=date
linuxidc=$(date)
生成列表中所需值就是使用命令的输出。
#!/bin/bash
reading values from a file
file="states"
for state in file)
do
echo "welcome $state"
done
states文件内容;
Hello World
Linuxmi com
linuxidc.net Linux公社
执行结果:
linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
welcome www.linuxidc.com
welcome Hello
welcome World
welcome Linuxmi
1 声明一个变量
用户创建变量的时候,变量名必须遵守下面的规则。
- 字母、数字和下划线字符组成。
- 第一个字符必须是一个字母或一个下划线,不能是数字。
- 不允许出现空格和标点符号。
变量声明的语法如下。
variable=value
上面命令中,等号左边是变量名,右边是变量。注意,等号两边不能有空格。
如果变量的值包含空格,则必须将值放在引号中。
myvar="hello world"
Bash 没有数据类型的概念,所有的变量值都是字符串。
变量可以重复赋值,后面的赋值会覆盖前面的赋值。
如果同一行定义多个变量,必须使用分号(;)分隔。
$ foo=1;bar=2
2 算术表达式
((...))语法可以进行整数的算术运算。
$ ((foo = 5 + 5))
$ echo $foo
10
((...))会自动忽略内部的空格,所以下面的写法都正确,得到同样的结果。
如果要读取算术运算的结果,需要在((...))前面加上美元符号$((...)),使其变成算术表达式,返回算术运算的值。
++和--这两个运算符有前缀和后缀的区别。作为前缀是先运算后返回值,作为后缀是先返回值后运算。
$((...))内部可以用圆括号改变运算顺序。
$ echo $(( (2 + 3) * 4 ))
20
$((...))结构可以嵌套。
$ echo $(((5**2) * 3))
75
# 等同于
$ echo $(($((5**2)) * 3))
75
这个语法只能计算整数,否则会报错。
# 报错
$ echo $((1.5 + 1))
bash: 语法错误
注意:在zsh下,这个语法就是支持的。
`,不过加上也不报错。
$ number=2
$ echo $(($number + 1))
3
上面例子中,变量number前面有没有美元符号,结果都是一样的。
如果在$((...))里面使用字符串,Bash 会认为那是一个变量名。如果不存在同名变量,Bash 就会将其作为空值,因此不会报错。
$ echo $(( "hello" + 2))
2
$ echo $(( "hello" * 2))
0
上面例子中,"hello"会被当作变量名,返回空值,而$((...))会将空值当作0,所以乘法的运算结果就是0。同理,如果$((...))里面使用不存在的变量,也会当作0处理。
逻辑运算
$((...))支持以下的逻辑运算符。
<:小于>:大于<=:小于或相等>=:大于或相等==:相等!=:不相等&&:逻辑与||:逻辑或!:逻辑否expr1?expr2:expr3:三元条件运算符。若表达式expr1的计算结果为非零值(算术真),则执行表达式expr2,否则执行表达式expr3。
5 test命令
if结构的判断条件,一般使用test命令,有三种形式。
# 写法一
test expression
# 写法二
[ expression ]
# 写法三
[[ expression ]]
上面的expression是一个表达式。这个表达式为真,test命令执行成功(返回值为0);表达式为伪,test命令执行失败(返回值为1)。注意,第二种和第三种写法,[和]与内部的表达式之间必须有空格。
但是第三种形式还支持正则判断,前两种不支持。
实际上,[这个字符是test命令的一种简写形式,可以看作是一个独立的命令,这解释了为什么它后面必须有空格。后面的叫 endstest
if关键字后面,跟的是一个命令。这个命令可以是test命令,也可以是其他命令。命令的返回值为0表示判断成立,否则表示不成立。因为这些命令主要是为了得到返回值,所以可以视为表达式。
Bash 还提供了((...))作为算术条件,进行算术运算的判断。
6 字符串判断
以下表达式用来判断字符串。
[ string ]:如果string不为空(长度大于0),则判断为真。[ -n string ]:如果字符串string的长度大于零,则判断为真。[ -z string ]:如果字符串string的长度为零,则判断为真。[ string1 = string2 ]:如果string1和string2相同,则判断为真。[ string1 == string2 ]等同于[ string1 = string2 ]。[ string1 != string2 ]:如果string1和string2不相同,则判断为真。[ string1 '>' string2 ]:如果按照字典顺序string1排列在string2之后,则判断为真。[ string1 '<' string2 ]:如果按照字典顺序string1排列在string2之前,则判断为真。
注意,test命令内部的>和<,必须用引号引起来(或者是用反斜杠转义)。否则,它们会被 shell 解释为重定向操作符。
- 同理。
7 文件判断
[ -e file ]:如果 file 存在,则为true。[ -f file ]:如果 file 存在并且是一个普通文件,则为true。
下面是一个示例。
#!/bin/bash
FILE=~/.bashrc
if [ -e "$FILE" ]; then
if [ -f "$FILE" ]; then
echo "$FILE is a regular file."
fi
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
if [ -r "$FILE" ]; then
echo "$FILE is readable."
fi
if [ -w "$FILE" ]; then
echo "$FILE is writable."
fi
if [ -x "$FILE" ]; then
echo "$FILE is executable/searchable."
fi
else
echo "$FILE does not exist"
exit 1
fi
上面代码中,$FILE要放在双引号之中,这样可以防止变量$FILE为空,从而出错。因为$FILE如果为空,这时[ -e $FILE ]就变成[ -e ],这会被判断为真。而$FILE放在双引号之中,[ -e "$FILE" ]就变成[ -e "" ],这会被判断为伪。
8 整数逻辑判断
[ integer1 -eq integer2 ]:如果integer1等于integer2,则为true。[ integer1 -ne integer2 ]:如果integer1不等于integer2,则为true。[ integer1 -le integer2 ]:如果integer1小于或等于integer2,则为true。[ integer1 -lt integer2 ]:如果integer1小于integer2,则为true。
数据结构
2.1 创建数组
数组可以采用逐个赋值的方法创建。
ARRAY[INDEX]=value
上面语法中,ARRAY是数组的名字,可以是任意合法的变量名。INDEX是一个大于或等于零的整数,也可以是算术表达式。注意数组第一个元素的下标是0, 而不是1。
下面创建一个三个成员的数组。
$ array[0]=val
$ array[1]=val
$ array[2]=va
数组也可以采用一次性赋值的方式创建。
ARRAY=(value1 value2 ... valueN)
# 等同于
ARRAY=(
value1
value2
value3
)
采用上面方式创建数组时,可以按照默认顺序赋值,也可以在每个值前面指定位置。
$ array=(a b c)
$ array=([2]=c [0]=a [1]=b)
$ days=(Sun Mon Tue Wed Thu Fri Sat)
$ days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)
只为某些值指定位置,也是可以的。
names=(hatter [5]=duchess alice)
上面例子中,hatter是数组的0号位置,duchess是5号位置,alice是6号位置。
没有赋值的数组元素的默认值是空字符串。
2.2 读取数组所有成员
@和*是数组的特殊索引,表示返回数组的所有成员。
$ foo=(a b c d e f)
$ echo ${foo[@]}
a b c d e f
这两个特殊索引配合for循环,就可以用来遍历数组。
for i in "${names[@]}"; do
echo $i
done
@和*放不放在双引号之中,是有差别的。
$ activities=( swimming "water skiing" canoeing "white-water rafting" surfing )
$ for act in ${activities[@]}; \
do \
echo "Activity: $act"; \
done
Activity: swimming
Activity: water
Activity: skiing
Activity: canoeing
Activity: white-water
Activity: rafting
Activity: surfing
上面的例子中,数组activities实际包含5个成员,但是for...in循环直接遍历${activities[@]},导致返回7个结果。为了避免这种情况,一般把${activities[@]}放在双引号之中。
$ for act in "${activities[@]}"; \
do \
echo "Activity: $act"; \
done
Activity: swimming
Activity: water skiing
Activity: canoeing
Activity: white-water rafting
Activity: surfing
上面例子中,${activities[@]}放在双引号之中,遍历就会返回正确的结果。
shell的变量文件加载
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. /etc/bashrc:为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取. ~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该 文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件. ~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该 该文件被读取. ~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件.
另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系.
~/.bash_profile 是交互式、login 方式进入 bash 运行的 ~/.bashrc 是交互式 non-login 方式进入 bash 运行的 通常二者设置大致相同,所以通常前者会调用后者。
设置生效:可以重启生效,也可以使用命令:source alias php=/var/eyouim/pub/php/bin/php source /etc/profile
查看端口占用情况
lsof -i:端口号 用于查看某一端口的占用情况
netstat -tunlp |grep 端口号,用于查看指定的端口号的进程情况
说明一下几个参数的含义:
-t (tcp) 仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化为数字
-l 仅列出在Listen(监听)的服务状态
-p 显示建立相关链接的程序名
实时查看日志文件和查看日志后100行
实时查看日志文件 tail -f 日志文件log
tail -f Console.log
2、实时查看日志文件 后一百行
tail - 100f Console.log
3、linux查看日志后100行
tail -n 100 Console.log
有两种解决办法:
*使用转义字符(反斜线)来将单引号转移;1
*使用双引号来定义用到单引号的值。
#!/bin/bash
#basic for command
for linuxidc in Kotlin Linuxmi'com linux Ubuntu "CentOS'rhel" Oracle
do
echo The next state is $linuxidc
done
执行结果:
linuxidc@linuxidc:~/linuxidc.com$ ./linuxidc.sh
The next state is Kotlin
The next state is Linuxmi'com
The next state is linux
The next state is Ubuntu
The next state is CentOS'rhel
The next state is Oracle
参考
[1] AWK 字符串拼接符 - 空格 ( ' ' )
[2] awk中如何输出单引号
[3] 2>&1的含义,segmentfault.com/a/119000004…
[4]参数解析,www.cnblogs.com/hxlinux/p/1…
介绍了shift的用法
##云服务器###############
阿里云服务器
Github在阿里云网络上无法访问,DNS可能出问题了,于是自己手动指定跳转。
说干就干,首先访问一个ip查询工具,这里使用 github.com.ipaddress.com/,然后分别查询 github.com 和 github.global.ssl.fastly.net 对应的 IP。
编辑主机的 hosts 文件,vim /etc/hosts,将查到的结果添加进去。
登录后复制 140.82.112.3 github.com 199.232.69.194 github.global.ssl.fastly.net
ssh免密登录
拷贝rsa
ssh 免密码登录需要使用公钥与私钥。linux下可以用ssh-keygen生成公钥/私钥对,以CentOS为例。
现有云主机A(192.168.1.155),云主机B(192.168.1.181)。现设置A机的user用户通过ssh免密码登录到B机的user用户。
如果是root用户设置免密登录,则将下述方法中的路径/home/user替换为/root即可,使用scp复制时也将目标机user替换为root即可。
1.在A机下生成公钥/私钥对。
[user@A ~]$ ssh-keygen -t rsa
出现交互界面要求输入密码、密钥保存路径等,均按回车以默认值生成即可
执行成功后在/home/user下生成.ssh目录,.ssh下有id_rsa和id_rsa.pub。
2.把A机下的id_rsa.pub复制到B机下相同路径下,使用scp命令,会要求输入B机user的登录密码,输入后回车即可完成复制
[user@A ~]$ scp .ssh/id_rsa.pub user@192.168.1.181:/home/user/id_rsa.pub
user@192.168.1.181's password:'s password:
id_rsa.pub 100% 223 0.2KB/s 00:00
3.B机把从A机复制的id_rsa.pub添加到/home/user/.ssh/authorized_keys 文件里。
[user@B ~]$ cat /home/user/id_rsa.pub >> /home/user/.ssh/authorized_keys
[user@B ~]$ chmod 600 /home/user/.ssh/authorized_keys
authorized_keys的权限需设置为600。
4.A机登录B机。
[user@A ~]$ ssh user@192.168.1.181
The authenticity of host 'B (192.168.1.181)' can't be established.
RSA key fingerprint is 00:a6:a8:87:eb:c7:40:10:39:cc:a0:eb:50:d9:6a:5b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.181' (RSA) to the list of known hosts.
Last login: Thu Mar 3 09:53:18 2018 from user
[user@B ~]$
第一次登录时需要输入yes将B主机加入A主机的已知主机列表中
现在A机user用户可以无密码登录B机user用户了。
想让A,B机user用户无密码互相登录,在B机上以上述方法配置,将B机生成的id_rsa.pub内容添加至A机的authorized_keys文件中即可。
原文参考:
ssh-copy-id
ssh-copy-id -i 公钥路径 user@host
指定秘钥
chmod 400 [.pem私钥文件在本地机上的存储路径]
chmod 400 ~/.ssh/ecs.pem
ssh -i [.pem私钥文件在本地机上的存储路径] username@[公网IP地址]
cd ~/.ssh
vim config
# 输入ECS实例的别名,用户SSH远程连接。
Host ecs
# 输入ECS实例的公网IP地址。
HostName 121.196.**.**
# 输入端口号,默认为22。
Port 22
# 输入登录账号。
User ecs-user
# 输入.pem私钥文件在本机的地址。
IdentityFile ~/.ssh/ecs.pem
ref
How to fix: "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED" on Mac and Linux (stackabuse.com)
阿里云主机开放端口
1、进入ECS云服务器控制台 2、先找到需要操作的目标实例,点击“更多”--“网络和安全组”--“安全组配置” 3、点击“配置规则” 4、点击“添加安全组规则”,添加8080号端口,如下图:
修改iptables,如果您未开通ECS内部防火墙,可以忽略此步骤。
sudo ufw status
麻烦您执行
sudo ufw allow 8080
iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
如果是内置的防火墙软件,使用命令查看:
service iptables status
服务查看
service --status-all
psef 服务名
hostname机器名
很多时候,很多机器名称是随机生成的,很奇怪,我们要修改个机器的名称
vim /etc/hostname 即可
查看ssh登录安全信息
vim /var/log/secure
查看实例监控信息
更新时间:2022年10月1日 01:46:00
监控您的ECS实例是否健康非常重要,您需要确保用户始终可以快速打开您的网站和应用,或者快速完成数据处理和渲染等任务。阿里云提供了监控数据收集、可视化以及实时监控告警等服务,确保您的实例始终处于正常的运行状态。
背景信息
目前,您可以通过ECS控制台和云监控控制台监控实例信息。ECS控制台提供vCPU使用率、网络流量和磁盘I/O监控,云监控控制台提供更加精细化的监控粒度。以下是对部分监控信息的说明:
-
vCPU:阿里云提供实例vCPU使用率监控数据,单位为百分比。百分比数值越高,实例vCPU负载越高。您可以通过ECS管理控制台、云监控管理控制台、调用ECS API或者远程连接实例后查询监控数据。以下是远程连接实例后查看vCPU使用率的方式:
- Windows实例:在任务管理器中查看vCPU使用情况,您可以按vCPU使用率排序,定位占用实例vCPU资源的进程。
- Linux实例:运行
**top**命令查看vCPU使用情况。在键盘上按下Shift+P根据vCPU使用率排序,定位占用实例vCPU资源的进程。
说明 如果CPU持续保持高使用率,则会对系统稳定性和业务运行造成影响。您可以参见以下方法进行优化:
- Linux实例请参见Linux系统CPU负载的查询和案例分析。
- Windows实例请参见Windows实例中CPU使用率较高问题的排查及解决方法。
-
网络流量:阿里云提供实例出方向和入方向的网络流量监控数据,单位为kbps。ECS控制台一般提供公网流量监控,云监控控制台可以提供公网和内网流量监控。例如,您的公网出网带宽为1 Mbps,当出网流量达到1024 kbps,表示您的公网带宽已经满负荷。
说明 经典网络公网带宽监控数据不包含高防回源流量,如需查看完整监控数据,请登录云监控管理控制台。
通过ECS控制台查看监控信息
在ECS管理控制台上查看ECS实例监控信息的操作步骤如下所示。
-
登录ECS管理控制台。
-
在左侧导航栏,选择实例与镜像 > 实例。
-
在顶部菜单栏左上角处,选择地域。
-
找到目标实例,单击实例ID。
-
在实例详情页,单击监控页签。
-
设置监控时间范围,可以查看vCPU使用率、内存使用率等监控信息。
说明
-
由于显示的聚合方式不一样,选择时间段的长短会影响显示的精度。选择时间范围越小,显示效果越精细。例如,1小时和6小时的平均值会显示不一样的结果。
-
实例是否安装云监控插件会导致在ECS控制台查看到的监控数据不同:
- 如果实例未安装云监控插件,在ECS控制台查看到的监控项与云监控的基础监控项一致。
- 如果实例已安装云监控插件,ECS控制台的监控项中,CPU、内存、系统负载数据为云监控的操作系统监控项,其他监控项与云监控的基础监控项一致。
基础监控项数据采集频率为每1分钟一次,操作系统监控项数据采集频率为每15秒一次。更多信息,请参见监控项说明。
-
您也可以使用DescribeInstanceMonitorData、DescribeDiskMonitorData和DescribeEniMonitorData接口获取监控数据。
apt
修改Ubuntu源为阿里云
add-apt-repository
- 安装软件 查看已经安装的软件 dpkg –l |grep vim
- 更改软件源
- 删除ppa源 blog.csdn.net/li_hai/arti…
linux安装搜狗输入法
TODO www.cnblogs.com/hupeng1234/… 安装完记得注销,否则找不到搜狗输入法
linux安装deb包
- 下载deb包
- dpkg –i 包名
- apt-get –f install : 修复依赖关系 非常重要!!
安装软件解锁
sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock
安装sublime
1、安装Sublime Text 3
首先添加sublime text 3的仓库:
sudo add-apt-repository ppa:webupd8team/sublime-text-3
根据提示按ENTER 继续,建立信任数据库
更新软件库
sudo apt update
安装Sublime Text 3
sudo apt install sublime-text-installer
安装mysql
sudo apt update
sudo apt search mysql-server-version(说不定可以加通配符)
安装报错
dpkg: 另外一个进程已经为状态数据库加了锁
稍作等等,后台正在更新,想要解决这个问题, 在系统设置里把自动更新关掉!!!
ubuntu安装python3
使用apt安装
sudo add-apt-repository ppa:jonathonf/python-3.6
sudo apt-get update
sudo apt-get install python3.6
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2
sudo update-alternatives --config python3
python3 –V
which python3: /usr/local/bin/python3
相关工作
参考
1 查看监控,help.aliyun.com/document_de…](help.aliyun.com/document_de…)
rsync 用法教程
这篇博客是来自阮一峰的。他还有很有优秀的博客。
作者: 阮一峰
日期: 2020年8月26日
一、简介
rsync 是一个常用的 Linux 应用程序,用于文件同步。
它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也可以当作文件复制工具,替代cp和mv命令。
它名称里面的r指的是 remote,rsync 其实就是"远程同步"(remote sync)的意思。与其他文件传输工具(如 FTP 或 scp)不同,rsync 的最大特点是会检查发送方和接收方已有的文件,仅传输有变动的部分(默认规则是文件大小或修改时间有变动)。
二、安装
如果本机或者远程计算机没有安装 rsync,可以用下面的命令安装。
# Debian
$ sudo apt-get install rsync
# Red Hat
$ sudo yum install rsync
# Arch Linux
$ sudo pacman -S rsync
注意,传输的双方都必须安装 rsync。
三、基本用法
3.1 -r 参数
本机使用 rsync 命令时,可以作为cp和mv命令的替代方法,将源目录同步到目标目录。
$ rsync -r source destination
上面命令中,-r表示递归,即包含子目录。注意,-r是必须的,否则 rsync 运行不会成功。source目录表示源目录,destination表示目标目录。
如果有多个文件或目录需要同步,可以写成下面这样。
$ rsync -r source1 source2 destination
上面命令中,source1、source2都会被同步到destination目录。
3.2 -a 参数
-a参数可以替代-r,除了可以递归同步以外,还可以同步元信息(比如修改时间、权限等)。由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新,所以-a比-r更有用。下面的用法才是常见的写法。
$ rsync -a source destination
目标目录destination如果不存在,rsync 会自动创建。执行上面的命令后,源目录source被完整地复制到了目标目录destination下面,即形成了destination/source的目录结构。
如果只想同步源目录source里面的内容到目标目录destination,则需要在源目录后面加上斜杠。
$ rsync -a source/ destination
上面命令执行后,source目录里面的内容,就都被复制到了destination目录里面,并不会在destination下面创建一个source子目录。
3.3 -n 参数
如果不确定 rsync 执行后会产生什么结果,可以先用-n或--dry-run参数模拟执行的结果。
$ rsync -anv source/ destination
上面命令中,-n参数模拟命令执行的结果,并不真的执行命令。-v参数则是将结果输出到终端,这样就可以看到哪些内容会被同步。
3.4 --delete 参数
默认情况下,rsync 只确保源目录的所有内容(明确排除的文件除外)都复制到目标目录。它不会使两个目录保持相同,并且不会删除文件。如果要使得目标目录成为源目录的镜像副本,则必须使用--delete参数,这将删除只存在于目标目录、不存在于源目录的文件。
$ rsync -av --delete source/ destination
上面命令中,--delete参数会使得destination成为source的一个镜像。
四、排除文件
4.1 --exclude 参数
有时,我们希望同步时排除某些文件或目录,这时可以用--exclude参数指定排除模式。
$ rsync -av --exclude='*.txt' source/ destination
# 或者
$ rsync -av --exclude '*.txt' source/ destination
上面命令排除了所有 TXT 文件。
注意,rsync 会同步以"点"开头的隐藏文件,如果要排除隐藏文件,可以这样写--exclude=".*"。
如果要排除某个目录里面的所有文件,但不希望排除目录本身,可以写成下面这样。
$ rsync -av --exclude 'dir1/*' source/ destination
多个排除模式,可以用多个--exclude参数。
$ rsync -av --exclude 'file1.txt' --exclude 'dir1/*' source/ destination
多个排除模式也可以利用 Bash 的大扩号的扩展功能,只用一个--exclude参数。
$ rsync -av --exclude={'file1.txt','dir1/*'} source/ destination
如果排除模式很多,可以将它们写入一个文件,每个模式一行,然后用--exclude-from参数指定这个文件。
$ rsync -av --exclude-from='exclude-file.txt' source/ destination
4.2 --include 参数
--include参数用来指定必须同步的文件模式,往往与--exclude结合使用。
$ rsync -av --include="*.txt" --exclude='*' source/ destination
上面命令指定同步时,排除所有文件,但是会包括 TXT 文件。
五、远程同步
5.1 SSH 协议
rsync 除了支持本地两个目录之间的同步,也支持远程同步。它可以将本地内容,同步到远程服务器。
$ rsync -av source/ username@remote_host:destination
也可以将远程内容同步到本地。
$ rsync -av username@remote_host:source/ destination
rsync 默认使用 SSH 进行远程登录和数据传输。
由于早期 rsync 不使用 SSH 协议,需要用-e参数指定协议,后来才改的。所以,下面-e ssh可以省略。
$ rsync -av -e ssh source/ user@remote_host:/destination
但是,如果 ssh 命令有附加的参数,则必须使用-e参数指定所要执行的 SSH 命令。
$ rsync -av -e 'ssh -p 2234' source/ user@remote_host:/destination
上面命令中,-e参数指定 SSH 使用2234端口。
5.2 rsync 协议
除了使用 SSH,如果另一台服务器安装并运行了 rsync 守护程序,则也可以用rsync://协议(默认端口873)进行传输。具体写法是服务器与目标目录之间使用双冒号分隔::。
$ rsync -av source/ 192.168.122.32::module/destination
注意,上面地址中的module并不是实际路径名,而是 rsync 守护程序指定的一个资源名,由管理员分配。
如果想知道 rsync 守护程序分配的所有 module 列表,可以执行下面命令。
$ rsync rsync://192.168.122.32
rsync 协议除了使用双冒号,也可以直接用rsync://协议指定地址。
$ rsync -av source/ rsync://192.168.122.32/module/destination
六、增量备份
rsync 的最大特点就是它可以完成增量备份,也就是默认只复制有变动的文件。
除了源目录与目标目录直接比较,rsync 还支持使用基准目录,即将源目录与基准目录之间变动的部分,同步到目标目录。
具体做法是,第一次同步是全量备份,所有文件在基准目录里面同步一份。以后每一次同步都是增量备份,只同步源目录与基准目录之间有变动的部分,将这部分保存在一个新的目标目录。这个新的目标目录之中,也是包含所有文件,但实际上,只有那些变动过的文件是存在于该目录,其他没有变动的文件都是指向基准目录文件的硬链接。
--link-dest参数用来指定同步时的基准目录。
$ rsync -a --delete --link-dest /compare/path /source/path /target/path
上面命令中,--link-dest参数指定基准目录/compare/path,然后源目录/source/path跟基准目录进行比较,找出变动的文件,将它们拷贝到目标目录/target/path。那些没变动的文件则会生成硬链接。这个命令的第一次备份时是全量备份,后面就都是增量备份了。
下面是一个脚本示例,备份用户的主目录。
#!/bin/bash
# A script to perform incremental backups using rsync
set -o errexit
set -o nounset
set -o pipefail
readonly SOURCE_DIR="${HOME}"
readonly BACKUP_DIR="/mnt/data/backups"
readonly DATETIME="$(date '+%Y-%m-%d_%H:%M:%S')"
readonly BACKUP_PATH="${BACKUP_DIR}/${DATETIME}"
readonly LATEST_LINK="${BACKUP_DIR}/latest"
mkdir -p "${BACKUP_DIR}"
rsync -av --delete \
"${SOURCE_DIR}/" \
--link-dest "${LATEST_LINK}" \
--exclude=".cache" \
"${BACKUP_PATH}"
rm -rf "${LATEST_LINK}"
ln -s "${BACKUP_PATH}" "${LATEST_LINK}"
上面脚本中,每一次同步都会生成一个新目录${BACKUP_DIR}/${DATETIME},并将软链接${BACKUP_DIR}/latest指向这个目录。下一次备份时,就将${BACKUP_DIR}/latest作为基准目录,生成新的备份目录。最后,再将软链接${BACKUP_DIR}/latest指向新的备份目录。
七、配置项
-a、--archive参数表示存档模式,保存所有的元数据,比如修改时间(modification time)、权限、所有者等,并且软链接也会同步过去。
--append参数指定文件接着上次中断的地方,继续传输。
--append-verify参数跟--append参数类似,但会对传输完成后的文件进行一次校验。如果校验失败,将重新发送整个文件。
-b、--backup参数指定在删除或更新目标目录已经存在的文件时,将该文件更名后进行备份,默认行为是删除。更名规则是添加由--suffix参数指定的文件后缀名,默认是~。
--backup-dir参数指定文件备份时存放的目录,比如--backup-dir=/path/to/backups。
--bwlimit参数指定带宽限制,默认单位是 KB/s,比如--bwlimit=100。
-c、--checksum参数改变rsync的校验方式。默认情况下,rsync 只检查文件的大小和最后修改日期是否发生变化,如果发生变化,就重新传输;使用这个参数以后,则通过判断文件内容的校验和,决定是否重新传输。
--delete参数删除只存在于目标目录、不存在于源目标的文件,即保证目标目录是源目标的镜像。
-e参数指定使用 SSH 协议传输数据。
--exclude参数指定排除不进行同步的文件,比如--exclude="*.iso"。
--exclude-from参数指定一个本地文件,里面是需要排除的文件模式,每个模式一行。
--existing、--ignore-non-existing参数表示不同步目标目录中不存在的文件和目录。
-h参数表示以人类可读的格式输出。
-h、--help参数返回帮助信息。
-i参数表示输出源目录与目标目录之间文件差异的详细情况。
--ignore-existing参数表示只要该文件在目标目录中已经存在,就跳过去,不再同步这些文件。
--include参数指定同步时要包括的文件,一般与--exclude结合使用。
--link-dest参数指定增量备份的基准目录。
-m参数指定不同步空目录。
--max-size参数设置传输的最大文件的大小限制,比如不超过200KB(--max-size='200k')。
--min-size参数设置传输的最小文件的大小限制,比如不小于10KB(--min-size=10k)。
-n参数或--dry-run参数模拟将要执行的操作,而并不真的执行。配合-v参数使用,可以看到哪些内容会被同步过去。
-P参数是--progress和--partial这两个参数的结合。
--partial参数允许恢复中断的传输。不使用该参数时,rsync会删除传输到一半被打断的文件;使用该参数后,传输到一半的文件也会同步到目标目录,下次同步时再恢复中断的传输。一般需要与--append或--append-verify配合使用。
--partial-dir参数指定将传输到一半的文件保存到一个临时目录,比如--partial-dir=.rsync-partial。一般需要与--append或--append-verify配合使用。
--progress参数表示显示进展。
-r参数表示递归,即包含子目录。
--remove-source-files参数表示传输成功后,删除发送方的文件。
--size-only参数表示只同步大小有变化的文件,不考虑文件修改时间的差异。
--suffix参数指定文件名备份时,对文件名添加的后缀,默认是~。
-u、--update参数表示同步时跳过目标目录中修改时间更新的文件,即不同步这些有更新的时间戳的文件。
-v参数表示输出细节。-vv表示输出更详细的信息,-vvv表示输出最详细的信息。
--version参数返回 rsync 的版本。
-z参数指定同步时压缩数据。
八、参考链接
- How To Use Rsync to Sync Local and Remote Directories on a VPS, Justin Ellingwood
- Mirror Your Web Site With rsync, Falko Timme
- Examples on how to use Rsync, Egidio Docile
- How to create incremental backups using rsync on Linux, Egidio Docile
(完)