1. 切换成root user
sudo su root
退出root用户
su -
2. 查看被占用的端口并删除进程
不管哪个平台netstat
都可以被用来查看哪些端口已经被占用或启用,常用参数有
-a
或--all
:显示所有连线中的Socket。
-i或--interfaces 显示网络界面信息表单。
-n
或--numeric
:直接使用IP地址,而不通过域名服务器。
-p
或--programs
:显示正在使用Socket的程序识别码和程序名称。
-s
或--statistics
:显示网络工作信息统计表。
-t
或--tcp
:显示TCP传输协议的连线状况。
-u
或--udp
:显示UDP传输协议的连线状况。
显示TCP端口号的使用情况
> netstat -t
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 288 mail:ssh 192.168.1.124:64483 ESTABLISHED
tcp 0 0 mail:ssh 192.168.1.124:64942 ESTABLISHED
> netstat -nt # 如果不用域名解析
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 288 192.168.0.90:22 192.168.1.124:64483 ESTABLISHED
tcp 0 0 192.168.0.90:22 192.168.1.124:64942 ESTABLISHED
显示网卡列表
> netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
docker0 1500 180487 0 0 0 387758 0 0 0 BMRU
ens33 1500 1623376 0 0 0 508323 0 0 0 BMRU
lo 65536 296 0 0 0 296 0 0 0 LRU
显示网络统计信息
> netstat -s
Linux/Mac
查看某个端口是否被占用
lsof -i :8080
杀死进程
kill -15 <PID>
Windows
查看某个端口是否被占用
netstat -aon|findstr "8080"
杀死进程
taskkill /T /F /PID <PID>
3. 本地文件信息查询
df: 显示磁盘分区上可以使用的磁盘空间
-a
: 查看全部文件系统,单位默认KB
-h
: 以KB、MB、GB的单位来显示,可读性高
查看磁盘容量的使用情况
df -h
显示使用率100%,解决方法是去删除比较大无用的文件
-i
: 查看inode包含的信息:文件的字节数,拥有者id,组id,权限,改动时间,链接数,数据block的位置
df -i
显示使用率100%,解决方法是去删除数量过多的小文件
du: 显示每个文件和目录的磁盘使用空间~~~文件的大小
-d
或--max-depth
: 指深度,后面加一个数值
-s
: 仅显示目录的总值,单位KB
-h
: 以K M G为单位显示,提高可读性
du -d 1 -h
cd ..
查看文件类型
通过file
命令查看
-i
:输出文件的 MIME 类型字符串
-b
:不输出文件名
-F
:自定义分隔符(注意默认的冒号是紧贴文件名后方的,因此自定义符号可能需要前置空格)
$ file daemon-uat.sh
daemon-uat.sh: ASCII text
$ file -i spinqCloud-server-3.9.0.jar
spinqCloud-server-3.9.0.jar: application/java-archive; charset=binary
$ file -b -i spinqCloud-server-3.9.0.jar
application/java-archive; charset=binary
$ file -F ' =>' spinqCloud-server-3.9.0.jar
spinqCloud-server-3.9.0.jar => Java archive data (JAR)
如果通过 file 命令直接查看软链接文件,则查看的就是软链接文件本身的信息。如果使用-L
选项来查看软链接文件,则查看的是软链接指向的目标文件的信息。
查看文件个数
通过ls
查看,实际上显示的是ls
所得条数,等同于文件个数
ls -l | grep "^-"|wc -l # 统计当前目录下文件的个数(不包括子目录)
ls -l | grep -c "^-" # 统计当前目录下文件的个数(不包括子目录)
ls -lR | grep "^-"|wc -l # 查询当前目录下所有目录子目录下文件的个数
ls -lR | grep -c "^-" # 查询当前目录下所有目录子目录下文件的个数
ls -l <dir_name> | grep "^-"|wc -l # 查看某目录下文件夹(目录)的个数(包括子目录)
ls -l <dir_name> -c grep "^-" # 查看某目录下文件夹(目录)的个数(包括子目录)
通过find
查看
find ./ -type f | wc -l
ls修改查找到的文件排序
ls
默认按照文件名排列文件
-S
按照从大到小排列文件
-t
按照修改时间从晚到早排列文件
-r
将排序结果反向输出,比如,若原本文件名由小到大,反向则为由大到小
-R
递归输出目录下所有文件(注意和-r
区分)
因此ls -tlh
则为按照时间倒序输出当前目录下的文件,ls -t | head -n 1
则为自动回滚脚本常用的找到最新备份
判断文件或文件夹是否存在
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
判断文件是否为空(文件不存在同为false)
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
判断文件是否大于maxsize
filesize=' ls -l $filename | awk '{ print $5}' ' #获取文件本身大小
maxsize=$((1024*10)) #最大内存10k
if [ $filesize -gt $maxsize ] #判断文件是否大于某个内存大小,
then
echo "exceeds 10KB"
else
echo "does not exceed 10KB"
fi
找出最近更新的文件
不包含子目录
ls -lt spinq_playbook/ | grep "yml" | head -n 1 | awk '{print $9}'
# ls -lt 按时间排序
# grep 按关键词搜索
# head -n 取前n条
# awk 取出文件名
du -sh
与df -h
大小有区别
用户删除了大量的文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它。然而如果此时还有运行的进程持有这个已经被删除的文件句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改,df仍会统计这个被删除的文件。
可通过lsof |grep deleted
命令查询处于deleted状态的文件,被删除的文件在系统中被标记为deleted。如果系统有大量deleted状态的文件,会导致du和df统计结果不一致。
杀死或重启持有文件句柄的进程可以释放调用,使df -h
回到与du -sh
一样大小
du -h
与ls -lah
大小有区别
ls -lah
显示的是文件的实际大小。
du -h
不是显示文件大小,而是显示文件所占用的block大小,默认linux系统分区的block size是4k,也就是说即使文件只有1个字节,也会占用4k,
5. 复制
cp
命令复制文件到某地
可以通过cp -l
和cp -s
分别建立源文件的硬链接和软链接
'-p':保留源文件的属性,对于备份文件很重要。
'-d':如果源文件是软链接,不使用'-d'时复制的是源文件,只有加入了'-d' 才会复制软链接文件(对硬链接无效)。
'-a':同时执行'-p','-d','-r'
如果该地点有同名文件,则覆盖(使用-i选项则会询问是否覆盖)
> ls
test.txt childDir
> cat test.txt
This is a new scp test
> cp test.txt childDir
> cd childDir
> cat test.txt
This is a new scp test
> echo "test in child" > test.txt
> cat test.txt
test in child
> cp test.txt ../
> cd ../
> cat test.txt
test in child
cp -r
递归复制命令在不同情况下表现不一样
> ls A # see what's in directory A
index.html, index.js
# If B/C exists
> cp -r A B/C
> ls B/C
A
# If B exists, but B/C does not exist
> cp -r A B/C
> ls B/C
index.html, index.js
# If B does not exist
> cp -r A B/C
No such file error
本地复制到远程
scp .\loading.gif root@my.remote.ip.address:/var/helper
远程复制到本地
scp root@my.remote.ip.address:/var/helper/loading.gif ./
和cp
一样,如果复制到的地点有同名文件/文件夹,则源文件会被覆盖
6. cat
利用cat
查看行号
cat -n file1 # output file1 with line numbers in stdout
利用cat
清空文件
cat /dev/null > file1 # clear file1
7. wget
Linux/Mac
wget https://www.spinq.cn/media/hero_video.f79c7ed6.mp4
如果在windows powershell使用的话需要指定Outfile
才可以成功下载
wget -Uri https://www.spinq.cn/media/hero_video.f79c7ed6.mp4 -OutFile "official.mp4"
另外在windows上第一次运行时可能会报错
wget : 无法分析响应内容,因为 Internet Explorer 引擎不可用,或者 Internet Explorer 的首次启动配置不完整。请指定 UseBasicParsing 参数,然后再试一次。
所在位置 行:1 字符: 1
+ wget -Uri https://www.spinq.cn/media/hero_video.f79c7ed6.mp4
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (:) [Invoke-WebRequest], NotSupportedException
+ FullyQualifiedErrorId : WebCmdletIEDomNotSupportedException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
应按照这个方法配置IE的访问权限
8. 查看系统版本
Linux
# 系统版本1
> cat /etc/issue
Ubuntu 18.04.5 LTS \n \l
# 系统版本2
> lsb_release -a
LSB Version: core-9.20170808ubuntu1-noarch:security-9.20170808ubuntu1-noarch
Distributor ID: Ubuntu
Description: Ubuntu 18.04.5 LTS
Release: 18.04
Codename: bionic
# 系统位数
> getconf LONG_BIT
64
# 内核版本
> cat /proc/version
Linux version 4.15.0-111-generic (buildd@lcy01-amd64-011) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #112-Ubuntu SMP Thu Jul 9 20:32:34 UTC 2020
Windows
> systeminfo
主机名: DESKTOP-U15VCI2
OS 名称: Microsoft Windows 10 家庭中文版
OS 版本: 10.0.18363 暂缺 Build 18363
OS 制造商: Microsoft Corporation
OS 配置: 独立工作站
OS 构建类型: Multiprocessor Free
注册的所有人: sunyuchen2014@gmail.com
注册的组织: HP
产品 ID: 00342-35830-00447-AAOEM
初始安装日期: 2020/6/28, 3:30:31
系统启动时间: 2021/3/15, 9:02:11
系统制造商: HP
系统型号: HP Pavilion Gaming Desktop TG01-1xxx
系统类型: x64-based PC
处理器: 安装了 1 个处理器。
[01]: Intel64 Family 6 Model 165 Stepping 3 GenuineIntel ~2904 Mhz
......
9. 安装和卸载软件
Ubuntu
sudo apt-get update # 更新安装列表
sudo apt-get upgrade # 升级软件
sudo apt list --installed # 查看已安装的所有软件
sudo apt install <plugin_name> # 安装软件
sudo apt --purge remove <plugin_name> # 卸载软件及其配置
sudo apt autoremove <plugin_name> # 卸载软件及其依赖的安装
10. 查看内存使用情况
Linux
free -h # 人类能看懂的方式显示
free -m # MB的方式显示
free -g # GB方式显示
Mac
$ top -l 1 | head -n 10 | grep PhysMem
PhysMem: 11G used (2952M wired), 5426M unused.
11. 查看硬盘使用情况
Linux/Mac
查看挂载磁盘的使用情况
$ top -l 1 | head -n 10 | grep Disk
Disks: 114285549/844G read, 348750697/4503G written.
$ df -h
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk1s1 233Gi 201Gi 22Gi 91% 2893896 9223372036851881911 0% /
devfs 189Ki 189Ki 0Bi 100% 652 0 100% /dev
/dev/disk1s4 233Gi 10Gi 22Gi 32% 10 9223372036854775797 0% /private/var/vm
map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net
map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home
/dev/disk1s3 233Gi 487Mi 22Gi 3% 36 9223372036854775771 0% /Volumes/Recovery
查看文件夹内每个子类的大小
du -sh * # 查看当前文件夹内每个子类的大小
du -sh # 查看当前文件夹总大小
12. RSA key-pair
生成rsa key-pair
$ ssh-keygen -t rsa -C "email@example.com" -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/test/.ssh/id_rsa.
Your public key has been saved in /home/test/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:iTmthm0NBebPx1+7HOgUKi7lb6BZgkNux/lQ1Sfew5s email@example.com
The key's randomart image is:
+---[RSA 4096]----+
| o . |
| o . . o . |
| . .. . = |
| . B.o . + |
| o o=oS o . .+ |
| =o*=+. o +E. |
| ..o=Xo.. + o |
| o+.o..o . o |
| ..o. . o |
+----[SHA256]-----+
修改rsa key-pair的passphrase
$ ssh-keygen -p
Enter file in which the key is (/home/test/.ssh/id_rsa):
Enter old passphrase:
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
将公钥文件copy到远程主机上
ssh-copy-id 192.168.X.XXX # 复制到root
ssh-copy-id -i /home/<username1>/.ssh/id_rsa.pub <username2>@192.168.X.XXX # 复制到特定用户
13. History
查看历史记录
通过history
和grep
组合可以通过关键词查询最近使用过的命令
$ history | grep 'git' | head -n 5
111 git commit -m "Modify the circuit board style"
112 git push
115 git status
116 git add .
117 git commit -m "Add delete buttons"
14. 滚动查看日志内容
tail -n +10 <filename> # 查看文件最后10行
tail -f <filename> # 滚动查看文件末尾
15. dmesg
dmesg命令用于显示开机信息
可以通过dmesg快速查看到因为内存溢出(OOM)而被杀死的进程
$ dmesg
[3569070.202443] [30468] 1000 30468 4304677 1426482 11968512 0 0 java
[3569070.202444] [30612] 1000 30612 10454 151 131072 0 0 top
[3569070.202446] Out of memory: Kill process 30468 (java) score 712 or sacrifice child
[3569070.203167] Killed process 30468 (java) total-vm:17218708kB, anon-rss:5705928kB, file-rss:0kB, shmem-rss:0kB
[3569070.382575] oom_reaper: reaped process 30468 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
16. top
top命令用于实时显示 process 的动态。
参数
-i<时间> 设置间隔时间
-u<用户名> 指定用户名
-p<进程号> 指定进程
-n<次数> 循环显示的次数
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
27689 mila 20 0 4563616 988872 19408 S 0.0 12.3 2:44.15 java
14781 mila 20 0 4704184 808616 18016 S 0.0 10.1 11:49.85 java
849 mila 20 0 700416 82308 25776 S 0.0 1.0 0:08.60 gunicorn
846 mila 20 0 699364 80700 25548 S 0.0 1.0 0:08.52 gunicorn
844 mila 20 0 699240 80564 25292 S 0.0 1.0 0:08.68 gunicorn
845 mila 20 0 699240 80368 25208 S 0.0 1.0 0:08.55 gunicorn
16583 mila 20 0 700432 60708 4236 S 0.0 0.8 0:08.53 gunicorn
16584 mila 20 0 700444 59512 3036 S 0.0 0.7 0:08.20 gunicorn
16585 mila 20 0 699244 59064 3844 S 0.0 0.7 0:08.22 gunicorn
16587 mila 20 0 699244 58468 3256 S 0.0 0.7 0:08.11 gunicorn
21536 root 19 -1 138584 47624 36048 S 0.0 0.6 0:14.56 systemd-journal
8668 root 10 -10 155072 25928 10944 S 0.7 0.3 114:14.94 AliYunDun
RES
行为我们需要的内存占用量,默认以字节为单位,超过1MB或1GB后末尾会有m
的字样g
进入top模式后,摁M
使进程按照内存占有量从大到小排列
进入top模式后,摁q
退出跟踪进程
进入top模式后,摁1
查看每个cpu占用
更多看这里
17. 打包与压缩
tar 打包
gzip 压缩
无法保留源文件
无法直接压缩文件夹,压缩文件夹前需要使用tar打包
$ ls
test.sh test2.sh
$ gzip test*.sh # 压缩
$ ls
test.sh.gz test2.sh.gz
$ zcat test.sh.gz # 展示压缩文件的内容
# ============ Test 1 of zip ================
echo 'Good morning'
$ gzip -l *.gz # 查看压缩信息
compressed uncompressed ratio uncompressed_name
177 201 25.4% test2.sh
268 358 32.4% test.sh
445 559 25.0% (totals)
$ gzip -d test*.sh.gz # 解压
$ ls
test.sh test2.sh
如果目录下已经有同名压缩文件,则询问是否覆盖,若选择覆盖则替换当前目录下的同名压缩文件,若选择不覆盖则终止压缩
$ ls
test.sh test2.sh
$ gzip test.sh
$ ls
test.sh.gz test2.sh
$ zcat test.sh.gz # 展示压缩文件test.sh.gz的内容
# ============ Test 1 of zip ================
echo 'Good morning'
$ mv test2.sh test.sh
$ ls
test.sh.gz test.sh
$ gzip test.sh
gzip: test.sh.gz already exists; do you wish to overwrite (y or n)? n
not overwritten
$ gzip test.sh
gzip: test.sh.gz already exists; do you wish to overwrite (y or n)? y
$ zcat test.sh.gz # 展示压缩文件test.sh.gz的内容
# ============ Test 2 of zip ================
echo 'Good evening'
默认目录下有同名压缩文件时自动合并两个压缩文件
if [ -e $compressed_filename ]
then
echo "压缩文件存在,需要合并"
mv $1 "$1.tmp"
gzip "$1.tmp"
zcat $compressed_filename "$1.tmp.gz" | gzip - > "$1.final.gz"
mv "$1.final.gz" $compressed_filename
rm "$1.tmp.gz"
else
echo "压缩文件不存在,成功压缩"
gzip $1
fi
zip 压缩
可以保留源文件,还可以压缩目录
-
-r
递归打包子目录下所有文件 -
-v
可视化操作过程,默认就是可视化的 -
-q
静默操作过程 -
b
表示块设备 -
-n
设置压缩级别 -
-e
加密压缩文件,会要求输入密码 -
-u
追加文件到压缩包
zip -r my.zip /my/ // 压缩文件夹
zip -u my.zip new.txt // 追加文件到压缩包
18. 寻找/归类文件
Linux寻找文件find
find <dir>
在某目录下查找,会列出所有子目录与文件
-name
查找对应名字的文件,可以使用正则
find /home -name “*.txt"
-type
查找对应类型的文件
-
f
表示文件 -
d
表示目录 -
c
表示字符设备 -
b
表示块设备 -
s
表示套接字 -
l
表示链接
find /home -type f
--mindepth
和--maxdepth
限制递归查找的层数
find /home -maxdepth 2 -type f
-o
表示或,!
表示否定
find /home -name “*.txt" -o -name “*.pdf" # 查找以.txt或.pdf结尾的文件
find /home ! -name ".txt" # 查找不是以.txt结尾的文件
Windows寻找文件Get-ChildItem
foreach ($var in Get-ChildItem . -Recurse -Name -exclude *.png) {cat $var > test.txt}
unzip解压
把文件解压到当前目录下
unzip test.zip
解压到指定文件夹下
unzip -d /test test.zip
不覆盖已经存在的文件
unzip -n -d /test test.zip
不必先询问用户,覆盖已经存在的文件
unzip -o -d /test test.zip
只看一下zip包里存在那些文件,不进行解压
unzip -l test.zip
执行时显示详细的信息,包括zip包里的文件和压缩比率
unzip -v test.zip
查看zip包是否损坏
unzip -t test.zip
18. Windows 休眠
取消休眠:以管理员权限运行终端,输入
powercfg.exe /hibernate off
启用休眠:以管理员权限运行终端,输入
powercfg.exe /hibernate on
19. screen
GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。
列出当前所有的session
screen -ls
回到yourname这个session
screen -r yourname
远程detach某个session
screen -d yourname
结束当前session并回到yourname这个session
screen -d -r yourname
杀死某个session
screen -X -S <PID> quit
进入screen会话后,可在会话中创建多个窗口(window),并对窗口进行管理,管理命令以ctrl + a开头。
ctrl + a + c:创建新窗口(create)
ctrl + a + n:切换至下一个窗口(next)
ctrl + a + p:切换至上一个窗口(previous)
ctrl + a + w: 列出所有窗口
ctrl + a + A: 窗口重命名
ctrl + a + [1-9]: 切换到指定窗口(1-9为窗口号)
ctrl + d:退出(关闭)当前窗口
ctrl + a + d:detach当前会话给后台 回到主会话
tcpdump
Linux上的抓包工具,可以抓出包后放在wireshark上可视化解析
很有用的链接
sudo tcpdump -nnX -s 0 port 80 or port 8080 # 只监听80和8080端口的信息
sudo tcpdump -nnX -s 0 src 123.XXX.XXX.XXX and dst 456.XXX.XXX.XXX # 只监听特定来源和目标的信息
sudo tcpdump -nnX -s 0 -w /home/spinq/tcpdump/test.cap 2>&1 &
sudo tcpdump -X -s 0 -w /home/spinq/tcpdump/test.notip.cap 2>&1 &
$(ps aux | grep tcpdump | awk '{print $2}' | xargs sudo kill -9)
20. grep
grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设 grep 指令会把含有范本样式的那一列显示出来
对于通过日志debug非常有用
可以结合head
或tail
来查找文件中最先/最后符合搜索条件的n行
$ grep "onMessage" task-INFO.log | head -n 5
[com.example.controller.MachineController 2021-07-27 00:00:00.651] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
[com.example.controller.MachineController 2021-07-27 00:00:00.658] INFO Method: onMessage(Line 66) - machineCode = 1, sessionId = 3
[com.example.controller.MachineController 2021-07-27 00:00:00.658] INFO Method: onMessage(Line 67) - Receive message string {"commandType": "updateMachineStatus", "machineStatus": "AVAILABLE", "timestamp": "2021-07-26T16:00:01.1069Z", "machineCode": "1", "platformCode": "platform1"}
[com.example.controller.MachineController 2021-07-27 00:00:00.659] INFO Method: onMessage(Line 93) - Request after parsing = MachineRequest(machineCode=1, platformCode=platform1, timestamp=Tue Jul 27 00:00:01 CST 2021, machineStatus=AVAILABLE, commandType=updateMachineStatus, taskResultRequest=null, stageUpdateRequest=null)
[[com.example.controller.MachineController 2021-07-27 00:00:00.659] INFO Method: onMessage(Line 110) - ============== Exit MachineController - onMessage ==============
$ grep "onMessage" task-INFO.log | tail -n 5
[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 66) - machineCode = 1, sessionId = 3
[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 67) - Receive message string {"commandType": "updateMachineStatus", "machineStatus": "AVAILABLE", "timestamp": "2021-07-27T01:58:23.1181Z",, "machineCode": "1", "platformCode": "platform1"}
[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 93) - Request after parsing = MachineRequest(machineCode=1, platformCode=platform1, timestamp=Tue Jul 27 09:58:23 CST 2021, machineStatus=AVAILABLE, commandType=updateMachineStatus, taskResultRequest=null, stageUpdateRequest=null)
[[com.example.controller.MachineController 2021-07-27 09:58:22.557] INFO Method: onMessage(Line 110) - ============== Exit MachineController - onMessage ==============
-c
: 计算符合样式的列数
$ grep -c "onMessage" task-INFO.log
197076
-n
: 在显示符合样式的那一行之前,标示出该行的列数编号
$ grep "onMessage" task-INFO.log | tail -n 5
1058154:[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
1058155:[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 66) - machineCode = 1, sessionId = 3
1058156:[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 67) - Receive message string {"commandType": "updateMachineStatus", "machineStatus": "AVAILABLE", "timestamp": "2021-07-27T01:58:23.1181Z",, "machineCode": "1", "platformCode": "platform1"}
1058160:[com.example.controller.MachineController 2021-07-27 09:58:22.533] INFO Method: onMessage(Line 93) - Request after parsing = MachineRequest(machineCode=1, platformCode=platform1, timestamp=Tue Jul 27 09:58:23 CST 2021, machineStatus=AVAILABLE, commandType=updateMachineStatus, taskResultRequest=null, stageUpdateRequest=null)
1058161:[com.example.controller.MachineController 2021-07-27 09:58:22.557] INFO Method: onMessage(Line 110) - ============== Exit MachineController - onMessage ==============
-e
: 寻找符合正则表达式的关键词
$ grep -e "onMessage.*Enter" task-INFO.log | head -n 5
[com.example.controller.MachineController 2021-07-27 00:00:00.651] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
[com.example.controller.MachineController 2021-07-27 00:00:02.104] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
[com.example.controller.MachineController 2021-07-27 00:00:02.249] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
[com.example.controller.MachineController 2021-07-27 00:00:02.655] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
[com.example.controller.MachineController 2021-07-27 00:00:04.243] INFO Method: onMessage(Line 65) - ============== Enter MachineController - onMessage ==============
-r
: 递归检索文件夹
$ grep -r "task" backup-2021-06 | head -n 5
backup-2021-06/console_2021-06-22_00.log.gz:[com.example.task.dto.TaskQueue 2021-06-21 09:31:58.187] INFO Method: hasTaskProcessingByMachine(Line 171) - ============== Enter isProcessingByMachine with mid = 1 ==============
backup-2021-06/console_2021-06-22_00.log.gz:[com.example.task.dto.TaskQueue 2021-06-21 09:31:58.187] INFO Method: hasTaskProcessingByMachine(Line 180) - ============== Exit isProcessingByMachine with mid = 1 and reuslt = false ==============
backup-2021-06/console_2021-06-22_00.log.gz:[com.example.task.service.TaskMachineService 2021-06-21 09:31:58.188] INFO Method: assignToMachine(Line 175) - ============== Enter assignToMachine ==============
backup-2021-06/console_2021-06-22_00.log.gz:[com.example.task.dto.TaskQueue 2021-06-21 09:31:58.188] INFO Method: hasTaskProcessingByMachine(Line 171) - ============== Enter isProcessingByMachine with mid = 2 ==============
backup-2021-06/console_2021-06-22_00.log.gz:[com.example.task.dto.TaskQueue 2021-06-21 09:31:58.188] INFO Method: hasTaskProcessingByMachine(Line 180) - ============== Exit isProcessingByMachine with mid = 2 and reuslt = false ==============
21. 设置链接
使用ln
命令
-s
参数表示建立软链接文件,如不写默认产生硬链接
-f
参数表示强制。如果目标文件已经存在,则删除目标文件后再建立链接文件。
软链接文件的源文件必须写成绝对路径,而不能写成相对路径(硬链接没有这样的要求)
# source为源文件,target为想要产生的链接
ln -fs <source> <target> # 设置软链接
ln -fs <source> <target> # 设置硬链接
22. ps查看进程信息
ps的参数比较多,最常使用的格式如下
ps aux
显示所有包含其他使用者的行程,返回的格式信息为
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME CMD
ps -aux
的用法其实不正确,其真正意义为打印用户名为"x"的用户的所有进程。一些版本的系统会在用户名为x的用户不存在时直接将命令转义为ps aux
且打出一个警告。而新版Mac则会直接报错
ps: No user named 'x'
ps -ef
显示所有进程信息,连同命令行,返回的格式信息为
UID PID PPID C STIME TTY TIME CMD
ps -ef | grep mysqld. #查看mysql进程pid
ps -u <username>
查看特定用户进程
查看使用CPU最多的前10进程
ps aux | sort -nr -k3 | head -10
查看使用内存最多的前10进程
ps aux | sort -nr -k4 | head -10
sort
命令用于对输入进行排序。
-n
表示以数值进行排序(默认为字符型)。
-r
表示反向排序,即从大到小。
-k3
表示按照第三列(也就是 CPU 使用率)进行排序。
23. sed做字符串替换
多个匹配规则可以用;
来分隔
sed "s/backend_src_path=.*/backend_src_path='${input}'/g; s/backend_env=.*/backend_env=uat/g" filename
可以直接带入变量
$ input=aaa
$ sed "s/backend_src_path=.*/backend_src_path='${input}'/g" filename
当变量中有特殊字符/
的时候可以通过修改分隔符来避免错误
$ input=/home/spinq
$ sed "s#backend_src_path=.*#backend_src_path=${input}#g" filename
24. 防火墙
Ubuntu
sudo ufw status # 信息
sudo ufw status verbose # 详细信息
sudo ufw allow 2222/tcp # 允许2222端口的TCP
sudo ufw allow 2222/udp # 允许2222端口的UDP
sudo ufw enable # 设置开机启动
sudo ufw disabe # 禁用开机启动
sudo ufw reload # 重启防火墙
25. 查看和设置环境变量
以下的修改均为临时修改,长期修改需要更新配置文件
bash
env # 查看所有环境变量
echo $FLASK_ENV # 查看某个环境变量
FLASK_ENV=development # 在当前用户会话设置环境变量,其他用户无法使用
export FLASK_ENV=development # 将设置提升为全局环境变量
export PATH=$PATH:/home/go # 追加环境变量
unset FLASK_ENV # 删除环境变量
powershell
ls env: # 查看所有环境变量
$env:FLASK_ENV # 查看某个环境变量
$env:FLASK_ENV = "development" # 设置环境变量
(type env:path) -split ';' # 分割path,换行显示每一条
(type env:path) -split ';' | sls bin # 过滤搜索符合条件的path
$env:Path="$env:Path;C:\sysin" # 追加环境变量
del env:FLASK_ENV # 删除环境变量
cmd
set FLASK_ENV # 查看某个环境变量
echo %FLASK_ENV% # 查看某个环境变量
set FLASK_ENV=development # 在当前会话设置环境变量
set path=%path%;d:\go # 追加环境变量
set FLASK_ENV= # 设置环境变量为空,等同于删除
26. 后台运行
Powershell
开始后台执行一个任务(关掉terminal会终止任务)
> Start-Job python run.py
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
18 4 388 1772 0.05 11424 1 python
如果想要获取任务的结果要用Receive-Job
开始后台执行一个任务(关掉terminal无影响)
-PassThru
表示要输出进程信息
> Start-Process -PassThru -WindowStyle hidden python run.py
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
18 4 388 1772 0.05 11424 1 python
获取进程信息
> Get-Process <process-name>
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
231 32 553368 40548 0.42 11424 1 python
227 32 555328 44004 0.64 14164 1 python
终止执行一个进程
> Stop-Process -Name <process-name> -Force
> Stop-Process -ID <pid> -Force
Linux/Unix
开始后台进程
nohup python run.py > nohup.log 2>&1 &
终止进程
kill -15 <pid>
27. 查看cpu以及内核数
总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
Linux
查看CPU信息(型号)
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo | grep "cpu cores"| uniq
查看逻辑CPU的个数
cat /proc/cpuinfo | grep "processor"| wc -l
查看线程数
grep 'processor' /proc/cpuinfo | sort -u | wc -l
28. tree
tree 以树状格式列出目录的内容
tree <dir_name>. # 以树状图显示某个目录
-a:显示所有文件和目录(默认不打印隐藏文件)
-C:输出条目加上色彩,便于区分类型
-d:只显示目录名
-f:在每个文件或目录之前,显示完整的相对路径
-i:不以阶梯状列出文件或目录名称,与-f
选项结合使用时非常有用
-I PATTERN:不显示符合通配符模式的文件或目录
-P PATTERN:只显示符合通配符模式的文件或目录
-L LEVEL:目录树的最大显示深度
-o FILENAME:输出到指定文件
--dirsfirst:在文件之前列出目录
--filelimit LIMIT:不要显示包含超过 LIMIT 个条目的目
29. 删除网卡
sudo ifconfig cni0 down
sudo ip link delete cni0
30. 展示iptable名单
sudo iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
31. curl
用来发送网络请求
-X
: 请求方法,默认为GET
-H
: 用来添加header
-d
: 请求体参数,默认格式为application/x-www-form-urlencoded
,传递json时需要添加header Content-Type: application/json
-s/--silent
: 静音模式。不输出任何东西
-o/--output
: 把输出写到该文件中
-O/--remote-name
: 把输出写到该文件中,保留远程文件的文件名
-C
: 支持断点续传
-v
: 打印请求回复详情,可debug用
-V
: 查看工具版本
-L/--location
: 当服务器报告被请求页面已被移动到另一位置时(通常返回3XX错误代码),允许curl使用新的地址重新访问
查看版本
$ curl -V
curl 8.0.1 (Windows) libcurl/8.0.1 Schannel WinIDN
Release-Date: 2023-03-20
Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp
Features: AsynchDNS HSTS HTTPS-proxy IDN IPv6 Kerberos Largefile NTLM SPNEGO SSL SSPI threadsafe Unicode UnixSockets
GET request with query params
When adding -d
,HTTP method will automatically return to POST, so need to add -G
to declare HTTP method to GET.
// method 1
$ curl -G http://localhost:5000/getTest?key1=val1&key2=val2
{"status":200,"msg":""}
// method 2
$ curl -d "key1=val1" -d "key1=val2" -G http://localhost:5000/getTest
{"status":200,"msg":""}
// when have space, need to use --data-urlencode to encoding data
$ curl --data-urlencode "key1=val1" --data-urlencode "key1=val2" -G http://localhost:5000/getTest
{"status":200,"msg":""}
POST request with json body
$ curl -X POST https://localhost:5000/activate -H 'Content-Type: application/json' -d '{"activateCode": "abcde", "softwareType": "t1"}'
{"status":200,"msg":""}
NOTICE: 使用Windows cmd时,因为字符解析的关系,以上请求会报错
{"status":1005,"msg":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported"}curl: (6) Could not resolve host: application
curl: (3) URL using bad/illegal format or missing URL
curl: (3) URL using bad/illegal format or missing URL
curl: (3) unmatched close brace/bracket in URL position 15:
t1}'
需要将引号转义,即可正常执行
$ curl --location -X POST https://localhost:5000/activate -H "Content-Type: application/json" -d "{\"activateCode\": \"abcde\", \"softwareType\": \"t1\"}"
{"status":200,"msg":""}
Can read in local file as input
$ cat data.txt
{"activateCode": "abcde", "softwareType": "t1"}
$ curl https://google.com/login /localhost:5000/activate -H 'Content-Type: application/json' -d '@data.txt'
{"status":200,"msg":""}
POST request with form body
$ curl -X POST https://edu.spinq.cn:5000/activateByForm \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode 'activateCode=abcde' --data-urlencode 'softwareType=t1'
{"status":200,"msg":""}
save webpage output to file
$ curl -o baidu.html http://www.baidu.com
$ curl -o -C baidu.html http://www.baidu.com # 断线后重新下载
-O
可以用来下载远程文件,并保留它的名字
$ curl -O http://www.baidu.com/hello.sh
查看自己的公网IP
$ curl cip.cc
IP : 113.87.216.223
地址 : 中国 广东 深圳
运营商 : 电信
数据二 : 广东省深圳市 | 电信
数据三 : 中国广东省深圳市 | 电信
URL : http://www.cip.cc/113.87.216.223
脚本中测试服务器是否正常,可以发送请求后获取它的状态码,再根据是否为200进行下一步操作
$ status=`curl -o /dev/null -s -w %{http_code} www.baidu.com`
// can use the value of status in later codes
$ echo $status
200
可以通过参数-v
来打印所有请求详情,以便debug
$ curl -v http://www.baidu.com
* Trying 14.119.104.189:80...
* Connected to www.baidu.com (14.119.104.189) port 80 (#0)
> GET / HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/8.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Connection: keep-alive
< Content-Length: 2381
< Content-Type: text/html
< Date: Wed, 31 May 2023 02:33:07 GMT
< Etag: "588604dc-94d"
< Last-Modified: Mon, 23 Jan 2017 13:27:56 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
...
32. base64加密解密
Linux
$ echo "SGVsbG8gd29ybGQ=" | base64 -d
Hello world
Windows Powershell
$ [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("SGVsbG8gd29ybGQ="))
Hello world
33. TCP Alive time
设置操作系统的net.ipv4.tcp_keepalive_time
,单位是秒
sudo sysctl -w net.ipv4.tcp_keepalive_time=300
查看操作系统的net.ipv4.tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_time
34. 修改电脑时间
$ date
Wed Jan 3 09:28:49 AM CST 2024
修改操作系统时间,使用timedatectl
,适用于所有有systemd的系统
$ sudo timedatectl set-timezone Asia/Shanghai
$ sudo hwclock --systohc # 同步系统时间到硬件时间
查看所有可用的时区
ls /usr/share/zoneinfo/