Jason Pan

Shell脚本中的经验

黄杰 / 2020-08-05


本文先介绍常用的 Linux 工具包,第二部分介绍我个人在平常使用Linux时,用到的一些指令和技巧,其中不包括特别基础的,大多为“用了可以省时省力,不使用也能有别的方法绕过”的技巧。

文中的指令,大部分在 Linux 和 MacOS 上都可用,少部分在 Mac OS 上可能不兼容。

一、常用工具包介绍

1.1 Bash 内置指令

Bash (Bourne-Again SHell) 是一个满足 POSIX 规范的 shell。查看手册可以看到 Bash 完整的介绍:man bash

常用的 Bash 内建指令包括:

这里提一下为什么说有些指令 Mac OS 上不兼容。因为 MacOS 上的预设 Shell 是 Zsh,而不是 Bash。

可以通过 echo $SHELL 来查看用户登入之后,默认使用的 shell 程序。

1.2 Core Utilities

GNU 发布的核心工具箱,包含的指令列表详见 coreutils wiki 以及官网介绍,可以使用 yum 直接安装:yum install coreutils

平时操作的大部分 shell 命令行,都来自于这个工具箱。这里简单罗列一下其中包含的命令:

1.3 util-linux

util-linux 是 Linux 内核组织发布的一套工具,完整的命令字列表可以参考 Util-linux#Included。我们日常用到这个工具箱中的命令字有:cal, fdisk, ipcs, kill, last, more, mount, dmesg, umount 等。

1.4 procps-ng/procps

系统和进程监控工具箱,主要是将 /proc 伪文件系统下的信息,进行可视化的展示或者设置。完整指令列表详见 procps wiki

ng 表示下一代,可能是之前的工具没人维护了,然后新拉分支就加个 ng,之前 util-linux 也有 ng,最后又合并回了 util-linux。

这里列举该工具箱中的指令:free, kill, pgrep, pkill, pmap, ps, pwdx, skill, slabtop, snice, sysctl, tload, top, uptime, vmstat, w, watch 等。

1.5 binutils

GNU 维护的二进制文件工具箱。包括

1.6 moreutils

类似于 core utilities,该库提供了一些比较基础的命令,比如可以查询错误码的 errno,可以并发执行任务的 parallel,可以只利用一个文件进行处理的 sponge,使用逻辑符比较和处理文本的combine

其他的指令还有:chronic, ifdata, ifne, isutf8, lckdo, mispipe, pee, sponge, ts, vidir, vipe, zrun

详细说明可以参考官网介绍和具体的使用示例

1.7 网络相关

net-tools 是常用的网络工具箱,包括:ifconfig, hostname, route, nameif, iwconfig, iptunnel, netstat, arp 等指令。

目前,功能更全面的 ip 指令被用来替换上述多个指令,前者来自于 iproute2utilip 指令表示上述指令的参数可以参考 iproute2 wiki

tcpdump 用于网络抓包,而 tshark 是 Wireshark 的命令行工具,用于分析包。

1.8 Glibc - ldd

Glibc 不是工具库,而是 GNU/Linux 系统的核心 API 库,比如 open, read, write, malloc, printf, getaddrinfo, dlopen, pthread_create, crypt, login, exit 等基础功能函数。同时,Glibc 提供了一个 ldd 的命令,用于打印动态库的依赖,也可以使用 ldd -v 来查看 Glibc 的版本。

1.9 包管理工具

通过一些包管理软件,我们就能方便的安装上一些我们常用的工具。

不同发行版本相关的:yum, apt, dnf, pkg, brew, rpm

不同语言相关的:pip, npm, go

在 CentOS 上,我们可以通过 rpm -qf $(which cat) 的方式,已经安装的工具属于哪个 .rpm 包。当我们迁移到不同环境的时候,可以安装对应的包以便使用该命令。

1.10 图片/视频库

我在协助客户端同学排查问题的过程中,也用到了一些图片视频相关工具箱。

ImageMagick:该工具箱提供方便的进行图片和视频的信息获得、转换、比较指令,我主要用到 convert 命令,其他指令详见命令行说明

FFmpeg:该工具箱用来提供视频的格式转换、截取等功能。

1.11 学会看手册

郭德纲相声里说:床头放着本,旁边放着本字典,再旁边放着本怎样查字典。如果要使用一个工具,得查它的手册,还得知道怎样查手册

