子曰:"工欲善其事, 必先利其器."
做一个积极的人
编码, 改 bug, 提升自己
我有一个乐园, 面向编程, 春暖花开!
学习应该是快乐的, 在这个乐园中我努力让自己能用简洁易懂 (搞笑有趣) 的表达来讲解让知识或者技术, 让学习之旅充满乐趣, 这就是写博文的初心.
今天是周末, 首先祝大家周末愉快了, 分享一张今天早上去外面拍的照片:
图书馆外面的小公园的春意.
这周整理了 Linux 的命令, 也被我称为 Linux 的魔法. 本篇回顾一些命令(魔法), 然后通过实际的应用场景, 使用这些命令(魔法).
故事旁白:
在哈利波特的电影中, 有许多的魔法咒, 比如复制成双: 复制咒, 使物体消失: 消隐无踪咒, 使物体归拢一起: 收拾咒, 移动物体: 移形幻影咒, 给我指路: 定向咒等等.
在 Linux 的魔法世界中, 同样也存在许多命令 (魔法) 文件复制 (cp) 魔法, 文件移形幻影 (mv) 魔法, 文件归拢一起 (tar) 魔法, 文件消隐无踪 (rm) 魔法(文件消失无踪魔法使用不当那就堪称 阿瓦达索命).
魔法地图:
在 Linux 下,"一切皆是文件"!
1, 磁盘占用
当服务器运行一段时间后, 会有数据的堆积. 此时我们用使用 df 魔法去看一下磁盘目前使用的空间情况, 如下:
[aflyun@localhost ~]$ df -h
文件系统 容量 已用 可用 已用 % 挂载点
- /dev/mapper/CentOS-root 17G 2.0G 16G 12% /
- devtmpfs 485M 0 485M 0% /dev
- tmpfs 496M 0 496M 0% /dev/shm
- tmpfs 496M 6.8M 490M 2% /run
- tmpfs 496M 0 496M 0% /sys/fs/cgroup
- /dev/sda1 1014M 129M 886M 13% /boot
- tmpfs 100M 0 100M 0% /run/user/0
但是当知道了一个挂载的磁盘下面没有空间时候, 怎么知道那个目录下面文件占用磁盘空间最多呢? 那就使用 du 魔法. 如下:
- # 查看 /home/aflyun 各个目录占用磁盘空间大小
- [aflyun@localhost ~]$ du -lh --max-depth=1
- 193M ./tools
- 0 ./magic
- 193M
各参数说明 :
- # -h 或 - human-readable 以 K,M,G 为单位, 提高信息的可读性.
- # -l 或 - count-links 重复计算硬件连接的文件.
- # -max-depth=<目录层数> 超过指定层数的目录后, 予以忽略.
应用场景: Linux 服务器磁盘空间占用, 大文件查找.
2, 删除文件
删除 (rm) 魔法, 也就是类似使物体消失: 消隐无踪咒. 这个魔法如果使用不当那就是 一个黑魔法(如阿瓦达索命).
正常使用:
- [aflyun@localhost rmtest]$ touch testrm1 restrm2
- [aflyun@localhost rmtest]$ mkdir -p testrmdir/0317
- [aflyun@localhost rmtest]$ mkdir testrmdir1
- [aflyun@localhost rmtest]$ cd testrmdir/0317/
- [aflyun@localhost 0317]$ touch testrm3
- [aflyun@localhost rmtest]$ ll
总用量 0
-rw-rw-r--. 1 aflyun aflyun 0 3 月 17 14:48 restrm2
-rw-rw-r--. 1 aflyun aflyun 0 3 月 17 14:48 testrm1
drwxrwxr-x. 3 aflyun aflyun 18 3 月 17 14:49 testrmdir
drwxrwxr-x. 2 aflyun aflyun 6 3 月 17 14:50 testrmdir1
- [aflyun@localhost rmtest]$
- # 1. 删除一个文件
- [aflyun@localhost rmtest]$ rm testrm1
- # 2. 删除文件之前询问
- [aflyun@localhost rmtest]$ rm -i restrm2
rm: 是否删除普通空文件 "restrm2"?
- # 注: Enter : 删除, ctrl +c : 退出
- # 3. 强制递归删除文件或者目录
- [aflyun@localhost rmtest]$ rm -f testrmdir
rm: 无法删除 "testrmdir": 是一个目录
- [aflyun@localhost rmtest]$ rm -rf testrmdir
- [aflyun@localhost rmtest]$ ll
总用量 0
drwxrwxr-x. 1 aflyun aflyun 6 3 月 17 14:50 testrmdir1
参数说明:
-i 删除前逐一询问确认.
-f 即使原档案属性设为唯读, 亦直接删除, 无需逐一确认.
-r 将目录及以下之档案亦逐一删除.
使用不当, 可能就要跑路喽!:
- # 1. 直接敲命令删除日志文件
- [aflyun@localhost ~]$ rm -rf / home/aflyun/logs/
- # 看出什么 端倪了没有. 提示一下: 一定不要拷贝这条命令去执行!!!
- # 如果你真的好奇, 那建议在自己的虚拟机上试试, 满足一下你的好奇心.
- # 这条命令中 "多了个空格"!
- # 2. 脚本中使用, 删除日志文件
- [aflyun@localhost ~]$ VIM cleanlog.sh
- cd ${
- log_path
- }
- rm -rf *
- # 进入到日志目录, 然后把日志都删除.
- # 乍看没有任何问题? 但是当目录不存在时, 那悲剧也就发生了.
注意:: 在生产环境上, 执行 rm 命令的时候, 一定擦亮眼睛, 否则一回车, 就是 "千古恨"!
友情建议:
可以在生产环境把 rm -rf 命令替换为 mv, 再写个定时 shell 定期清理. 模拟了回收站的功能.
参考: rm -rf * 了咋办, 跑路吗? http://t.cn/Exyx5f5
3, 查找文件
当你忘记文件 / 目录具体在哪个地方的时候, 请使用 find 魔法.
- # 3.1 查找 / home/aflyun 目录下面的所有文件
- [aflyun@localhost ~]$ find /home/aflyun/
- /home/aflyun/
- /home/aflyun/.bash_logout
- /home/aflyun/.bash_profile
- /home/aflyun/.bashrc
- /home/aflyun/tools
- /home/aflyun/tools/apache-tomcat-8.5.38.tar.gz
- /home/aflyun/tools/jdk-8u191-Linux-x64.tar.gz
- /home/aflyun/magic
- /home/aflyun/magic/happy.log
- /home/aflyun/rmtest
- /home/aflyun/rmtest/restrm2
- /home/aflyun/rmtest/testrmdir1
- # 3.2 查找 / home/aflyun 目录中所有大于 10M 的文件并列出来
- [aflyun@localhost ~]$ find /home/aflyun -size +5M -exec ls -lh {
- } \;
-rw-r--r--. 1 root root 9.3M 3 月 17 14:35 /home/aflyun/tools/apache-tomcat-8.5.38.tar.gz
-rw-r--r--. 1 root root 183M 3 月 17 14:35 /home/aflyun/tools/jdk-8u191-Linux-x64.tar.gz
参数说明:
- # /home/aflyun 指的是当前目录 你也可以指定目录 /home/happy
- # -size 文件大小
- # +10M 注意 M 是大写的 意思大于 10M
- # -exec ls -lh {
- } \; 管道 列出来并标明大小
- # ls -lh 以 k M G 的形式列出来
注: 确保不要在你 Linux 系统的根目录运行该命令, 因为这可能导致你的机器 I/O 瓶颈.
- # 3.3 查找 /home/aflyun 下面 REST 的文件, 忽略大小写
- [aflyun@localhost ~]$ find /home/aflyun/ -iname REST* -type f
- /home/aflyun/rmtest/restrm2
- /home/aflyun/rmtest/Restrm
参数说明:
- # -i 忽略大小写
- # -name 文件名
- # 3.4 查找文件或者目录
- [aflyun@localhost ~]$ find /home/aflyun -iname REST* -type f
- /home/aflyun/rmtest/restrm2
- /home/aflyun/rmtest/Restrm
- [aflyun@localhost ~]$ find /home/aflyun -iname REST* -type d
- /home/aflyun/rmtest/restrmdir1
- # 3.5 find 和它的朋友 exec 组合使用, 3.2 已经用过
- # 忽略大小写 , 查找 REST 开头的文件, 并删除文件
- [aflyun@localhost ~]$ ll rmtest/
总用量 0
-rw-rw-r--. 1 aflyun aflyun 0 3 月 17 15:33 Restrm
-rw-rw-r--. 1 aflyun aflyun 0 3 月 17 14:48 restrm2
drwxrwxr-x. 2 aflyun aflyun 6 3 月 17 14:50 restrmdir1
- [aflyun@localhost ~]$
- [aflyun@localhost ~]$ find /home/aflyun -iname REST* -type f -exec rm -f {
- } \;
- [aflyun@localhost ~]$
- [aflyun@localhost ~]$ ll rmtest/
总用量 0
drwxrwxr-x. 2 aflyun aflyun 6 3 月 17 14:50 restrmdir1
4, 服务状态
在服务器上我们一般会允许很多的服务, 一般公司会有服务器状态检测机制. 那我们通过命令怎么查看服务是否启动, 以 tomcat 为例子.
- # 4.1 查看 tomcat 服务启动状态
- [aflyun@localhost bin]$ ps -aux | grep tomcat
- aflyun 5142 0.0 0.0 113308 688 pts/0 S 15:41 0:00 /bin/sh /home/aflyun/tools/apache-tomcat-8.5.38/bin/catalina.sh start
- aflyun 5143 3.4 8.6 2296124 87748 pts/0 Sl 15:41 0:05 /usr/local/java/jdk1.8.0_191/bin/java -Djava.util.logging.config.file=/home/aflyun/tools/apache-tomcat-8.5.38/conf/logging.properties
..... 省略
- # 4.1.1 另一种方式看服务状态, 输出不是 0 , 代表服务启动状态
- [aflyun@localhost bin]$ ps -aux | grep -P "/home/aflyun/tools/apache-tomcat-8.5.38/" | grep -v "\sgrep\s" | wc -l
- 2
- [aflyun@localhost bin]$
注: 服务是启动了, 但是不代表服务是正常的. 有时候 tomcat 服务查看是正常的, 但是接口无法访问, 有假死情况等!
# 4.2 再次启动 tomcat 遇到 8080 端口被占用
java.NET.BindException: 地址已在使用 (Bind failed)
- at java.NET.PlainSocketImpl.socketBind(Native Method)
- java.NET.BindException: Port already in use (Bind failed)
- at java.NET.PlainSocketImpl.socketBind(Native Method)
- # 查看端口 8080 的使用情况
- [aflyun@localhost bin]$ netstat -alnp | grep 8080
- (Not all processes could be identified, non-owned process info
- will not be shown, you would have to be root to see it all.)
- tcp6 0 0 :::8080 :::* LISTEN 5143/java
- # 查看端口属于哪个程序
- lsof -i :8080
- [aflyun@localhost bin]$ lsof -i :8080
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- java 5143 aflyun 49u IPv6 40442 0t0 TCP *:webcache (LISTEN)
- [aflyun@localhost bin]
- # 注: 5143 pid 就是上面查看 tomat 的 pid.
5, 日志查看
在工作中, 经常会遇到线上项目出现问题, 需要排查! 然而在茫茫的日志文件中, 如何快速的找到报错的地方的日志, 以及快速定位和解决问题, 这是一种能力, 这种能力是可以在平时工作中锻炼出来的.
- # 5.1 查看 tomcat 的日志, 滚动输出
- [aflyun@localhost logs]$ tail -f catalina.out
- # 5.2 查看 tomcat 的日志中包含 aflyun 的字符, 滚动输出
- [aflyun@localhost logs]$ tail -f catalina.out | grep "java 编程技术乐园"
- # 5.3 查看 tomcat 的日志中包含 "地址已在使用" 内容的行数
- # cat -n 文件名 | grep 搜索名称
- [aflyun@localhost logs]$ cat -n catalina.out | grep "地址已在使用"
83 Caused by: java.NET.BindException: 地址已在使用
117 Caused by: java.NET.BindException: 地址已在使用
145 java.NET.BindException: 地址已在使用 (Bind failed)
- [aflyun@localhost logs]$
- # 5.4 查看 tomcat 的日志中包含 "地址已在使用" 内容的 83 行, 前后 10 行日志
- # cat -n 文件名 | tail -n + 起始行数 |head -n + 查询多少行数
- [aflyun@localhost logs]$ cat -n catalina.out | tail -n +73 | head -n +20
- 73 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- 74 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
- 75 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- 76 at java.lang.reflect.Method.invoke(Method.java:498)
- 77 at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)
- 78 at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
- 79 Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
- 80 at org.apache.catalina.connector.Connector.initInternal(Connector.java:995)
- 81 at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
- 82 ... 12 more
83 Caused by: java.NET.BindException: 地址已在使用
- 84 at sun.nio.ch.NET.bind0(Native Method)
- 85 at sun.nio.ch.NET.bind.NET.java:433)
- 86 at sun.nio.ch.NET.bind.NET.java:425)
- 87 at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
- 88 at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
- 89 at org.apache.tomcat.util.NET.NioEndpoint.bind(NioEndpoint.java:219)
- 90 at org.apache.tomcat.util.NET.AbstractEndpoint.init(AbstractEndpoint.java:1087)
- 91 at org.apache.tomcat.util.NET.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:265)
- 92 at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:581)
- [aflyun@localhost logs]$
注: 日志相关的东西很多, 这里强调一下, 关键的地方一定要打日志, 要不出了问题, 及时你会各种 Linux 的魔法, 日志中没有输出出现问题的内容(当前的请求参数, 响应参数等), 你也就是一个 "巧妇", 因为巧妇难为无米之炊. 日志一定要记录好! 否则出了问题就苦恼 + 浪费很多时间排查! 重视每个环节!
6, 定时任务
crontab 命令常见于 https://baike.baidu.com/item/Unix 和类 Unix https://baike.baidu.com/item/类Unix 的操作系统之中, 用于设置周期性被执行的指令. 该命令从标准输入设备读取指令, 并将其存放于 "crontab" 文件中, 以供之后读取和执行.
crontab 命令的参数:
-e : 执行文字编辑器来设定时程表, 内定的文字编辑器是 VI, 如果你想用别的文字编辑器,
则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
-r : 删除目前的时程表
-l : 列出目前的时程表
注: Linux crontab 命令, 最小的执行时间是一分钟.
- # 6.1, 写一个脚本, 使用 crontab 执行, 每 2s 执行一次!
- [aflyun@localhost crontabtest]$ touch printlog.sh
- [aflyun@localhost crontabtest]$ touch print.log
- [aflyun@localhost crontabtest]$ VIM printlog.sh
- [aflyun@localhost crontabtest]$ cat printlog.sh
- #!/bin/bash
- ttime=`date +"%Y-%m-%d %H:%M:%S"`
- echo "$ttime,Welcome to Java 编程技术乐园">>/home/aflyun/crontabtest/print.log
- #-------------------------
- # 1. 覆盖 echo "">文件名
- # 2. 追加 echo "">>文件名
- [aflyun@localhost crontabtest]$ chmod 755 printlog.sh
- [aflyun@localhost crontabtest]$ ll
总用量 8
-rw-rw-r--. 1 aflyun aflyun 1264 3 月 17 16:36 print.log
-rwxr-xr-x. 1 aflyun aflyun 132 3 月 17 16:34 printlog.sh
- [aflyun@localhost crontabtest]$
- # 6.2, 写一个定时的任务
- # crontab -e 输入以下语句, 然后 :wq 保存退出. 保存后可以使用 crontab -l 查看定时任务.
- * * * * */home/aflyun/crontabtest/printlog.sh
- * * * * * sleep 1 && /home/aflyun/crontabtest/printlog.sh
- * * * * * sleep 2 && /home/aflyun/crontabtest/printlog.sh
- ...
- * * * * * sleep 59 && /home/aflyun/crontabtest/printlog.sh
- # 6.3 查看打印的日志
- [aflyun@localhost crontabtest]$ cat print.log
2019-03-17 16:34:01,Welcome to Java 编程技术乐园
2019-03-17 16:34:02,Welcome to Java 编程技术乐园
....
备注: crontab 命令 的时程表的格式如下
# f1 f2 f3 f4 f5 program
f1 是表示分钟, f2 表示小时, f3 表示一个月份中的第几日, f4 表示月份, f5 表示一个星期中的第几天
program 表示要执行的程序.
当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序, 其馀类推
当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行, f2 为 a-b 时表示从第 a 到第 b 小时都要执行, 其馀类推
当 f1 为 /n 时表示每 n 分钟个时间间隔执行一次, f2 为 /n 表示每 n 小时个时间间隔执行一次, 其馀类推
当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行, f2 为 a, b, c,... 时表示第 a, b, c... 个小时要执行, 其馀类推
本文总结
来源: https://www.cnblogs.com/aflyun/p/10547761.html