常用命令
adduser
$ adduser eagle
$ passwd eagle # ur password for eagle user
# 赋予用户可以 sudo的权限
$ chmod u+w /etc/sudoers
$ vim /etc/sudoers
# 找到 `root ALL=(ALL) ALL`这行,并在下面添加 eagle用户
eagle ALL=(ALL) ALL
$ chmod u-w /etc/sudoers
# 切换到 eagle用户
$ su - eagle
chown
# 软链接
$ chown -h superset:superset superset
# 所有子目录及文件
$ chown -R superset:superset superset-0.15.4
date
# 该时间戳格式为 13位毫秒级别
$ echo "`date -d '2017-04-21 10:00:00' +%s`000"
du
# 文件大小
$ du -h /home/ --max-depth=1
3.1G /home/eagle
40.8G /home/
# 同理,使用 `ll -h`也可以得到文件的大小
$ ll -h
总用量 546M
-rw-rw-r-- 1 zookeeper zookeeper 41M 8月 31 10:08 zookeeper.log
-rw-rw-r-- 1 zookeeper zookeeper 101M 8月 31 00:06 zookeeper.log.1
-rw-rw-r-- 1 zookeeper zookeeper 101M 8月 29 11:39 zookeeper.log.2
-rw-rw-r-- 1 zookeeper zookeeper 101M 8月 27 16:01 zookeeper.log.3
-rw-rw-r-- 1 zookeeper zookeeper 101M 8月 25 20:38 zookeeper.log.4
-rw-rw-r-- 1 zookeeper zookeeper 101M 8月 24 00:34 zookeeper.log.5
-rw-rw-r-- 1 zookeeper zookeeper 4.2M 8月 31 09:35 zookeeper.out
grep
# 或操作
$ grep -E 'bin|etc'
$ egrep 'bin|etc'
$ awk '/bin|etc/'
# 与操作
$ grep bin | grep etc
# 不区分大小写
$ grep -i BIN # (bin/sbin)
# 全词匹配
$ grep -w bin # (bin)
# 匹配,并指定显示多少行上下文
$ grep -C 1 bin # (bin/boot root/sbin/script)
# 过滤脚本输出 (|& 相当于 stdout + stderr )
$ zkServer.sh status |& grep Mode
Mode: follower
lsof
# 系统级 监控 & 诊断工具
# 指定进程号,可以查看该进程打开的文件
$ lsof -p <pid>
nmon
- 生成 nmon文件
# 获得帮助文档
$ nmon_x86_64_centos6 -h
# 不同的操作系统,可能 nmon命令不一样
# -f 使得 xxx.nmon文件名包含文件创建的时间
# -N 指定需要对 NFS活动情况进行监控
# -m 指定生成的 xxx.nmon存放的目录
# -s 指定相隔多少秒,做一次监控
# -c 指定采集多少次监控数据,生成一个 xxx.nmon文件
$ /nmon/nmon_x86_64_rhel6 -f -N -m /nmon -s 60 -c 1440
$ /nmon/nmon_x86_64_centos6 -f -N -m /nmon -s 60 -c 1440
# 转换 .nmon文件为 .csv文件
$ sort yuzhouwan-prd3_170831_0001.nmon > yuzhouwan-prd3_170831_0001.csv
# 查看监控数据
# 在 https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/Power%20Systems/page/nmon_analyser 页面,下载 nmon analyser v52_1.xlsm文件
# 打开后,会提示"启用宏定义",点击确定
# 一共会有 Analyser/Settings/Release Notes 三个 sheet,跳转到第一个 Analyser里
# 点击 "Analyze nmon data"按钮,选择 yuzhouwan-prd3_170831_0001.csv文件
# 会生成一个 yuzhouwan-prd3_170831_0001.nmon.xlsx,并直接打开
- 系统资源实时监控
$ /nmon/nmon_x86_64_centos6
# 常用组合:nml
lnmonq14g---------------------Hostname=yuzhouwan-prd3-Refresh= 2secs ---11:04.35-----------|
| CPU +-------------------------------------------------------------------------+ |
|100%-| | |
| 95%-| | | # 为节省空间 此处,省去25%~90%
| 20%-| | |
| 15%-| | |
| 10%-| ss | |
| 5%-|UUUUsUUUUsUUsUUUUwUUssUssUUssUUUsUUsUUUUUsU| |
| +--------------------User---------System----+----Wait---------------------+ |
| Memory Stats --------------------------------------------------------------------------|
| RAM High Low Swap Page Size=4 KB |
| Total MB 129013.3 -0.0 -0.0 10240.0 |
| Free MB 584.1 -0.0 -0.0 10240.0 |
| Free Percent 0.5% 100.0% 100.0% 100.0% |
| MB MB MB |
| Cached= 76656.7 Active= 54649.3 |
| Buffers= 4908.1 Swapcached= 0.0 Inactive = 68809.5 |
| Dirty = 131.6 Writeback = 0.0 Mapped = 75.1 |
| Slab = 4059.3 Commit_AS = 47663.8 PageTables= 96.6 |
| Network I/O ---------------------------------------------------------------------------|
|I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans |
| lo 1044.0 1044.0 335.5 335.5 3186.8 3186.8 8639.4 8639.4 |
| eth0 5262.7 1168.7 5999.0 2762.1 898.3 433.3 10531.6 43312.1 |
| eth1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 |
|---------Warning: Some Statistics may not shown-----------------------------------------|
make
$ make -j<thread_num>
# 查看 CPU核数
$ cat /proc/cpuinfo | grep processor | wc -l
# 如果是两个处理器的话,一般 `-j2`可以达到最高效率 (某些进程主要耗时是在 I/O上,并不能充分利用单个 cpu的时间,则可以考虑 -j4)
# 一般的,使用 `thread_num = number_of_cores + 1`公式来计算即可
tar
# 压缩
$ tar zcvf gc.tar.gz gc
# 解压
$ tar zxvf gc.tar.gz
top
# 查看进程内线程资源消耗
$ top -Hp <pid>
tree
$ yum install tree -y
$ tree -L 1 /
/
├── bin
├── usr
└── var
rpm
$ rpm -i --badreloc --relocate /usr/java=/home/eagle/software/java jdk-7u80-linux-x64.rpm
rsync
# 软链接、隐藏文件 等特殊文件的复制,需要用 `rsync`命令而不能用 `scp`
$ rsync -avuz -e ssh eagle/ root@eagle:/home/eagle
ps
# 查看进程的 启动时间 和 已运行时长
$ ps -eo pid,lstart,etime | grep <pid>
# 查看进程分配内存大小
# RSS (Resident Set Size) 常驻内存集,表示该进程分配的内存大小
$ ps -e -o pid,rss
uname
$ uname -a
Linux yuzhouwan 2.6.32-504.3.3.el6.centos.plus.x86_64 #1 SMP Wed Dec 17 01:21:03 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
# kernel version
$ uname -r
2.6.32-504.3.3.el6.centos.plus.x86_64
# 具体含义: <内核主版本>.<偶数:稳定版本/奇数:开发中版本>.<错误修补的次数>-<?>
标准I/O
# 只输出 脚本执行异常信息
$ ./commands.sh 1>/dev/null 2>./error.log
# 完全不作输出
$ ./commands.sh 1>/dev/null 2>&1
--
Shell编程
dirname
# 跳转到,当前脚本的文件目录
cd `dirname $0`
.bashrc
# 在执行脚本开始的时候,载入环境变量
source ~/.bash_profile
cut string
# 将 string的前后各删除一个字符
arr="[leader, election, zookeeper]"
arr=`echo ${arr:1:${#arr}-2}` # leader, election, zookeeper
command
# 通过 `command`命令,可以在脚本开始执行前,对需要的命令进行check
command -v nc >/dev/null 2>&1 || {
echo >&2 "I require nc but it's not installed. Try install..."; exit 1;
}
for loop
arr="leader, election, zookeeper"
OLD_IFS="$IFS"
IFS=$", "
arr=(${arr})
for a in ${arr[@]}; do
echo ${a}
done
IFS="$OLD_IFS"
# 设置IFS,前面 "实战技巧 - IFS设置" 已经提到了
# 下面介绍一种 `fori`的遍历方式
# 0 /election
# 0 /leader
# 2 /zookeeper
sorted_num=`echo ${sorted} | wc -l`
if [ ${sorted_num} -gt ${top_n} ]; then
sorted_num=${top_n}
fi
json="{"
for (( i=1; i<=${sorted_num}; i++ )); do
line=`echo "${sorted}" | sed -n "${i} p"`
json="${json}`echo ${line} | awk '{print $1}'`: `echo ${line} | awk '{print $2}'`"
if [ ${i} -lt ${sorted_num} ]; then
json="${json}, "
fi
done
json="${json}}"
# 当然,也有其他的实现方法,比如下面 `seq`这种
# 但是,`seq`这种方式需要注意两点
# 第一点,$(seq 1 1 10)里面的 初始值、步长、最大值 都必须要是 Integer类型的,如果是通过 shell外部传参进来的,需要做类型转换
# 第二点,`seq`方式在 console里面执行没问题,但是,写在 shell脚本里面,可能会失效 (原因尚不明确)
for i in $(seq 1 2 10); do echo "skip by 2 step, value is $i"; done
readlink
# 获取到文件
$ readlink -f logs/zookeeper.log
/home/zookeeper/logs/zookeeper.log
sed
# 先后从 zk_con里面,将 ":"冒号后面 和 "/"斜线之前的 都删掉
zk_con=" /192.168.1.1:35632[1](queued=0,recved=146,sent=146,sid=0x25dd0c02a0a02a7,lop=PING,est=1503994626336,to=40000,lcxid=0x0,lzxid=0xffffffffffffffff,lresp=1503996561355,llat=0,minlat=0,avglat=0,maxlat=3)"
zk_con=`echo $zk_con | sed 's/:.*//g' | sed 's/.*\///g'` # 192.168.1.1
sort
# 通过 `-k1`指定 针对第一列进行排序
# 通过 `-n`指定 针对数字进行排序,避免 9排在了 10前面
# 当然也可以通过增加 `-r`,使得排序变成降序
# 如果,列与列之间的分隔符不是默认的 \t,则需要通过 `-t`参数进行指定
# 0 /election
# 0 /leader
# 2 /zookeeper
sorted=`echo ${result} | sort -k1 -n`
uniq
# 计数
echo -e "1\n1\n0" | uniq -c
# 2 1
# 1 0
exit 0
# 养成一个,脚本结尾,添加 `exit 0`的好习惯
exit 0
实用技巧
IFS设置
Shell 脚本中 IFS变量全称 Internal Field Seprator ,内部域分隔符
$ echo $IFS
$ echo "$IFS" | od -b
0000000 040 011 012 012
0000004
# 遍历多行文本之前,设置 IFS为 \n
pids=`ps -ef | grep "${PROCESS_NAME}" | grep -v grep | grep -v "${SELF_NAME}" | awk '{print $2}'`
IFS=$'\n' read -rd '' -a pids <<<"$pids"
echo "pids: ${pids}"
for pid in "${pids}"; do
echo "kill -9 ${pid}"
kill -9 "${pid}"
done
每秒执行一次
$ while true; do sleep 1; <command>; done
Windows相关
- Windows下执行 shell脚本
# 安装 git
$ doskey bash="%GIT_HOME%\bin\bash.exe" $*
$ doskey sh="%GIT_HOME%\bin\sh.exe" $*
$ bash shell.sh
# 类似的可以设置 `np`为 `notepad++`的快捷启动命令
$ doskey np=D:\apps\Notepad++\notepad++.exe $*
- Cmd设置 Proxy
$ set http_proxy=http://your_proxy:your_port
$ set http_proxy=http://username:password@your_proxy:your_port
$ set https_proxy=https://your_proxy:your_port
$ set https_proxy=https://username:password@your_proxy:your_port
优化实战
关闭Swappiness
$ cat /proc/sys/vm/swappiness
# default: 60
# memory first: 0
# swap first: 100
# 使得 swappiness设置永久生效
$ vim /etc/sysctl.conf
vm.swappiness=10
# 可以配合 JVM中的 `-XX:+AlwaysPreTouch`参数,在进程启动的时候,让 jvm通过 demand-zeroed方式将内存一次分配到位,提高 daemon常驻进程性能
控制Overcommit
$ cat /proc/sys/vm/overcommit_memory
# 0: 表示内核将检查是否有足够的可用内存供应用进程使用
# 如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程
# 1: 表示内核允许分配所有的物理内存,而不管当前的内存状态如何
# 2: 表示内核允许分配超过所有物理内存和交换空间总和的内存
禁用透明巨页
- Page Size
$ getconf PAGE_SIZE
4096
- Huge Page Size
$ cat /proc/meminfo | grep Hugepagesize
Hugepagesize: 2048 kB
- Transparent Huge Pages
$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
$ echo never > /sys/kernel/mm/transparent_hugepage/enabled
$ echo never > /sys/kernel/mm/transparent_hugepage/defrag
# Redhat的相关目录: /sys/kernel/mm/redhat_transparent_hugepage/