通过 man man 可以了解如何查手册,首先我们得知道,手册有 1-9 分类:

man 1 sleep  # 1 可执行文件或shell命令
man brk      # 2 系统调用,类似的 `man epoll_create`
man 3 sleep  # 3 库函数,类似的 `man malloc`
man null     # 4 特殊文件,此处介绍 `/dev/null` 作用
man proc     # 5 系统文件格式和规范,此处介绍 /proc 进程信息伪文件系统
man inotify  # 7 杂项,此处的inotify的用法描述,类似的 `man epoll`
man netstat  # 8 系统管理指令
             # 6 和 9 我个人没用到过

二、Shell 是什么

前边发了一篇《Linux 常用工具包介绍》,不过不少同学对 shell, Bash, Zsh, iTerm2, Oh-My-Zsh 还略有混淆,今天短文一篇,来说明白这几个东西到底是什么。

2.1 概念

APUE 第一页上有下边的图,介绍说 shell 是特殊的应用程序,为运行其他程序提供了接口:

what-is-shell

POSIX 有一小节《Shell Introduction》对 shell 的功能进行了简单的定义,shell 是一个命令语言解释器,基本操作包括:

2.2 实现

shell 是个概念,或者说是功能的规范。而我们实际用的时候,必然会选择一种实现这些功能的一个应用程序。

你系统中可以用的 shell 程序,可以通过 cat /etc/shells 来查看。我们常用的就是 Bash 和 Zsh。

无论是通过 ssh 远程登录,还是本地打开一个终端窗口,都会以交互模式(-i)拉起一个 shell 进程,他会接收我们的输入,然后将结果打到标准输出或标准错误。

2.3 远程 shell

以我们远程登录到 dev-cloud 的机器为例,我们可以看看这个 bash 进程是如何启动的。ssh 到机器之后,执行指令:

pstree -asp `echo $$`

会有如下的结果产生:<!–

systemd,1 --switched-root --system --deserialize 22
  └─sshd,1449 -D
      └─sshd,12166
          └─bash,12168
              └─pstree,1635 -asp 12168

–>

remote-bash-pstree

稍做简单解释:

$$ 是 shell 的 PID,pstree 可以查看父子进程的关系。

2.4 本地 shell

以我们在 MacBook 上打开一个 iTerm 窗口为例,类似地使用 pstree -asp `echo $$` ,可以得到如下结果:

local-bash-pstree

这里也简单解释:

2.5 嵌套调用

前边说 shell 也是一个应用程序,而 shell 可以运行可执行文件,所以在一种 shell 中可以调用另外一种 shell:

nested-shell-pstree

2.6 配置

Bash 的配置文件在用户目录下,是 $HOME/.bashrc,通常会通过判断全局的配置文件是否存在,先加载,然后再有用户自己定义的一些配置。类似的,Zsh 的配置文件叫做 $HOME/.zshrc

我个人用了 GitHub 上一个 .bashrc,其本身包括加载基础配置、颜色配置、环境变量设置、命令字 alias、封装了一些方便的函数(比如extracttrim 等)。

我自己也修改其中一些配置,比如,为了保存更多的操作历史,修改了两个变量:

# Expand the history size
export HISTFILESIZE=100000000
export HISTSIZE=5000000

当然,有些方便的配置则会带来一些麻烦:

# Alias's to modified commands
alias cp='cp -i'

因为 cp 变成了带交互模式,当使用 cp 进行拷贝并且可能发生覆盖的时候,就会填出提示 cp: overwrite ‘dd/a.out’?,如果不想发生交互,可以通过 which cd 来找到真正的 cd,然后直接调用 /usr/bin/cp 来去掉交互模式。

2.7 iTerm2、Zsh、Oh My Zsh

使用 MacBook 的同学入手电脑之后,都会提到安装 iTerm2 和 Oh My Zsh。经过上边的介绍,基本上就很容易理解这三个名词了。

Zsh 是一种 shell 实现,Oh My Zsh 是对应 .bashrc 的配置。

iTerm2 是替换 Mac 自带终端,能够更好地让用户跟 Bash 交互以及额外的功能。比如常用的:

三、脚本中常用技巧

3.1 判断操作系统

$OSTYPE可以用于脚本中的判断操作系统

if [[ "$OSTYPE" == "linux-gnu" ]]; then
        # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
        # POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
        # Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
        # I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
        # ...
else
        # Unknown.
fi

