====== 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 实践]]