Bash Tips(持续更新) - 开发常用Bash命令

这些命令是在开发或者运维配置过程中常用的一些命令,自己查找和记录下来不断完善!

grep,剔除不匹配

// 先通过find找md的文件,寻找不匹配的
$ find . -name '*.md' -print0 | xargs -0 grep -iL "title"

// 和上面一样,上面的命令执行效率更优
$ find . -name '*.md' | xargs -n 1 grep -iL "title"

// 直接利用grep的-L,在仅包含md文件内寻找,不含title的文件
$ grep -iL "title" -r ./* --include '*.md'

1. 磁盘观测

// 磁盘IO观测, -d -x表示显示所有磁盘I/O的指标
$ iostat -d -x 1
%util ,磁盘I/O使用率;
r/s+ w/s ,就是 IOPS;
rkB/s+wkB/s ,就是吞吐量;
r_awai、+w_await ,就是读写等待响应时间。
rareq-sz 和 wareq-sz,平均读写请求的大小

// 进程IO观测
$ pidstat -d 1
秒读取的数据大小(kB_rd/s) ,单位是 KB。
每秒发出的写请求数据大小(kB_wr/s) ,单位是 KB。
每秒取消的写请求数据大小(kB_ccwr/s) ,单位是 KB。
块 I/O 延迟(iodelay),包括等待同步块 I/O 和换入块 I/O 结束的时间,单位是时钟周期。

$ iotop

2. sar,系统活动报告

sar支持提供系统的CPU、内存、磁盘块设备、网络相关事件的报告

$ sar -h

// CPU相关活动,包括软硬中断(vmstat、top、mpstat也可以比较好的看到)
$ sar -u ALL 1

// 网卡情况
$ sar -n DEV 1
$ sar -n IP 1
$ sar -n TCP 1

3. 打包命令

  • -x:指示tar提取文件。
  • -f:指定文件名/压缩包名称。
  • -v:详细(提取文件时显示进度)。
  • -j:通过bzip2过滤存档,用于解压缩.bz2文件。
  • -z:通过gzip过滤归档文件,用于解压缩.gz文件。
  • –wildcards:指示tar将命令行参数视为glob模式。
  • –no-anchored:通知它模式在任何/分隔符之后适用于成员名称

3.1. 解压并仅提出部分文件

// 先查看文件
$tar -ztf hugo.tar.gz

// 提取指定文件,注意-f的位置
$ tar -zxvf hugo.tar.gz hugo -C ./hugo/
$ tar -zx --extract hugo -f hugo.tar.gz

// 提取符合匹配符的文件
$ tar -zxvf hugo.tar.gz *go *.md -C ./hugo/
$ tar -zxf cbz.tar.gz --wildcards --no-anchored '*.php'

利用管道传输压缩文件(压缩完,同传输给到另外一端解压)

// 本地打包,同步传至远端服务cloud_native下的/tmp/mysql.tgz
tar -zvcf - mysql/ | ssh user@cloud_native -p 2222 "cat > /tmp/mysql.tgz"

// 可以利用括号写入多条命令
tar -zcvf - . |ssh user@cloud_native -p 2222 "(cd /data/www/archstat.com; tar -zxvf - )"

// 本地打包,同步到远端服务器,解压缩到指定/tmp目录,mysql目录,会在/tmp目录生成
tar -zvcf - ./mysql/ | ssh user@cloud_native -p 2222 "tar -zxvf - -C /tmp"

// 远程ssh执行打包,复制到本地
ssh user@tkstorm_srv -p 2222 "(cd /data/www/archstat.com; tar -zcf - ./mysql/)"|tar -zxf -

4. rpm 查询软件包配置

// 前利用rpm -qa查看包名
rpm -qf postfix-2.10.1-7.el7.x86_64

// 查看配置
rpm -qc postfix-2.10.1-7.el7.x86_64

// 查看包相关文件
rpm -ql postfix-2.10.1-7.el7.x86_64

5. 进制转换

5.1. 转成10进制

// 利用printf函数,格式化输出
printf "%d\n" 0xFF

// bash
echo $((2#1111))
echo $((8#017))
echo $((16#FF))
// 或者
echo $((0x2f))
47
hexNum=2f
echo $((0x${hexNum}))
47

5.2. 转成16进制

printf '%08X\n' 15

6. find

// 查找非'*.c'的文件
find . \! -name "*.c" -print
// 查找并输出文件类型,并打印
find . -type f -exec echo {} \;
// 查找并执行删除命令
find -L /usr/ports/packages -type l -exec rm -- {} +

7. curl

curl在grep时候,无法正常得到结果

因为curl将所有内容输出到标准错误输出接口导致,解决方式:

// 将标准错误输出,转到标准输出,再grep
curl -Iv https://github.com 2>&1|grep -i '^http'
HTTP/1.1 200 OK

// 利用 --stderr 到 - ,也可以实现
curl -Iv --stderr - https://github.com|grep -i '^http'
HTTP/1.1 200 OK

7.1. proxy代理或者指定hostname解析ip请求url

// Mac
curl -x socks5://10.33.1.196:1443 https://ip.cn
// CentOS
curl —socks5 127.0.0.1:10443 https://ip.cn
// 解析到指定机器
-4, --ipv4          Resolve name to IPv4 address
-6, --ipv6          Resolve name to IPv6 address
// 调试请求,注意`\`后面不要有空格
$ curl -I -k \
    -H 'Host: tkstorm.com'  \
    -H 'cache-control: no-cache' \
    -H 'user-agent: Test-UA' \
    -H 'referer: https://haha.html' \
    'https://119.23.74.167' \
    --compressed

7.2. post请求、cookie、get参数、file参数等

// 普通post参数(content-type: application/x-www-form-urlencoded)
curl -X POST \
  'http://www.baidu.com/?value_1=a&value_2=b' \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'cookie: SID=123&FId=456' \
  -H 'keep-alive: true' \
  -H 'postman-token: b8ad2446-1148-c94d-a42f-f1a8cfcd5297' \
  -b 'SID=123&FId=456' \
  -d 'uname=cocoglp&passwd=123456’

// 附带文件(content-type: multipart/form-data; boundary=xxx)
curl -X POST \
  'http://www.baidu.com/?value_1=a&value_2=b' \
  -H 'cache-control: no-cache' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -H 'cookie: SID=123&FId=456' \
  -H 'keep-alive: true' \
  -H 'postman-token: aefb545b-6792-648f-6274-f9341ce6d86d' \
  -b 'SID=123&FId=456' \
  -F 'filea=@个人资料照片.jpg'

7.3. get请求

curl -X GET \
  'http://www.baidu.com/?value_1=a&value_2=b' \
  -H 'postman-token: 7f3cd841-c395-d518-a22d-0006db1265d7' \
  -b 'SSID=12345&FROM_ID=307'

8. wget和curl下载文件

// 自定义文件名
wget --content-disposition -c http://cn2.php.net/get/php-7.2.12.tar.gz/from/this/mirror
wget -O somefile.extension http://www.vim.org/scripts/download_script.php?src_id=9750

// -O使用远程名称,并-J强制-O从内容处置标头而不是URL获取该名称,并-L在需要时进行重定向。
-L, --location      Follow redirects (H)
-J, --remote-header-name  Use the header-provided filename (H)
-O, --remote-name   Write output to a file named as the remote file

curl -JLO http://cn2.php.net/get/php-7.2.12.tar.gz/from/this/mirror

9. xargs

x argument的意思,产生某个命令的参数的意思

// 选项与参数
-0  :如果输入的 stdin 含有特殊字符,例如 `, \, 空格键等等字符时,这个 -0 参数
      可以将他还原成一般字符。这个参数可以用于特殊状态喔!
-e  :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到
      这个字符串时,就会停止继续工作!
-p  :在运行每个命令的 argument 时,都会询问使用者的意思;
-n  :后面接数字,每次 command 命令运行时,要使用几个参数的意思。

// CentOS
-d :指定一个分隔符
-s :选择最大字符数
-I replace-str

// 加-p询问
cut -d':' -f1 /etc/passwd |head -n 3| xargs -p finger

// 加-n指定参数个数
cut -d':' -f1 /etc/passwd | xargs -p -n 5 finger

// 分隔符
echo "nameXnameXnameXname" | xargs -dX
name name name name

// 找到文件删除
find /tmp -name core -type f -print| xargs /bin/rm -f
find . -name '*.md'|xargs -n 1 ls -al

// 将要执行的内容,替换成字符变量
cat file | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}'
find . -name '*.md'|xargs -I '{}' -n 1 echo "md file >" '{}'

// 备份Chrome的插件文件
cat /tmp/export.log|xargs -n 1 -I '$f' find $chrome_home -type d -name '$f' -exec cp -a '{}' /tmp/chrome_extensions \;

10. awk

  • BEGIN{...} PATTERN{...} END{...} ,BEGIN和END部分都可以省略
  • PATTERN{...}类似一个循环体,会对文件中的每一行进行迭代, $n表示第n个字段,同时$0表示整行
  • 相关预定义变量:NF表示行字段数(num field),NR表示行记录数(num row)

10.1. BEGIN{}、PATTERN、END

$ ls resources/images/2019/survey2018-results/fig*|awk 'END{print index($0, "fig")}'
42
// 每行前置计数i
awk 'BEGIN{ i=1 } { print i,$0 ; i++; }' index.html
// 打印每行
awk '{print}' index.html
// 统计文件行数
$ awk 'END{ print NR }' index.html
30

10.2. if语句、循环等

// 正则操作,打印匹配以10开头的行
$ awk '{ if($0 ~ /10/){print $0;} }' index.html

// 指定分隔符
awk -F: '{ print $NF }' /etc/passwd
awk 'BEGIN{ FS=":" } { print $NF }' /etc/passwd

// 语句if.else;while;for...
awk 'BEGIN{
  total=0;
  for(i=0;i<=100;i++){
    total+=i;
  }
  print total;
}'

10.3. awk预定义变量字段

说明:[A][N][P][G]表示第一个支持变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk

$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。 
$0 这个变量包含执行过程中当前行的文本内容。

[A] FILENAME 当前输入文件的名。
[A] FS 字段分隔符(默认是任何空格)。
[A] NF 表示字段数,在执行过程中对应于当前的字段数。
[A] NR 表示记录数,在执行过程中对应于当前的行号。
[A] OFMT 数字的输出格式(默认值是%.6g)。
[A] OFS 输出字段分隔符(默认值是一个空格)。
[A] ORS 输出记录分隔符(默认值是一个换行符)。
[A] RS 记录分隔符(默认是一个换行符)。

[N] ARGC 命令行参数的数目。
[N] ARGV 包含命令行参数的数组。
[N] ERRNO 最后一个系统错误的描述。
[N] RLENGTH 由match函数所匹配的字符串的长度。
[N] SUBSEP 数组下标分隔符(默认值是34)。
[N] RSTART 由match函数所匹配的字符串的第一个位置。

[P] ENVIRON 环境变量关联数组。
[P] FNR 同NR,但相对于当前文件。

[G] ARGIND 命令行中当前文件的位置(从0开始算)。
[G] IGNORECASE 如果为真,则进行忽略大小写的匹配。
[G] FIELDWIDTHS 字段宽度列表(用空格键分隔)。
[G] CONVFMT 数字转换格式(默认值为%.6g)。


// 过滤掉首位行(尾行基于正则匹配识别)输出:
cat /data/www/pac.psr100.cn/proxy-default.pac |sed  -n '/var blockHostsList/,/]/p'|awk '{if (NR>1 && $0 !~ /]/) print NR ":" $0}'

10.4. gsub, substr, sprintf等函数使用

// 字符串函数,比如substr、match、split、tolower等
// gsub, 在info中查找满足正则表达式,将数字替换`!`,并赋值给info
awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}'
// substr
awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'
// sprintf
awk 'BEGIN{n1=124.113;n2=-1.224;n3=1.2345; printf("%.2f,%.2u,%.2g,%X,%on",n1,n2,n3,n1,n1);}'

// 从匹配<tr><td></td>的行起,在期内替换成数字i
$ cat index.html |awk 'BEGIN{i=0} {if (match($0, "<tr><td></td>")){i++;} gsub("<tr><td></td>", "<tr><td>"i"</td>", $0); print $0 }'

// 补齐表格内容
ls |sort -n -k 1.4|awk 'BEGIN{i=0; print "<table>\n<tr><td>ID</td><td>课程PPT</td></tr>"} {i++;if(NR>1){ line=sprintf("<tr><td>%d</td><td><a href=\"./%s\">%s</a></td></tr>", i, $0, $0); print line}} END{ print "</table>"}'

// awk函数使用
$ ls |sort -n -k 1.4|awk '{new=sprintf("%s %s%s%s%s", $1,$2,$3,$4,$5); gsub(/\s+$/,"",new); exec=sprintf("mv -i \"%s\" \"%s\" ", $0, new); system(exec)}'

11. sort排序

// 开始排序的位置
echo "resources/images/2019/survey2018-results/fig"|wc -c
45

// 从第1列,45位置处开始排序, -n表示按number排序
// `1.n` refers to the nth character from the beginning of the line; 
// if n is greater than the length of the line, the field is taken to be empty.

/data/www/tkstorm.com # ls resources/images/2019/survey2018-results/fig*|sort -k 1.45 -n
resources/images/2019/survey2018-results/fig1.svg
resources/images/2019/survey2018-results/fig2.svg
...

$ ls|sort -k 1.4 -n
lec1-课程概述-v1.pptx
lec2-实验零 操作系统实验环境准备-chy4.pptx
lec3-启动中断异常系统调用-chy1.pptx
lec4-lab1-chy1.pptx
lec5-第五讲 物理内存管理  连续内存分配-chy1.pptx
lec6-第六讲 物理内存管理  非连续内存分配-1.pptx
lec7-第七讲 实验二 物理内存管理.pptx
....

12. 生成随机字符串1

// 取10个字符
head -c10 /dev/urandom|base64

// ascii随机字符
$ head -c 1000 /dev/urandom|LC_ALL=C tr -dc 'a-zA-Z0-9@_'|fold -w 50|head -n 1

// base64字符集中随机字符
$ cat /dev/urandom |base64 |head -c 50

// 基于dd方式
dd if=/dev/urandom bs=512 count=1|LC_ALL=C tr -dc 'a-zA-Z0-9' |fold -w 50|head -n 1|cat
dd if=/dev/urandom of=- bs=512 count=1|LC_ALL=C tr -dc 'a-zA-Z0-9' < -|fold -w 50|head -n 1|cat

13. sed - 删除字符串最后一个字符

// 利用sed
echo 38252,38261,38269,|sed 's/,$//g'

// 变量截取
$ x=38252,38261,38269,; echo $x; echo ${x/%?/}
38252,38261,38269,
38252,38261,38269

// 以行为单位的新增(a|i)/删除功能(d)
nl /etc/passwd | sed '2,5d'
nl /etc/passwd | sed '2a drink tea' //第2行后加字符
nl /etc/passwd | sed '2i drink tea' //第2行之前加字符

// 以行为单位的替换(c)与显示功能(p)
nl /etc/passwd | sed '2,5c No 2-5 number' //将2到5行,替换成指定字符
nl /etc/passwd | sed -n '5,7p'  // 打印5到7行,(-n)表示安静模式,仅5到7行内容

// 搜索&替换
sed 's/要被取代的字串/新的字串/g'
sed 's/^.*addr://g' | sed 's/Bcast.*$//g'

// 将匹配的空白行删除
sed '/^$/d'

// 直接修改(i),Tips: 注意会直接写原文件
sed -i 's/\.$/\!/g' regular_express.txt   //每一行结尾若为.则换成 !
sed -i '$a # This is a test' regular_express.txt //最后一行加入『# This is a test』

14. uuid生成

参考:https://serverfault.com/questions/103359/how-to-create-a-uuid-in-bash?rq=1

// 基于库函数生成
uuidgen

// 基于urandom方式生成
od -x /dev/urandom | head -1 | awk '{OFS="-"; srand($6); sub(/./,"4",$5); sub(/./,substr("89ab",rand()*4,1),$6); print $2$3,$4,$5,$6,$7$8$9}'
$ od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'|tr '[a-z]' '[A-Z]'
$ od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'|LC_ALL=C tr '[a-z]' '[A-Z]'

15. dns查询

// dns跟踪
dig +trace +nodnssec www.tkstorm.com
dig +short www.tkstorm.com

// dns调试
nslookup -debug tkstorm.com

// 解析耗时
time nslookup qq.com

16. mtr - 网络丢包分析 2

mtr(My traceroute)几乎是所有Linux发行版本预装的网络测试工具。其将ping和traceroute的功能合并,所以功能更强大。

mtr默认发送ICMP数据包进行链路探测。您也可以通过“-u”参数来指定使用UDP数据包进行探测。

相对于traceroute只会做一次链路跟踪测试,mtr会对链路上的相关节点做持续探测并给出相应的统计信息。

所以,mtr能避免节点波动对测试结果的影响,所以其测试结果更正确,建议优先使用。

yum install mtr
mtr tkstorm.com

17. lsof - 查看进程端口

支持基于端口快速查找进程方式:lsofnetstat

// MAC环境
lsof -i tcp:3000 
lsof -ti:3000

// -n 不解析主机名 -P 不解析端口名 
// -i 指定(indicate)IP版本,传输协议,端口列表等,注意顺序!! 
//    -i i select by IPv[46] address: [46][proto][@host|addr][:svc_list|port_list]
lsof -nP -i 4TCP

// COMMAND     PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
$ lsof -nP -i 4TCP |grep 8080

// Linux环境
netstat -ntap|grep 8000

18. perf - 动态追踪工具

perf top

perf record -g

perf report

19. strace - 进程执行跟踪

命令说明:

  • -tt: 精确到毫秒
  • -T: 显示系统调用时间:Show the time spent in system calls.
  • -c: 统计信息,统计过程不会打印相关输出明细(可以通过-C优化)
  • -C: 持续统计信息,类似-c,调用时间、次数、错误等信息,打印规则输出;
  • -v: 不缩写打印结构体相关成员内容
  • -s: 指定最大字符串打印长度(默认是32,这个当数据太少,不好判断的时候可以调大)
  • -e expr: 告知strace跟踪哪些事件,以及如何跟踪这些事件,如
  • -e trace=open,close,read,write 跟踪指定的IO系统调用
  • -e trace=file 文件操作相关,比如open,stat,chmod,unlink,….
  • -e trace=process 进程相关
  • -e trace=network 网络相关
  • -e trace=signal 信号相关
  • -e trace=ipc 所有IPC进程通信相关
  • -e trace=desc 文件描述符操作相关
  • -e trace=memory 内存操作相关
  • -e abbrev=all|none|sets 默认是缩写所有大的结构体成员,通过-v可以释放掉该效果,或者设置为none,或者指定成员
  • -e verbose=all|none|sets 详细化打印结构体成员
  • -e raw=set 使用未经过编码的参数打印系统调用参数
  • -e signal=all|set 打印指定信号
  • -e read=set 打印读取指定文件描述符的数据内容
  • -e write=set 打印写入指定文件描述符的数据内容
  • -o file: 打印输出记录到文件,而非标准错误输出
  • -p pid1,pid2…: 跟踪指定进程号进程
  • -f : 跟踪进程的子进程(通过fork\vfork\clone生成的)
  • -ff: 和-o filename配合,生成filename.pid按进程号区分的文件
// 短小快速分析
strace -tt -p 6,7

// 希望看到系统调用时间,加上`-T`
strace -ttT -p 6,7

// 希望看到更明细的参数信息`-s 1024`
strace -ttT -s 1024 -p 6,7

// 【足够详细】希望看到相关结构体成员信息`-v`
strace -ttTv -s 1024 -p 6,7

// 仅关系网络|进程|内存相关
strace -ttTvf -e trace=network -p 6,7
strace -ttTvf -e trace=process -p 6,7
strace -ttTvf -e trace=memory -p 6,7

// 希望加`-C`统计分析
strace -ttTCv -s 1024 -e trace=all -p 59432

strace -ttTCv -s 1024 -e trace=all -p 59432 -o /tmp/bench-all-1.log

strace -ttTCv -s 1024 -e trace=network,procss,desc -p  -o /tmp/bench-net-proc-desc-1.log

strace -ttTfC -s 1024 -p "281590 279290 279157 279068 278854 278353" -o /tmp/bench-1106.log

strace -ttTfC -e trace=all -s 1024 -p "37912 37911 37910 37909 37908" -o /tmp/bench-1107.log

strace -ttTfC -e trace=all -s 1024 -p "`pidof php-fpm|awk '{print $1}'`" -o /tmp/bench-1108-01.log

// 调试nc进程(C/S模式),经典的Unix网络套接字编程中的内容可见!
strace -vCTtt nc -vl 1234 //服务端端
strace -vCTtt nc localhost 1234 //客户端

20. manpage缺失问题

在Docker中,可能我们想安装Man,但发现安装不了的情况,可以检查下包管理工具安装属性(为了镜像大小将man文件选择不安装):

// 注释掉nodocs:
sed -i 's/tsflags=nodocs/# &/' /etc/yum.conf

// 重新安装需要man的包
yum reinstall shadow-utils

// 或者直接执行
yum --setopt=tsflags='' reinstall shadow-utils

21. nc命令

  1. 有时候服务器没有telnet,我们可以通过nc工具替代;
  2. 有时候用于测试TCP的C/S模式也可以采用nc替换:nc -l -p 1234nc localhost 1234
  3. 数据传输+shasum校验(linux传完会自动断开),当然如果由scprsync等工具另做别论
  4. 正向代理

Tips: Linux下的nc和Mac下的nc命令有一定差异,比如:nc -lv 1024(linux下)表示在1024端口下监听,而在Mac下,需要通过-p指定监听端口

21.1. nc - 端口扫描

  • -v 明细
  • -z Zero-I/O mode (scanning)
  • -w second 超时设置
// 检测9000端口是否打开
nc -zv localhost 9000

// 批量扫描端口(比较耗时)
$ nc -zv 10.40.2.181 1-65535
static.io [10.40.2.181] 22 (ssh) open
static.io [10.40.2.181] 80 (http) open
...

21.2. nc - 数据传输

以下内容利用nc将Mac端的数据传输给到Linux端

// 1. Mac端(客户端)计算待发送的数据shasum值
$ shasum go1.13.3.src.tar.gz
1fdfd1586888d4d24f5dadee6016092f89e6049e  go1.13.3.src.tar.gz

// 2. Linux(服务端)充当数据接收方,接收到的数据存储到指定位置(Tips: CentOS下的nc没有指定`-p`参数)
nc -vl 1024 > /tmp/go1.13.3.src.tar.gz

// 3. Mac端(客户端):数据发送方,将文件加入的nc网络输入流中
nc -v 10.40.2.181 1024 < go1.13.3.src.tar.gz

// 4. Linux端(服务端),当数据传输完后,利用sha1sum计算数据的完整性(Tips: Linux上使用的sha1sum、md5sum均可以用于数据一致性校验, Mac下采用shasum和md5命令计算)
$ md5 go1.13.3.src.tar.gz 
MD5 (go1.13.3.src.tar.gz) = 94ae8bf6a4fe623e34cb8b0db2a71ec0
$ shasum go1.13.3.src.tar.gz
1fdfd1586888d4d24f5dadee6016092f89e6049e  go1.13.3.src.tar.gz

[root@test_10 tmp]# md5sum go1.13.3.src.tar.gz
94ae8bf6a4fe623e34cb8b0db2a71ec0  go1.13.3.src.tar.gz
[root@test_10 tmp]# sha1sum go1.13.3.src.tar.gz
1fdfd1586888d4d24f5dadee6016092f89e6049e  go1.13.3.src.tar.gz

21.3. nc - 目录拷贝

如果传递的是目录,可以先对数据内容进行打包压缩,输出到nc网络连接上:

// 接收端
nc -l -p 1234|uncompress -c|tar xvfp -
// 发送端
tar cfp - /some/dir|compress -c |nc -w 3 10.40.2.181 1234

21.4. nc - HTTP请求

  1. 注意echo需要开启反斜杠转移,即-e,注意HTTP1.0在每次HTTP请求后都会关闭连接,但HTTP1.1不会
  2. 另外在HTTP1.1类似管道发送多个HTTP请求时候,HTTP是基于TCP上面的,不能随意发送多余的字符,否则引起HTTP协议解析失败产生400客户端错误!
printf "GET / HTTP/1.0\r\n\r\n"|nc host.example.com 80

// echo 
echo -e "HEAD / HTTP/1.0\r\n\r\n"|nc localhost 80
echo -e 'HEAD / HTTP/1.1\r\nHost:localhost\r\n\r\nHEAD /xx.html HTTP/1.0\r\n'|nc localhost 80
echo -e 'HEAD / HTTP/1.0\r\nHost:localhost\r\n\r\nHEAD /xx.html HTTP/1.0\r\n'|nc localhost 80

22. rsync和sync - 同步数据

// rsync方式同步
rsync -avz -e "ssh -p 2222" ./* username@archstat.com:/tmp

// scp方式同步
scp -r -P 2222 ./* username@archstat.com:/tmp

23. 命令行tty相关快捷键

eof : End of file 的意思,代表『结束输入』。 erase : 向后删除字符, intr : 送出一个 interrupt (中断) 的讯号给目前正在 run 的程序; kill : 删除在目前命令列上的所有文字; quit : 送出一个 quit 的讯号给目前正在 run 的程序; start : 在某个程序停止后,重新启动他的 output stop : 停止目前屏幕的输出; susp : 送出一个 terminal stop 的讯号给正在 run 的程序。

(tips:是否有过把ctrl+S后,发现命令行无法输出的情况? 实际是停止了屏幕的输出,可以通过ctrl+Q恢复)

[root@www ~]# stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; 
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
...

24. set - 设置bash调试相关信息

// 调试相关,可以显示更多的信息
-u  :默认不激活。若激活后,当使用未配置变量时,会显示错误信息;
-v  :默认不激活。若激活后,在信息被输出前,会先显示信息的原始内容(未做变量解析);
-x  :默认不激活。若激活后,在命令被运行前,会显示命令内容(做了变量解析,前面有 ++ 符号)

// 当前的终端配置
echo $-

//  -v后,会显示执行的命令,但未做变量解析
/ # set -v && echo $HOME
/root
/ # set +v && echo $HOME
set +v && echo $HOME
/root

// set -x后,会显示解析的命令
/ # set -x && echo $HOME
+ echo /root
/root
/ # set +x && echo $HOME
+ set +x
/root

// set -u后,会有相关的提示信息
/ # set -u && echo $NOSET
/bin/sh: NOSET: parameter not set
/ # set +u && echo $NOSET

25. du - 忽略文件的统计

// centos下的du
du -sh --exclude=./relative/path/to/uploads
du -ch --exclude={relative/path/to/uploads,other/path/to/exclude}
du -ch --exclude=relative/path/to/uploads --exclude other/path/to/exclude

// mac下,安装coreutils,然后利用
brew install coreutils
gdu -sh --exclude=./app/node_modules

26. pgrep,pkill - 基于进程名称查找、杀死进程

默认情况,可以通过grep+awk得到pid,然后kill

sleep 100 &

// 查看指定名称进程相关信息,确定是否自己需要杀死的,以下几个都类似
ps -fp $(pgrep -d, sleep)
ps -jp $(pgrep -d, sleep)
ps -jlp $(pgrep -d, zsh)

// 杀死指定名称相关进程信息
$ pkill sleep
$ ps -fp $(pgrep -d, sleep)
[1]  + 38024 terminated  sleep 100

27. openssl认证3

// 检测ioio.cool的TLS链接
openssl s_client -connect ioio.cool:443
// 检测证书内容
openssl x509 -text
...

28. locale、localectl - 本地化语言设置

28.1. localectl命令操作

localeglibc 和其它需要本地化的应用程序和库用来解析文本(或正确的显示当前区域的某些文字样式,如货币,时间,日期,特殊字符和其他的区域格式).

// 列出所有启用的locale
$ locale -a
// 显示当前环境使用的locale
$ locale 

// 系统配置所在,格式:[language][_TERRITORY][.CODESET][@modifier].
$ cat /etc/locale.conf
LANG="en_US.UTF-8"
// 另外,注意profile.d下的配置
$ ls /etc/profile.d/locale.sh

// 配置设定本地化和键盘布局
localectl status
localectl list-locales
localectl set-locale LANG=en_US.utf8

// 配置键盘布局,更多查看`man localectl`
localectl list-keymaps
localectl set-keymap MAP [TOGGLEMAP]

28.2. export导出语言配置

// 方法1,设定当前语言环境变量
$ export LANG="en_US.utf8"

// 方法2
$ LANG="en_US.utf8" ./my_application.sh

29. 磁盘分区+性能测试

29.1. 磁盘分区4

分区分为主分区扩展分区,主分区+扩展分区不能超过4个,另外扩展分区可以扩展多个逻辑分区,分区总数量不能超过255

存储大小=柱面数 x 扇区大小

// 查看
fdisk -l

// 磁盘分区(m是帮助信息,n创建新分区、p查看分区情况、w分区设置生效、-u以柱面数据展示,默认以扇区展示)
fdisk -u /dev/vdb
p //打印当前分区表
n //创建扇区
p|e|l //主分区|扩展分区|逻辑分区
w //保存分区表(注意先利用p查看)

// 输入起始柱面,终止柱面(支持大小指定)
命令(输入 m 获取帮助):n
Partition type:
   p   primary (1 primary, 1 extended, 2 free)
   l   logical (numbered from 5)
Select (default p): l
添加逻辑分区 6
起始 柱面 (52021-83220,默认为 52021):
将使用默认值 52021
Last 柱面, +柱面 or +size{K,M,G} (52021-83220,默认为 83220):+10G
分区 6 已设置为 Linux 类型,大小设为 10 GiB

29.2. 磁盘文件格式化

mkfs -t ext4 /dev/vdb1
mkfs.ext4 /dev/vdb5
mkfs.xfs /dev/vdb6

29.3. 挂载到指定目录(需要先创建目录)

// 设备标识|挂载点|文件类型|mount挂载方式|文件系统是否支持dump|启动是否做磁盘检测
UUID=87ba1103-a0d7-49ef-a8ae-6ce1d3fd2453 /                       ext4    defaults        1 1
/dev/vdb1   /data     ext4  defaults 0 0
/dev/vdb5   /data/www   ext4  defaults 0 0
/dev/vdb6   /data/go  xfs defaults 0 0

29.4. 查看挂载点和文件类型方式

[root@acp-test-001 ~]# lsblk -p   // 查看挂载点和文件类型以及大小

// df查看
[root@acp-test-001 ~]# df -T
文件系统       类型        1K-块    已用     可用 已用% 挂载点
....
/dev/vdb1      ext4     10190100   36896  9612532    1% /data
/dev/vdb5      ext4     15350248   40984 14506452    1% /data/www
/dev/vdb6      xfs      15714144   32992 15681152    1% /data/go

// 利用mount命令查看
[root@acp-test-001 ~]# mount|grep '^/dev'

// 类型查看
[root@acp-test-001 ~]# fsck -N /dev/vdb1
fsck,来自 util-linux 2.23.2
[/sbin/fsck.ext4 (1) -- /data] fsck.ext4 /dev/vdb1

// 利用块ID查看
[root@acp-test-001 ~]# blkid /dev/vdb5
/dev/vdb5: UUID="bbbc2933-4d33-4490-8c03-25d847fe23a2" TYPE="ext4"

// 利用File命令查看
[root@acp-test-001 ~]# file -sL /dev/vdb6
/dev/vdb6: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)

// 查看配置
cat /etc/fstab

30. fio 磁盘性能测试5

  • -direct=1 表示测试时忽略I/O缓存,数据直写。
  • -iodepth=128 表示使用AIO时,同时发出I/O数的上限为128。
  • -rw=randwrite 表示测试时的读写策略为随机写(random writes)。其它测试可以设置为:
    • randread(随机读random reads)
    • read(顺序读sequential reads)
    • write(顺序写sequential writes)
    • randrw(混合随机读写mixed random reads and writes)
  • -ioengine=libaio 表示测试方式为libaio(Linux AIO,异步I/O)。应用程序使用I/O通常有两种方式:
    • 同步:同步的I/O一次只能发出一个I/O请求,等待内核完成才返回。这样对于单个线程iodepth总是小于1,但是可以透过多个线程并发执行来解决。通常会用16−32根线程同时工作将iodepth塞满。
    • 异步:异步的I/O通常使用libaio这样的方式一次提交一批I/O请求,然后等待一批的完成,减少交互的次数,会更有效率。
  • -bs=4k 表示单次I/O的块文件大小为4KB。默认大小也是4KB。
    • 测试IOPS时,建议将bs设置为一个较小的值,如4k。
    • 测试吞吐量时,建议将bs设置为一个较大的值,如1024k。
  • -size=1G 表示测试文件大小为1GiB。
  • -numjobs=1 表示测试线程数为1。
  • -runtime=1000 表示测试时间为1000秒。如果未配置,则持续将前述-size指定大小的文件,以每次-bs值为分块大小写完。
  • -group_reporting 表示测试结果里汇总每个进程的统计信息,而非以不同job汇总展示信息。
  • -filename=iotest 指定测试文件的名称,例如iotest。
  • -name=Rand_Write_Testing 表示测试任务名称为Rand_Write_Testing,可以随意设定。
// 随机读写IOPS测试(小块操作)
fio -direct=1 -iodepth=128 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Write_Testing
fio -direct=1 -iodepth=128 -rw=randread  -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
// 顺序读写吞吐量测试(大块读写)
fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=1024k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Write_PPS_Testing
fio -direct=1 -iodepth=64 -rw=read  -ioengine=libaio -bs=1024k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Read_PPS_Testing
// 随机读写延时测试
fio -direct=1 -iodepth=1 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -group_reporting -filename=iotest -name=Rand_Write_Latency_Testing
fio -direct=1 -iodepth=1 -rw=randread  -ioengine=libaio -bs=4k -size=1G -numjobs=1 -group_reporting -filename=iotest -name=Rand_Read_Latency_Testingrandwrite

31. sshd

31.1. ssh配置相关

客户端ssh连接参数配置,另外,我们也可以通过$ ssh -o StrictHostKeyChecking=no root@acp-test-02 方式指定。

$ cat ~/.ssh/config
Host *
    ServerAliveInterval 120
    ServerAliveCountMax 3
Host github.com
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_rsa_github

31.2. ssh利用跳板机连接

// 利用代理ServerA,连接ServerB,参考:https://wiki.gentoo.org/wiki/SSH_jump_host
ssh -J user01@ServerA:portA user02@ServerB -p portB -v

32. PS1提示符设定6

32.1. 新建 /etc/profile.d/ps1.sh

  • \u: Display the current username .
  • \h: Display the hostname
  • \W: Print the base of current working directory.
  • \$: Display # (indicates root user) if the effective UID is 0, otherwise display a $.
export PS1='\n\
[\[\e[32m\]\u\[\e[0m\]\
@\
\[\e[35m\]\h \
\[\e[36;1m\]\w\
\[\e[0m\]] \
$(RETVAL="$?"; echo -en "\e[33m{$(date +'%H:%M:%S')} ";
  if [ "$RETVAL" -eq 0 ];then
                echo -en "\[\e[32m\]($RETVAL)"
        else
                echo -en "\[\e[31;1m\a\]($RETVAL)"
  fi)\n\
\[\e[0;1;34m\]\$ \[\e[0m\]'

32.2. 个性化登陆Ascii Art提示7

/etc/motd进行个性化设置:

----------------------------------------------------
      _             _         _        _
     / \   _ __ ___| |__  ___| |_ __ _| |_
    / _ \ | '__/ __| '_ \/ __| __/ _` | __|
   / ___ \| | | (__| | | \__ \ || (_| | |_
  /_/   \_\_|  \___|_| |_|___/\__\__,_|\__|

 Welcome to Alibaba Cloud Elastic Compute Service !
----------------------------------------------------

  1. https://serverfault.com/questions/283294/how-to-read-in-n-random-characters-from-dev-urandom ↩︎

  2. https://help.aliyun.com/knowledge_detail/40573.html ↩︎

  3. https://github.com/tkstorm/ss-cert ↩︎

  4. https://help.aliyun.com/document_detail/116650.html?spm=a2c4g.11186623.6.780.388a10355t54J0 ↩︎

  5. https://help.aliyun.com/document_detail/25382.html?spm=a2c4g.11186623.2.20.22a3341fRlgVDH ↩︎

  6. https://www.cyberciti.biz/faq/bash-shell-change-the-color-of-my-shell-prompt-under-linux-or-unix/ ↩︎

  7. http://www.network-science.de/ascii/ ↩︎