3.2 在管道之间添加注释

我们通常会用管道符号连接若干命令,当一行命令太长之后,可读性就会变差。我们写在脚本中,可以利用 `# 注释` 的方式,可以使代码更具有可读性。

以下例子仅用于说明注释,有可以优化的地方,比如可以使用 netstat -alnput 替换第一个管道。

netstat -lanp                `# `                          | \
grep -P '(tcp|udp)'          `# ignore unix domain socket` | \
grep -v LISTEN               `# ignore LISTEN port`        | \
awk '{print $5}'             `# print down stream IP`      | \
grep -v "::1"                `# ignore ipv6 localhost`     | \
grep -v "127.0.0.1"          `# ignore ipv4 localhost`     | \
grep -v ":::\*"              `# ignore ipv6 any ip:port`   | \
grep -v "0.0.0.0:\*"         `# ignore ipv4 any ip:port`   | \
grep -v -P "119.254.0.\d*"   `# ignore link local address` | \
grep -v ":12300$"            `# ingnore onion system`

3.3 使用数组并遍历

## declare an array variable
declare -a arr=("element1" "element2" "element3")

## now loop through the above array
for i in "${arr[@]}"
do
   echo "$i"
   # or do whatever with individual element of the array
done

# You can access them using echo "${arr[0]}", "${arr[1]}" also

3.4 读文件行

while read p; do
  echo "$p"
done <peptides.txt

3.5 赋值

https://phoenixnap.com/kb/linux-commands-cheat-sheet

3.6 脚本中的特殊流程

3.7 传递外部变量到脚本中

COLUMNS=$COLUMNS my_script

3.8 脚本获取 flag 参数

getopts 被用来在解析通过命令行传给脚本的参数,可以通过 man bash 或者 man getopts 来查看具体用法:

getopts OPTSTRING VARNAME [ARGS...]

其中,OPTSTRING 为预期的参数,有以下几种类型:

冒号在最前边的作用:让用户自己处理选项不匹配的错误。不匹配的选项,对应的 ${flag}?。另外有两个变量:OPTARG 用于获取带参数的选项的参数,OPTERR表示师傅需要显示错误信息。

a_flag=''
files=''
verbose='false'

print_usage() {
  printf "Usage: ...\n"
}

# -a -f 带参数 -v
while getopts 'af:v' flag; do
  case "${flag}" in
    a) a_flag='true' ;;
    f) files="${OPTARG}" ;;  # 获取 -f 参数
    v) verbose='true' ;;
    *) print_usage
      exit 1 ;;
  esac
done

3.9 特殊变量

https://linuxhint.com/use-special-variables-in-bash/

# 存储为 t.sh 并执行 sh t.sh a b c
touch "$*"  # 会创建一个文件
touch "$@"  # 会创建三个文件
echo "$#"   # 3
echo "$0"   # t.sh
echo "$?"   # 0
sleep 1000 &
echo "$!"   # sleep 的 PID

四、文件内容处理

4.1 grep 按照模式匹配内容

grep 可以匹配行,可以匹配内容的一部分,也可以只显示文件名,也可以过滤"不匹配",还可以处理二进制文件。

# 查找不包含指定内容的文件 (`-L, --files-without-match`)
grep -L title *   # 注意跟 `-v` 的含义的不同

# 二进制文件过滤内容 (`-a`, --text 以文本形式处理二进制文件)
# 只显示匹配到的内容 (`-o`)
grep -a -o -P "GLIBCXX[_0-9\.]*" /usr/lib/libstdc++.so

# 大小写不敏感(`-i`)匹配 build,递归目录下所有文件(`-r`)
grep -i -r build * --color

# 显示文件名(`-H`),显示行数(`-n`),不包含(`-v`)DEBUG的所有行
grep -H -n -v DEBUG wx.log


# 显示匹配行的前几行(`-B n`)和后几行(`-A n`)
grep verify_code_expiretime * -B 2| grep cfg -A 1

# 只显示文件名(`-l`)
grep -l test t.log

对于二进制文件,也可以通过 strings 先将其转成可见字符串,再进行 grep

4.2 按照列进行处理

【打印第 N 列到最后】 awk 能方便地拆分字段,通过将前边的 N-1 个值赋值为空,则可以达到打印第N列到最后的效果,但是这样会留下N-1个空格,可以配合使用 sed 将开头的空格去掉:

