====== Linux 命令实践 ======
本篇并不是大而全的命令合集,只是摘录了本人工作中经常遇到或者使用到的一些命令及使用场景。
===== 日志管理&搜索排序 =====
==== 统计文件中的重复行并按照出现次数排序 ====
sort data | uniq -c | sort -r
==== 查找文件内关键字并统计 ====
egrep -c "Keyword_or_regPattern" file.log
==== 查找文件中的IP地址并去重 ====
其中sort -g 表示按照数值排序,默认为按照ascii码
egrep -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" pg-01-30.csv | uniq -c | sort -rgk1
==== 直接搜索gz压缩文件 ====
gzip -c *.gz | grep TAG
==== awk ====
awk 'BEGIN{} {statement;statement;statement;} END{}' filename
BEGIN区域可以设定初始化参数,比如分割符,常见初始变量为: FS=列分隔符,NR=行(记录分隔符)
多个分隔符用[]包括起来,如FS="[=;]"表示"="和";"都作为列分隔符
===== 系统管理 =====
==== 进程管理 ====
=== 查找内存使用最大的进程 ===
# 按照第四列(内存列降序排序)
ps aux | sort -rk4 | more
=== PS命令:显示特定列并按照指定列排序 ===
ps -e -o pid,comm=,wchan,trs,drs,vsz,rss --sort=-vsz
ps ax o pid,%cpu,%mem,psr,trs,drs,vsz,rss,cmd k -vsz
-o 列表
pid: 进程号
comm=: 命令行
args: 完整命令行
wchan: 等待链,运行中的程序用"-"标识,多线程程序用"*"标识
trs: 进程代码空间占用的内存数量
drs: 进程数据空间占用的内存数量,drs == vsz - trs
vsz: 进程申请的内存数量(不代表实际占用的数量)
rss: 进程实际占用的内存数量
%mem: 内存百分比
%cpu: cpu百分比
--sort=[+-]%cpu, 按照cpu使用排序,+为升序,-为降序
=== CPU 性能问题 ===
**Linux kslowd占用CPU问题临时解决办法**
# Linux Kernel 2.6.35 及以下内核出现问题
echo N> /sys/module/drm_kms_helper/parameters/poll
==== 内存&SWAP管理 ====
=== 创建SWAP文件 ===
mkdir /swap
dd if=/dev/zero of=/swap/swap01 bs=1M count=512 #创建一个512M的文件
chmod 0600 /swap/swap01 #将权限设置为0600,否则系统会告警
mkswap /swap/swap01 #创建swap文件
swapon /swap/swap01 #启用swap文件
free -h #查看可用的内存
注:有些云虚机未开启swap文件,虚拟机内存小,开启swap后对性能提升还是有用的。
=== 清理SWAP空间 ===
swapoff -a
swapon -a
=== 清除CACHE空间 ===
sync
echo 1 > /proc/sys/vm/drop_caches
==== IO ====
=== 查看系统中谁的IO大 ===
- 关闭系统日志: service rsyslog stop
- 开启块记录: echo 1 > /proc/sys/vm/block_dump
- 检查系统IO块情况: dmesg | egrep "READ|WRITE|dirtied",会出现诸如以下日志:postmaster(13648): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13649): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13650): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13651): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13652): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13653): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13654): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13655): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13656): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
postmaster(13657): WRITE block 108389744 on unknown-block(253,2) (16 sectors)
进行统计之后就知道哪个程序写得比较多了。
统计命令: dmesg | egrep "READ|WRITE|dirtied" | awk -F: '{print $1}'|sort|uniq -c|sort -rn|head -n 10
- 完成后关闭块记录: echo 0 > /proc/sys/vm/block_dump 并打开系统日志: service rsyslog start
=== 磁盘性能测试 ===
dd if=/dev/zero of=~/disk-test count=4k bs=64k conv=fdatasync #使用写缓存,最后落盘
df if=/dev/zero of=~/disk-test count=4k bs=64k oflag=dsync #写每一块都落盘,不使用写缓存,相当于严格测试,测出来速度也非常低
=== 关于磁盘空间占用问题 ===
df -h #查看整体空间占用
du -h --max-depth=1 #查看占用较大的文件
df -h /tmp #查看特定目录。特别的,此命令还可查看特定目录使用的挂载点,比如/tmp目录,有可能使用了/目录的挂载位置,占用了根目录的空间。
df -i #查看Inode使用情况,如果Inode占用满了,也可能导致系统出现异常。
特别地,如果挂载点丢失,文件会被写入到挂载点对应的目录里面,占用根文件系统空间。
==== 时钟 ====
# 实时时钟RTC
cat /sys/class/rtc/rtc0/date #日期
cat /sys/class/rtc/rtc0/time #时间
cat /proc/driver/rtc #RTC相关信息
==== 文件管理 ====
# 查找文件
查找一天内、一天前修改|创建的文件
find ./ -mtime -1
find ./ -mtime +1
find ./ -name xxx 查找文件名包含xxx的文件
find ./ -mtime -1 -exec cp -rpf {} ./newf/ \; 查找文件并复制到newf目录下
watch -n3 "find ./ -mtime -1 | wc" 每三秒种执行一次find命令,并统计文件数目
===== CentOS,YUM包管理系统 =====
## 查找释放特定文件的包:
yum provides "*/filename"
## 查找特定软件包释放的文件
rpm -ql pkg_name
## 查找软件包
yum search pkg_name
## 查看是否安装软件包
rpm -qa | grep pkg_name
===== 网络 =====
==== SSH ====
=== SSH 清除指定主机SSH公钥凭据 ===
ssh-keygen -R 1.1.6.3
=== 使用配置文件登录SSH ===
echo StrictHostKeyChecking no > ssh.conf #自动保存公钥到 KnownHosts
ssh -F ssh.conf root@a.b.c.d
=== SSH使用证书登录 ===
- 生成密钥对文件,默认为id_rsa, id_rsa.pub,命令行: ssh-keygen -b1024 -t rsa
- 将id_rsa.pub(公钥文件)内容追加到 ~/.ssh/authorized_keys 文件中,其中~为需要登录用户的HomeDir
- chmod u-w authorized_keys
- 服务端使用 ssh user@server_name 登录
> 可以多个服务器均使用一个密钥对登录,但不建议。b)如果使用的私钥文件不是id_rsa,需要手动指定,命令为: ssh -i file.key user@server_name
=== 清除Key文件密码 ===
ssh-keygen -p 并输入旧密码,新密码留空
==== 其他网络相关 ====
# Socat - Socket CAT, Socket双向数据连接
基础用法: socat [opt] # 在指定的两个数据通道上建立连接
基础原理为:
a) 先启动第一个连接,成功后再启动第二个连接。
b) 两个连接均启动成功后,如果有数据则进行双向交换
==== 正向代理 ====
## 端口转发: 监听LocalAddr:12345端口,并将请求转发到1.1.1.1:12345上
## $ socat tcp4-listen:12345,bind=LocalAddr,reuseaddr,fork tcp:1.1.1.1:12345
选项:
bind=LocalAddr, 指定绑定的本地地址
reuseaddr, 指定地址重用(必须明确指定IP地址,才可以使用reuseaddr,主要避免端口未完全关闭导致的监听失败)
fork, 建立子程序处理链入请求,不然处理一个请求后程序就退出去了。
## $socat tcp4-listen:12345 tcp-listen:23456
先监听端口12345,如果有传入连接,再启动监听23456。
===== 常见问题 =====
1. 在编译过程中出现"config.status: error: connot find input file:..."这种错误时,使用以下命令序列生成所需文件
aclocal
libtoolize –force
automake –add-missing
autoconf
autoheader
make clean
===== 文件编辑 =====
==== vi 将dos格式文件转换为*nix格式 ====
:set ff=unix
注,dos格式文件在打开时会在底栏显示[dos]字样
==== 在线编辑程序Sed ====
直接修改文件: sed -i command filename
流式修改文件: sed cmd file
=== 常见命令 ===
- 删除包含指定内容的行: '/search_word/d'
- 将包含指定内容的行修改为新的内容: '/search/c new_word'
- 搜索指定内容,并在当前行插入一行: '/search/i inserted_word'
- 搜索指定内容,并在当前行后添加新内容: '/search/a new'
- 删除指定行号的内容: '2,5d'
- 将指定行修改为新的内容: '2,5c new'
- 在文件尾添加内容: '$a new'
- 搜索内容并将搜索到的内容替换为新的内容: 's/old/new/g' g代表全局替换
- 删除空行: %%'/^[[:space:]]*$/d'%%
- 正则替换及子匹配: %%echo "Hello,12345" | sed -e 's/Hello,\(.*\)/\1/'%%, 这个指令的意思是:搜索模式Hello,(.*),并将搜索到的模式替换成匹配的第一组子串(即用第一个括号括起的内容,本处为12345)
> 注:2)与7)的不同之处是2)是将指定行修改为新的内容,7)是只将搜索到的内容替换为新的内容
=== 大小写转换 ===
* %%echo 'Asdf' | tr [:lower:] [:upper:]%%
* %%echo 'Asdf' | tr a-z A-Z%%
* %%echo 'Asdf' | sed 's/[a-z]/\U&/g' 转大写,注使用大写的U表示转全文,小写的u转首字%%
* %%echo 'ASDF' | sed 's/[A-Z]/\L&/g' 转换小写%%
==== 关于Shell里面的正则表达式 ====
- ERE(扩展正则):
- BRE(基本正则): %%七个元字符{}()|?+需要转义才代表特殊含义,而扩展正则不需要转义就代表特殊含义,BRE没有诸如\d,\s这样的字符集,取而代之的是:[:space:]-空白字符,[:alnum:]-字母+数字,[:alpha:]-字符,[:blank:]-空白+制表符,[:lower:][:upper:]小写、大写,[:punct:]标点符号,[:digit:]-数字 %%
vi,sed,grep 使用BRE正则
awk,egrep 使用扩展正则
ref: http://www.4e00.com/blog/linux/2016/01/21/posix-bre-and-ere-regular-expression.html
===== 防火墙 ====
CentOS 7 以后防火墙
systemctl status firewalld
systemctl enable firewalld
systemctl unmask/mask firewalld #MASK了以后就无法再进行启动
systemctl start firewalld
firewall-cmd --add-port=22/tcp #允许一个端口经过防火墙,立即生效(不保存配置文件)
firewall-cmd --add-port=22/tcp --permanent #允许一个端口经过防火墙,重新装载后生效(保存配置文件)
firewall-cmd --list-* #列出防火墙运行中的规则,*可以是ports, sources, rich-rules等
firewall-cmd --zone=public --add-rich-rule="rule family='ipv4' source address='$IP' port port=22 protocol=tcp drop" #禁止一个IP地址访问特定端口,可以用drop,可以用reject
firewall-cmd --permanent --add-rich-rule='rule protocol value=icmp drop' #禁止PING
===== REDIS =====
# redis-cli 命令直接写系统文件
echo "keys 'cf_a1s2_*' " | redis-cli -h $HOST -p 6379 -a '123456' > /tmp/cf_a1_keys.txt
telnet $HOST 6379
config set dir $DIR
set shell "ABCDEFG"
config set $FILE
save
===== 杂项 =====
==== 生成UUID ====
cat /proc/sys/kernel/random/uuid
==== xargs 处理命令行参数并批量执行命令 ====
ls -tr | head -10 | xargs -I{} rm -rf {}
其中:
* ls -tr 按照文件从旧到新列出当前目录下的文件与目录名
* head -10 只取出其中10项
* xargs -I{} rm -rf {} 指定替换符,这里替换符为一个大括号,xargs将从管道收到的数据处理后依次传送给命令替换符指定的位置
==== 符号链接 ====
# 关于符号链接,第一个参数为要链接的文件或者目录,第二个参数为链接名称(经常搞反)
ln -s work_dir name
==== 一个简单的 Web Terminal, Webshell ====
[[https://github.com/tsl0922/ttyd/releases/tag/1.6.3|ttyd--一个简单的Web Shell终端]]
wget https://github.com/tsl0922/ttyd/releases/download/1.6.3/ttyd.x86_64
chmod +x ttyd.x86_64
ln -s /path/to/ttyd.x86_64 /usr/bin/ttyd
ttyd -p32768 bash #在端口32768上启用一个WebShell
注:该程序既可用于黑客等非法用途,也可自己用于合法用途,还是看自己用法吧。
注意:
* **!!!请不要在root权限下运行该程序**
* **使用NGINX之类的代理系统转发时做好认证工作** See also: [[itwiki:nginx-practice|NGINX 实践]]