awk '{$1=$2=""; print $0}' somefile | sed 's/^   //g'

【按照第 N 列排序】 sort 指令用 -t 表示分列的符号,类似于 awk-F-k 带数字表示按照第几列排序。

sort -t' ' -k1 simple_history

【按照字段过滤某列】

## 以 `\t` 分割,第二列为`at createError` 则打印该行(`$0`)
awk -F'\t' '{if($2=="at createError") {print $0}}' t.log

【按照列运算】

# 求和
awk '{sum+=$1} END {print "Sum = ", sum}' file

# 平均值
awk '{sum+=$1} END {print "Avg = ", sum/NR}' file

# 最大值
awk 'BEGIN {max=0}{if($1>max) max=$1 fi} END {print "Max=", max}' file

4.3 通过管道处理文件并落到同一个文件

利用 sponge工具,能够等待接收到所有数据之后再落文件,所以下边的指令实际是等待管道前面执行完,获得所有输出再落到该文件中。

grep -v 'seg[0-9]\{1,\}\.[0-9]\{1\}' file_name | sponge file_name

4.4 文件的交集、并集、差集

使用 comm 命令,比较好记的方法是,3表示file1与file2独有的行,1表示不在file1的行,2表示不在file2的行,所以通过下列组合,可以得到不同的集合:

# 差集:在file1且不在file2的行
# file1和file2独有的行 且 不在file2的行,就是只在file的行
comm -23 file1 file2

# 差集:在file2且不在file1的行
comm -13 file1 file2 

# 交集:在file1且在file2的行
comm -12 file1 file2 

上边的file1 和 file2 得是已经排序的,如果不想动文件,可以直接在命令行中排序:

comm -23 <(sort file1.tx) <(sort file2.txt) > file1_remaining.txt

4.5 打乱行顺序

# 打乱行顺序,可以用于将文件快速分成训练集和验证集
shuf file1

tac file1    # 行倒序
cat file1    # 行正序

4.6 创建指定大小+随机内容的文件

以下两种方式的指令,都可以产生 1G 大小文件并存放到 1G.log 中:

head -c 1G </dev/urandom >1G.log
dd if=/dev/urandom of=1G.log bs=4096

五、文件路径相关

5.1 查找文件

# 只匹配 文件名或者最后一层文件夹 包含完成单词
locate -b -r "\<make-me-stronger\>"   # -r 表示二进制,-b basename

如果 locate 遇到 “locate: can not open `/var/lib/mlocate/mlocate.db’: No such file or directory” 的错误,可以执行 updatedb 解决。

5.2 find

# 找到当前目录及子目录,普通文件(`-type f`),并执行(`-exec {} ... \;`) grep 命令
find . -type f -name "*" -exec grep cmd {} -H \;

# 找到当前目录下(`-maxdepth 1`),所有以 `.` 开头的文件
find . -maxdepth 1 -name '.[^\.]*'

# 多种条件 or (`-o`)
find . -name "*.cc" -o -name "*.h" 

# 查找除了(-path ... -prune) thirdparty目录之外的 *.bzl 文件
find . -path ./third_party -prune -o -name '*.bzl' -print

# 查找1M~50M且修改时间在1天前4天内的文件
find . -size +1M -size -50M -mtime +1 -mtime -4

5.3 创建临时文件/文件夹

mktemp -d XXXX -p /tmp/  # 指定产生位置
mktemp -d /tmp/XXXX      # `-d` 是文件夹的,不带是文件
mktemp -q pic-XXXX

5.4 特殊路径处理

# 查看隐藏目录文件的大小
du -hs .[^.]* 

# 删除 `-` 开头的文件
rm ./-o

# 文件路径拼接,-1表示一列显示一个文件,paste将其进行拼接
ls -1 | paste -sd "," -

六、网络相关

6.1 抓包与分析

tcpdump 抓 pcap 文件,可以使用 Wireshark 分析:

tcpdump -i any -s 65535 tcp port 80 -w xx.pcap

tshark 可以处理 pcap 文件:

tshark -r 983_MonthlyCalendar.QueryPackage.new.pcap -Y "tcp.stream eq 0 and http2.streamid eq 6121" -T fields -e http2.data.data > temp.bin

6.2 curl

-o, --output: 指定下载文件,将文件指定为 /dev/null 可以直接丢弃返回内容 -v, --verbose: 查看请求和返回的详细信息 -w, --write-out: 指定输出格式 -F, --form: 表单内容,接 @xx 可以上传文件

统计一次请求的不同阶段的耗时:

curl -o /dev/null -s -w %{time_namelookup}::%{time_connect}::%{time_starttransfer}::%{time_total}::%{speed_download}"\n" "http://www.qq.com"

上传文件:

curl -X POST -H 'Referer: http://ref-astc-encoder.com/' -F file=@"example.astc" "http://astc-encoder.com/decompress?block=8x8&color-profile=H" -o example.tga

6.3 wget

直接下载文件并执行或解压,而不保存到本地:

wget --no-check-certificate -qO- https://download.docker.com/linux/static/stable/x86_64/docker-20.10.9.tgz | tar zx

6.4 netstat

netstat -lanp | grep 5005| grep LISTEN| awk '{print $7}'|awk -F"/" '{print $1}'|xargs kill
netstat -4tlanp | grep -i listen

netstat -46

netstat -su4
netstat -st6

6.5 网络异常模拟

使用 TC 模拟网络异常,参考文章《基于TC和netem实现网络异常情况的模拟

# 删除 eth0网卡之前添加的netem配置
tc qdisc del dev eth0 root 

# eth0 网卡延迟增加
# 以下分别延迟 100ms / ± 20ms 之间(90ms - 110ms)/ 比例随机 / 正态随机
tc qdisc add dev eth0 root netem delay 100ms
tc qdisc add dev eth0 root netem delay 100ms 20ms
tc qdisc change dev eth0 root netem delay 100ms 20ms 50%
tc qdisc change dev eth0 root netem delay 100ms 20ms distribution normal

# 发送的报文有 50% / 0.3% ~ 25% 的丢包率
tc qdisc change dev eth0 root netem loss 50%
tc qdisc change dev eth0 root netem loss 0.3% 25%

# 随机产生 50% 重复的包
tc qdisc change dev eth0 root netem duplicate 50%

# 随机产生 2% 损坏的报文(在报文的随机位置造成一个比特的错误)
tc qdisc change dev eth0 root netem corrupt 2%

# 固定的每隔一定数量的报文就乱序一次 / 使用概率来选择乱序的报文
tc qdisc change dev eth0 root netem reorder 50% gap 3 delay 100ms
tc qdisc change dev eth0 root netem reorder 50% 15% delay 300ms

6.6 防火墙

firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=mountd
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --reload

6.7 其他辅助工具

ws - WebSocket 测试】 安装 websocket tool,go get -u github.com/hashrocket/ws。连接 Server 使用:

ws ws://127.0.0.1:1323/ws

wrk - HTTP 压测】地址:https://github.com/wg/wrk

七、文件格式校验、转换

7.1 解析与校验

XML 文件解析及是否合法:利用 xmlint 工具,如果 XML 文件不合法,则将会产生标准输出

xmllint --format demo_n_idip.xml > /dev/null
echo $?

JSON解析及是否合法:利用 jq 指令,格式化 JSON 输出,与上边类似,也可以利用返回码做校验

cat timeout.log  | jq

7.2 文件信息查询

# 查询图片大小
convert example.png -print "Size: %wx%h\n" /dev/null

# 查看文件创建、修改、访问时间
stat file1

# 查看视频信息
mediainfo input.mkv
mediainfo --fullscan input.mkv

7.3 文本编码相关

# 去掉 UTF8 BOM
sed -i '1s/^\xEF\xBB\xBF//' orig.txt

# 查看文件编码方式
file file1

# 编码转换,gbk转utf8

7.4 文件格式转换

Tex 转 Word,使用到 pandoc 工具,这个工具可以将很多标记类文本进行相互转换,比如 HTML、Markdown、Tex、docx、pptx、pdf。

pandoc -s resume.tex --bibliography=mycite.bib -o resume.docx

图片转PDF - ImageMagick 图片处理

# `apt-get install imagemagick` on Ubuntu
convert *.jpg -auto-orient pictures.pdf

视频转换 profile 和 level

ffmpeg -i input.mp4 -c:v libx264 -profile:v high -level:v 4.0 -c:a copy output.mp4

将视频进行切分

ffmpeg -i ORIGINALFILE.mp4 -acodec copy -vcodec copy -ss 0 -t 00:15:00 OUTFILE-1.mp4
ffmpeg -i ORIGINALFILE.mp4 -acodec copy -vcodec copy -ss 00:15:00 -t 00:15:00 OUTFILE-2.mp4

7.5 代码格式化工具

yapf   # Python     `pip install yapf`

八、Bash 输出

8.1 特殊字符和格式输出

数字补 0

https://stackoverflow.com/questions/8789729/how-to-zero-pad-a-sequence-of-integers-in-bash-so-that-all-have-the-same-width

seq -f "%05g" 10 15    # 生成补0的序列
printf "%05d\n" $i     # 打印补0的数字
printf -v j "%05d" $i  # 存储补0的数字

echo 带换行

echo $'hello\nworld'

清空屏幕内容

clear

8.2 强制刷管道缓冲

# 按照行缓冲
stdbuf -oL /some/command &> some_log.log

# 无缓冲
stdbuf -o0 /some/command &> some_log.log

8.3 日期时间转换

date +%s                   # 打印当前时间戳
date -d@1635131675         # 将时间戳转换成时间
date --date='2022-06-28 12:40:00' +"%s"  # 时间字符串转时间戳
date +"%s" -d "1 day ago"  # 当前时间一天前的时间戳

8.4

九、进程与系统状态

9.1 信号

查看所有信号对应的数值

kill -l      # 列出所有能通过kill发送的信号
kill -l 9    # 查询指定信号值的含义
man 7 signal # 查看信号值具体含义

kill -SIGUSR1 32281   # 向指定进程发送指定信号
kill -10 32281   # 向指定进程发送指定信号

9.2 错误码含义查询

errno -l  # 查看所有错误码
errno 11  # 查看指定错误码

会返回:

EAGAIN 11 Resource temporarily unavailable

errno 指令在 moreutils 包中,如果如果需要使用,可能需要使用 yum install moreutils 进行安装。

9.3 top

按照内存排序:top 的展示默认是按照 CPU 排序的,如果想按照内存(%MEM),有两种方式可以操作:

9.4 ps

# -e 所有进程,-o 指定显示列,lstart 带详细启动时间
ps -eHo pid,lstart,cmd

# -f 完整信息列表,-T 显示线程,-p 指定 PID
ps -fT -p 3402179

9.5 查看系统日志

找到被OOM Killer 杀掉的进程,可以直接去 /var/log/ 目录中查看 message开头的日志。或者使用命令:

dmesg -T | egrep -i 'killed process'  
# `-T, --ctime` - Print human-readable timestamps.

查看 crontab 执行的日志,可以在 /var/log/ 目录下 cron- 开头的文件中找到。

十、资源控制与参数调整

cgroups

建立资源限制,该限制下最多使用 10% 的 CPU:

cgcreate -g cpu:/tlog
cgset -r cpu.cfs_period_us=1000000 tlog
cgset -r cpu.cfs_quota_us=100000 tlog
cgexec -g cpu:tlog ./a.out &

系统参数设置

显示所有系统参数:

sysctl -a

设置core文件命名模式:

sysctl -w kernel.core_pattern=core

网络相关参数

/proc/sys/net/ipv4/* 目录中的变量说明,可以参考这个链接

调整接收/发送缓冲区大小:

sysctl -w net.core.rmem_default=26214400
sysctl -w net.core.rmem_max=26214400

sysctl -w net.core.wmem_max=67108864
sysctl -w net.core.wmem_default=67108864

调整 socket监听的backlog上限

sysctl -w net.core.somaxconn=65535
sysctl -w net.core.tcp_max_syn_backlog=262144
sysctl -w net.core.netdev_max_backlog=3000000

调整TCP使用内存页数(第一个值是内存使用的下限;第二个值是内存压力模式开始对缓冲区使用应用压力的上限;第三个值是内存使用的上限):

sysctl -w net.ipv4.tcp_mem='758316 1011092 1516632'

调整client端口范围:

sysctl -w net.ipv4.ip_local_port_range="32768 61000"

其他一些常用参数:

net.ipv4.tcp_tw_reuse
net.ipv4.tcp_fin_timeout
net.ipv4.tcp_syncookies
net.ipv4.tcp_tw_recycle
net.ipv4.tcp_no_delay_ack

调整 TCP/IP 栈传输队列大小

ifconfig eth1 txqueuelen 10000

安装给用户

但是我们可以安装到

编译构建

automake

获取系统页大小:

getconf PAGESIZE

显示 GCC 在该平台上的默认添加的定义:

gcc -dM -E - < /dev/null