Linux 常用命令以及简介

前言

最近在学习大数据,少不了和linux打交到,下面是半年来使用过的linux相关的命令,想起来的就整理了一下,以供查阅,并督促自己时常整理所学知识。 也可以帮初学者梳理一下~

基础概念

# [用户名@主机名 当前文件夹],`$`代表普通用户
[[email protected] zhangqiang]$ 

# ~ 代表当前用户的根目录,`#`代表超级用户
[[email protected] ~]# 

基础命令和工具

man & info

查看命令的具体使用方法和说明

# 如果对当前命令不是特别清楚它的用法
man [command]

# 例如:它会显示rm命令的解释说明和它的 options
$ man rm 

# 相对于`man`,`info`命令可以查阅更详细的命令介绍
$ info rm

访问文件夹

# cd 命令
  # 进入当前用户的主目录
  只输入 cd  或者 cd ~
  # 返回上级目录
  cd ..
  # 进入当前文件夹的data文件夹,. 代表当前文件夹
  cd ./data 
  # 进入系统根目录
  cd /

文件/文件夹的创建、拷贝、移动、重命名

# 创建文件夹
$ mkdir directory
# 创建多层文件夹
$ mkdir -p d1/d2/d3
# 创建文件
$ touch file.txt

# 重命名,把d2重命名成rd2
$ mv d2 rd2
# 移动文件夹,将d2移动到上级目录
$ mv d2 ../ 

# 拷贝文件 将hello.txt拷贝到world.txt
$ cp hello.txt world.txt
# 拷贝文件夹
$ cp -r dir1 dir2
# 拷贝多个文件到指定目录
$ hadoop fs -ls /data/testData | sed -n '3,33p' | awk '{print $8}' | xargs -i hadoop fs -cp {} /data/test/download_test

Linux 跨服务器的文件传输

scp

# 在文件所在路径下 将spark-env.sh 发送到IP为s12181的neu用户的/opt/neu/spark/conf文件夹下(如果已经存在则覆盖)
$ scp spark-env.sh [email protected]:/opt/neu/spark/conf

# 传送文件夹下的所有文件(包含隐藏文件),-p指保留原文件的修改时间、访问时间和文件权限。 
$ scp -rp /usr/zhangqiang/source/. [email protected]:/usr/zhangqiang/test/

# 传送文件夹到s121203的neu用户的根目录下
$ scp -rp spark-2.1.1-bin-hadoop2.6 [email protected]:

# 将多个文件发送到目标节点的用户根目录
$ scp file1 file2 file3  [email protected]:

# 将远程主机的文件发送到本机用户根目录
$ scp [email protected]:~/file ~

# 将远程主机1(s121203)的文件发送到远程主机2(s121204)的用户根目录
$ scp [email protected]:~/file [email protected]:~

# 将远程主机1(s121203)的文件和远程主机2(s121204)的文件发送到远程主机3(s121205)
# 可以看出只有最后一个才是目标主机,其他的都是源主机(发送文件的主机)
$ scp [email protected]:~/file_from203 [email protected]:~/file_from204 [email protected]:~

# 通过跳板机与内网机器互相传输
# -o 添加 /etc/ssh/sshd_config 配置
$ scp -P 22 -o 'ProxyJump [email protected] -p 22' /data/file [email protected]:~
# 如果不能直接将中间服务器当做跳板机的情况,修改跳板机的 sshd_config
$ vim /etc/ssh/sshd_config
AllowTcpForwarding yes
PermitTunnel yes
# 重启跳板机 ssh 服务

# 将文件传送到多个服务器上 < Linux -i 替代{}, -i <=> -I{} ; OSX -t 替代参数{} >
$ cat /home/hadoop/slaves|xargs -i -t scp /etc/hadoop/conf/hdfs-site.xml [email protected]{}:/etc/hadoop/conf/hdfs-site.xml

rsync

# 递归同步目录数据 -> 最终会生成 destination/source
$ rsync -r source destination
# 如果只想把 source 中的内容同步到 destination,而非 destination/source 这种形式,就可以带上 /
$ rsync -r source/ destination
# -a 参数可以替代 -r,除了可以递归同步以外,还可以同步元信息(比如修改时间、权限等)
$ rsync -a source destination
# 如果不确定 rsync 执行后会产生什么结果,可以先执行预览
# -n, --dry-run       输出参数模拟执行的结果
# -v                  将结果输出到终端
$ rsync -anv source/ destination

sz rz

# 利用 Zmodem 协议从本地(Windows..)和服务器(Linux)之间进行文件传输,一次可以传送一个或多个文件
# 相对于 sftp 的优点就是不需要登录服务器去获取文件,缺点是只适合小文件传输,速度只有 10KB/s
# sz(send: server -> local)
# rz(receive: server <- local)
# send / receive 是相对于 linux server 来说的,因为要在 server 端执行命令
# 只需安装在 Linux Server 即可,配合 Xshell 或者 ScureCRT 客户端(Windows)使用
$ yum install -y lrzsz
# 以二进制格式进行传输
$ sz -b file1 [file2] [file3...]

nc

# 对于大文件传输,使用 nc 传输文件同样不像 scp、rsync 那样输密码的操作,但是和 sz、rz 也不同,windows linux 都要安装 netcat
# Netcat for Windows: 
https://joncraton.org/blog/46/netcat-for-windows
# 先在 receiver server 启动服务,监听端口等待接收文件
# -v 显示详细信息,一般用于 debug, -vv 显示更详细的信息
# -l listen mode, for inbound connects, 即启动 server
$ nc -vv -l 9995 >somefiles.rpm
# 然后传送数据给 server, server 端成功接收完数据后会自动退出监听
# -w 10 connects 和 final net reads timeout,10s 后断开连接,不然连接会一直保持,只能在 client 端生效
$ nc -vv -w 3 192.168.0.1 9995 <somefiles.rpm
# server 接收多文件
$ nc -vv -l 9995 | tar -xfvz -
# client 打包当前文件夹所有文件
$ tar -zvcf - * | nc -v 192.168.0.1 9995
# server 端显示进度
$ yum install epel-release -y
$ yum install pv -y
$ nc -vv -l 9995 | pv -b | tar -zxvf -

# -k 监听多个连接,这样 nc server 会一直运行不会因为某个client断开连接而终止
$ nc -vv -l -k 9995

# 留后门, -e 执行 command,将 /bin/bash 与端口 10000 相连
$ nc -l 9995 -e /bin/bash
# 这样就相当于跳过登录直接获取一个 bash shell 操控系统,不过用户权限取决于起 nc 服务的用户
$ nc 192.168.0.1 9995

# 端口转发
# -u udp 
# -c 所有连接到 80 端口的连接都会转发到 8080 端口。
$  nc -u -l 80 -c  'nc -u -l 8080'
# 将两个文件做连接,二者在物理上是同一个文件。目的是为了在不同文件夹下使用相同文件而不用拷贝多个文件,cp无法做到同步更新。
ln

# 创建硬连接(默认),会创建一个和sourceFile大小相同的文件targetFile,和拷贝不同的是,两个文件的内容是同步的,修改其中一个文件,
# 另一个文件中的内容也会改变。它们在物理上共用一个相同的inode号,因为inode号是文件系统唯一的,因此硬连接不能跨磁盘分区,每个磁盘
# 分区都有自己独立的文件系统(ext4,xfs...)
$ ln sourceFileName targetLinkFileName

# 创建软连接(符号连接),相当于windows的快捷方式。
# 当创建软连接的时候源文件也可以是文件夹,硬连接不可以
$ ln -s sourceFileName[sourceDirectoryName] targetLinkFileName[targetLinkDirectoryName]

# 例1:为/Users/despacito/test.conf 在/Users/despacito/ 下创建一个名为testlink的硬连接文件
$ ln /Users/despacito/test.conf /Users/despacito/testlink
$ ls -l
# 可以发现test.conf 和 testlink的连接数为 2,并且文件大小都为 3196353
-rw-r--r--  2 despacito  staff  3196353  5 29 21:57 test
-rw-r--r--  2 despacito  staff  3196353  5 29 21:57 testlink

# 例2:为/usr/local/python2.7 在 /usr/local/bin/中创建名为python2.7的软连接
$ ln -s /usr/local/python2.7 /usr/local/bin/
$ ls -l /usr/local/bin
# 可以看到,其中lrwxr-xr-x中的第一位l表示它是一个软连接,它指向/usr/local/python2.7
lrwxr-xr-x  1 root  wheel  71  8 10 14:17 python2.7 -> /usr/local/python2.7

文件内容的修改与查看

vi / vim
# 当编辑的文件不存在的时候会创建一个新的文件
vi file.txt
# 一开始进入的是检查模式,按'i'进入编辑模式,按'esc'退出编辑模式,进入检查模式
# 在检查模式下输入':'进入命令模式,同样的,按'esc'退出命令模式,进入检查模式
# 保存并退出,在检查模式下按 'shift'+'z'*2,即两次大写的'Z', 或者在命令模式下输入 ':wq'
# 放弃保存并退出,在命令模式下输入':q!'
# 在未修改任何内容的情况下,正常退出, 输入':q'
# 跳转到文件头,命令模式下:1
# 跳转到文件尾,命令模式下:$ 或者检查模式下 shift + g(大写的 G)
# 按关键字查找,命令模式下:/keyword
# 删除第1到200行(包括第200行) 命令模式下:1,200d

# 查找文本,按'/'进入查找模式,默认是大小写敏感的查找
/text
# 大小写不敏感的查找,在后面加上'\c'。'\C'是大小写敏感
/text\c
# 或者
$ vim ~/.vimrc
# 设置大小写不敏感
set ignorecase
# 如果查找包含一个大写字符,则切换到大小写敏感
set smartcase 

# 查找并替换文本,语法
:{作用范围}s/{匹配项}/{替换}/{替换标志}
# 当前行查找,替换第一个匹配项目
:s/oldstr/newstr
# 当前行查找,并替换所有匹配项
:s/oldstr/newstr/g
# 全文查找,并替换所有匹配项
:%s/oldstr/newstr/g
# 在第 5 到 11 行查找,并替换所有匹配项
:5,12s/oldstr/newstr/g
# 在当前行和接下来的两行中查找,并检查所有匹配项(需要人确认是否替换)
:.,+2s/oldstr/newstr/gc

# vi 快捷键命令
# 整页翻页 f=forward,b=backword 
ctrl + f   ctrl + b
# 翻半页 d=down,u=up
ctrl + d ctrl + u
# 滚一行
ctrl + e ctrl + y

# zz让光标所在的行居屏幕中央
# zt让光标所在的行居屏幕最上一行 t=top
# zb让光标所在的行居屏幕最下一行 b=bottom


# 文件内容查看
 1) more :一页一页的查看,单页查看。缺点是只能往后看,不能往前看。
 2) tail : 查看文件尾部的内容,多用于查看最新的日志信息(滚动日志)
    tail -500f # 当出现最新的日志信息时滚动输出末尾500行内容。
 3) cat : 查看所有文件的内容 -n 显示行号
    # 火眼金睛: -A 显示所有不可见的字符(OSX 不支持),vim :set list 看不到的字符这里也能看到哦
    $ echo "--items hadoop" > invisible_test
    $ cat -A invisible_test
    --itemsM-BM- hadoop$
 4) less : 可以一页一页的随意浏览文件,而且不会加载全文件。
    # /  向下搜索"字符串"
        # n 查找下一个匹配的字符串
        # N 查找上一个匹配的字符串
    # ?  向上搜索"字符串"
    # spcae  滚动一行
    # enter  滚动一页
    # pagedown  向下翻动一页
    # pageup  向上翻动一页
    # :100g 跳转到指定行(第100行),默认(:g)跳到文件开始
    # :100G 跳转到指定行(第100行),默认(:G)跳到文件末尾
    # 显示行号
    less -N 
    # 不计算行号,这样在打开大文件的时候跳到结尾的时候就不会因为计算行号而卡一段时间
    less -n 

查看文件属性 file

# 查看 test.csv 的文件属性
$ file test.csv
test.csv: UTF-8 Unicode (with BOM) text, with very long lines, with CRLF line terminators

# 查看文件的编码信息
$ file --mime-encoding test.csv
test.csv: utf-8

UTF8-BOM 转 UTF8

# 查看文件是否有 BOM
$ grep -rlI $'^\xEF\xBB\xBF' filename

# 删除 BOM
# === 方式 1:
$ find $path -type f -name "*" -print | xargs -i sed -i '1 s/^/\xef\xbb\xbf&/' {}

# === 方式 2:
$ vim filename
:set nobomb # 删除 BOM
:set bomb # 添加 BOM

文件的编码问题

Linux系统默认支持的语言与/etc/sysconfig/i18n有关,终端默认使用变量LANG所指定的字符集进行解码。

# 查看LANG变量
$ echo $LANG
zh_CN.UTF-8

# 更换字符集
$ export LANG=zh_CN.UTF-8

文件编码转换

iconv # 语法:iconv -f old_encode -t new_encode filename [-o new_filename]
# 例如:把编码格式为 utf8 的文件 test.csv 转换成 utf16 并保存到 new_test.csv 中
iconv -f utf8 -t utf16 test.csv -o new_test.csv
# 查看 iconv 支持的字符集
iconv --list
# 繁体中文 uft8 -> 简体中文 utf8
iconv -f utf8 -t big5 traditional_chinese.txt | iconv -f big5 -t gb2312 | iconv -f gb2312 -t utf8 -o simplified_chinese.txt 

# 在 gbk/gb2312 转 utf8 的时候出现
iconv: illegal input sequence at position 189680374
# 这是因为你指定的断言编码有问题。gb2312 是国标里面一个最小也是最早的中文编码标准,它只涵盖了6763个汉字。
# 而 gb18030 是最新的国家标准,包含了27564个汉字,而且向下兼容 gb2312 和 gbk,可以用 gb18030 做为
# 源格式来进行转换
iconv -f gb18030 -t utf8 result.csv -o utf8result.tsv

DOS 与 Linux 换行符

在 DOS(Windows) 系统中建立的文件,换行符用^M$表示,我们把他称为CRLF两个字符。但在 Linux 中,仅有$,即LF一个字符。因此将 Windows 编写的 shell 文件拿到 Linux 下是要记得转换换行符。

# 在 CentOS 中

# DOS 转 Linux
$ dos2unix [-kn] file.txt [new_file.txt]
$ dos2unix -n old_file.txt new_file.txt

# Linux 转 DOS
$ unix2dos [-kn] file.txt [new_file.txt]

# -k:不更新文件的修改时间
# -n:保留原始文件,将转换后的内容输出到新文件中

# 在 Ubuntu 中
$ sudo apt-get install tofrodos

# dos2unix
$ fromdos file.txt

# unix2dos
$ todos file.txt

文件的删除

# 删除文件
$ rm hello.txt

# 删除空目录
$ rmdir d3

# 强制删除文件夹及其包含的所有文件
# -r 递归 (删除 文件夹 d1 以及 d1 内的所有文件)
# -f 强制删除(强制删除不会提醒,慎用!)
$ rm -rf d1 

文件压缩/解压

# tar 命令参数介绍
  -c 压缩 
  -x 解压
  -z 以gzip方式解压(*.tar.gz/*.tgz)
  -v 显示正在处理的文件进度
  -f 要解压的文件名称
  -C 要解压到的特定目录(默认解压到当前目录)

# 压缩 tar
$ tar -zcvf test.tgz dirname
# 排除文件/文件夹
$ tar -zcvf test.tgz dirname --exclude logs --exclude testData


# 解压 tar.gz(tarball) 文件
$ tar -zxvf spark-2.0.2-bin-hadoop2.6.tgz -C /usr/zhangqiang/spark 

# 压缩文件夹
$ zip -r targetDir/targetFile.zip sourceDir
# 压缩 zip(加密)
$ zip -e targetDir/targetFile.zip sourceFile1 sourceFile2...
Enter password:
Verify password:
adding: sourceFile1 (deflated 80%)
adding: sourceFile2 (deflated 80%)
# 分卷压缩(要正常解压缩需要先合并分卷)
$ zip -s 50m origin.zip --out new.zip
# 合并分卷
$ zip splitFile.zip -s=0 --out single.zip

# 解压 zip 文件到指定目录
$ unzip abc.zip -d /home/hadoop/abc

# 解压 gz 文件,-d decompress,gzip 本身并没有解压到指定目录的参数
$ gzip -d abc.gz  

Linux 环境变量设置

# 全局环境变量,应用于所有的用户与Shell  
$ vi /etc/profile 
# 例如配置jdk环境变量
JAVA_HOME=/usr/java/jdk....
CLASS_PATH=$JAVA_HOME/lib
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASS_PATH

# 使配置的环境变量立即生效,不需要重启
$ source /etc/profile 

# 当前用户,应用于所有的Shell。当前用户主目录下 ls -a可以看到所有文件包含隐藏文件
$ vi ~/.bash_profile 

# 全局用户,应用于 Bash Shell
$ vi /etc/bashrc 

# 当前用户,应用于Bash Sell
$ vi ~/.bashrc 

工具

# 批量修改指定文件夹下文件的后缀名称
find /Users/zhangqiang -maxdepth 1 -name "*.xlsx" | awk -F "." '{print $1}'|while read i
do
        echo "$i";
        
        mv $i.xlsx  $i.xls
done
# 或者
find ./ -maxdepth 1 -name "*.xlsx" | awk -F "." '{print $2}' | xargs -i -t mv ./{}.xlsx  ./{}.xls
# 或者 centos
rename .xlsx .xls *.xlsx

文件搜索

 1) find :  
  使用格式如下:
  find <指定目录> <指定条件> <指定动作>
  - <指定目录>: 所要搜索的目录及其所有子目录。默认为当前目录。
  - <指定条件>: 所要搜索的文件的特征。
  - <指定动作>: 对搜索结果进行特定的处理。
  如果什么参数也不加,find默认搜索当前目录及其子目录,并且不过滤任何结果(也就是返回所有文件),将它们全都显示在屏幕上。

  find的使用实例:
    # 搜索当前目录(含子目录,以下同)中,所有文件名以my开头的文件。 
      find . -name "my*"
    # 搜索当前目录中,所有文件名以my开头的文件,并显示它们的详细信息。
      find . -name "my*" -ls
    # 搜索当前目录中,所有过去10分钟中更新过的普通文件。如果不加-type f参数,则搜索普通文件+特殊文件+目录。
      find . -type f -mmin -10
    # 忽略大小写,比如查找 my My mY
      find / -iname "*My*"
    # 只查找当前目录
      find . -maxdepth 1 -name "*sql"
 
 2) locate :其实是`find -name`的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据
 库(/var/lib/locatedb),这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一
 次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,
 手动更新数据库。
    此命令需要安装,`yum -y install mlocate`
  locate的使用实例:
    # 搜索etc目录下所有以sh开头的文件。
      locate /etc/sh
    # 搜索用户主目录下,所有以m开头的文件。
      locate ~/m
    # 搜索用户主目录下,所有以m开头的文件,并且忽略大小写。
      locate -i ~/m
      
 3) whereis :whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b)、man说明文件(参数-m)和源代码
 文件(参数-s)。如果省略参数,则返回所有信息。
  
   whereis的使用实例:
     # 搜索grep的路径
       whereis grep
 
 4) which :which命令的作用是,在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。也就是
 说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。
    
    which的使用实例:
      # 查看python命令的位置
        which python
 
 5)  type :type命令其实不能算查找命令,它是用来区分某个命令到底是由shell自带的,还是由shell外部的独立二进制
 文件提供的。如果一个命令是外部命令,那么使用-p参数,会显示该命令的路径,相当于which命令。
   
    type的使用实例:
      # 系统会提示,cd是shell的自带命令(build-in)
        type cd
      # 系统会提示,grep是一个外部命令,并显示该命令的路径
        type grep
      # 加上-p参数后,就相当于which命令。
        type -p grep

文本内容搜索

grep 是 Linux 下通用的文本内容匹配查找的工具

# 查找当前目录下所有以`file`为后缀的文件中包含字符串`test`的行
$ grep "test" ./*file

# 输出匹配行的前后5行
$ grep -5 'pattern' inputfile 
# 或者
$ grep -C 5 'pattern' inputfile 

# 输出匹配行的后5行
$ grep -A 5 'pattern' inputfile 

# 输出匹配行的前5行
$ grep -B 5 'pattern' inputfile 

# 高亮显示匹配项
$ grep --color=auto "test" ./*file

# 更多的是通过管道符号`|`,对输入流进行文本行过滤
$ cat test.txt | grep "zhangqiang"

# 不区分大小写
$ echo "Test" | grep -i "test"

# 启用扩展正则表达式
$ echo "Test" | grep -E "^T.*"

下载

wget

wget是Linux系统中的一个下载文件的工具。wget 可以跟踪HTML页面上的链接依次下载来创建远程服务器的本地版本,完全重建原始站点的目录结构。这又常被称作”递归下载”。在递归下载的时候,wget 遵循Robot Exclusion标准(/robots.txt). wget可以在下载的同时,将链接转换成指向本地文件,以方便离线浏览。wget 非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性.如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。这对从那些限定了链接时间的服务器上下载大文件非常有用。

wget -O newName.tar.gz http://192.168.51.250:8080/data/data-renminwang/history/article/2017-09-01.tar.gz 

Linux 用户及权限管理

# 添加用户neu
[[email protected] ~]# useradd 参数 用户名

# 参数如下
  -c comment 指定一段注释性描述。
  -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
  -g 用户组 指定用户所属的用户组。
  -G 用户组,用户组 指定用户所属的附加组。
  -s Shell文件 指定用户的登录Shell。
  -u 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。

# 默认创建/home/neu为主目录
[[email protected] ~]# useradd neu 

# 此命令创建了一个用户neu,其中-d和-m选项用来为登录名neu产生一个主目录/usr/neu(/usr为默认的用户主目录所在的父目录)。
[[email protected] ~]# useradd –d /usr/neu -m neu 

# 此命令新建了一个用户gem,该用户的登录Shell是/bin/sh,它属于group用户组,同时又属于adm和root用户组,其中group用户组是其主组。
[[email protected] ~]# useradd -s /bin/sh -g group –G adm,root gem 

# 删除neu用户 -r 将用户的主目录及内容一并删除
[[email protected] ~]# userdel -r neu

# 添加一个新的组neu
[[email protected] ~]# groupadd neu

# 删除组neu
[[email protected] ~]# groupdel neu  

# 修改用户权限,使用参数和 useradd 一样
# 此命令将用户 sam 的登录 Shell 修改为 ksh,主目录改为/home/z,用户组改为 developer。
[[email protected] ~]# usermod -s /bin/ksh -d /home/z –g developer sam

# 允许 hbase 用户登录
[[email protected] ~]# usermod -s /bin/bash hbase 
# 禁止 hbase 用户登录,禁止一切服务,不可以 ftp,并且没有提示,如果想要用false在禁止login的同时允许ftp,则必须在/etc/shells里增加一行/bin/false。
[[email protected] ~]# usermod -s /bin/false hbase 
# 禁止登陆,而且有提示,可以ftp
[[email protected] ~]# usermod -s /sbin/nologin hbase 

# 用户口令管理
$ passwd options username
# 参数如下
  -l 锁定口令,即禁用账号。
  -u 口令解锁。
  -d 使账号无口令。
  -f 强迫用户下次登录时修改口令。

# 当前用户修改自己的用户口令
$ passwd
Old password:******
New password:*******
Re-enter new password:*******
# root 用户修改其他用户(neu)的用户口令
[[email protected] ~]# passwd neu
New password:*******
Re-enter new password:*******
# 删除neu用户的登陆口令(下次登陆不需要口令)
[[email protected] ~]# passwd -d neu
# 锁定neu用户,使其不能登陆
[[email protected] ~]# passwd -l neu
# 解锁
[[email protected] ~]# passwd -u neu

# 为普通用户开启sudo功能,NOPASSWD会避免密码交互
[[email protected] ~]# visudo || vi /etc/sudoers
user     ALL=(ALL)       NOPASSWD: ALL
# /etc/sudoers 文件遵语法格式:
who where=(whom) command
# 即哪个用户/用户组在哪个主机以谁(用户:用户组)的身份执行命令,例如
root     ALL=(ALL:ALL)       ALL
%root    ALL=(ALL:ALL)       ALL
# root       表示 root 用户。
# %root      表示 root 用户组
# ALL        表示从任何的主机上都可以执行,也可以`192.168.100.0/24`。
# (ALL:ALL)  是以谁的身份来执行,ALL:ALL 就代表 root 可以以(任何用户:任何用户组)的身份来执行命令。
# ALL        表示可以执行任何命令。
 
# 查看当前linux下所有的用户
$ cat /etc/passwd    # 可以查看所有用户的列表
$ w                  # 可以查看当前活跃的用户列表,比较详细
$ who                # 可以查看当前活跃的用户列表
$ cat /etc/shadow    # 查看用户名
$ cat /etc/group     # 查看用户组
    
# 新建用户异常:    
# 解决创建同名用户时"信箱文件:已存在"的问题,(Creating mailbox file: 文件已存在)
[[email protected] ~]# rm -rf /var/spool/mail/neu(用户名)
# 解决 useradd: invalid numeric argument 'hadoop'
# 这是由于 hadoop 组不存在 请先建 hadoop 组

查看进程信息

查看进程号的方式大概有三种,静态的ps、动态的top、查阅程序树之间的关系pstree

截取某个时间点的进程运行情况(静态)

# 查看所有进程
$ ps

# 使用 -ef
# -e 所有进程均显示出来,同 -A 
# -f 做一个更为完整的输出
$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun30 ?        00:00:07 /sbin/init
...

# 使用 aux ,注意没有 - 
# a 列出所有进程。注意 a 和 -a 是不同的两个参数。-a 列出不与terminal有关的所有进程
# u 以面向用户的格式显示进程信息。注意 u 和 -u 也是不同的两个参数。
# x 通常与参数 a 一起使用,显示更多的信息
$ ps aux 
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  19236  1464 ?        Ss   Jun30   0:07 /sbin/init
...

# 查看neu用户下正在进行的进程
$ ps -u neu
PID TTY          TIME CMD
16223 pts/3    00:08:44 java
25583 ?        00:11:10 redis-server


# 仅查看当前bash相关的进程
$ ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R   503   630   682  0  80   0 - 27024 -      pts/3    00:00:00 ps
4 S   503   682   681  0  80   0 - 27113 wait   pts/3    00:00:00 bash

# 无条件终止进程
$ kill -9 24270(pid,进程号)

# ww 参数的含义是:避免详细参数被截断
# 管道符'|'用来分隔两个命令,左边命令的输出会作为右面命令的输入
# 输出所有进程号|输出含有关键字'a'的进程|去除含有关键'b的进程'|截取输入行第9~15个字符(pid)|将前面命令的输出结果(pid)作为kill -9的参数,并执行
$ ps -efww | grep a | grep -v b | cut -c 9-15 | xargs kill -9
# grep命令用来筛选信息

# 在已知进程名(name)的前提下,交互式 Shell 获取进程 pid 有很多种方法,典型的通过 grep 获取 pid 的方法为(这里添加 -v grep是为了避免匹配到 grep 进程):
$ ps -ef | grep "name" | grep -v grep | awk '{print $2}'
# 或者不使用 grep(这里名称首字母加[]的目的是为了避免匹配到 awk 自身的进程):
$ ps -ef | awk '/[n]ame/{print $2}'
# 如果只使用 x 参数的话则 pid 应该位于第一位:
$ ps x | awk '/[n]ame/{print $1}'
# 注意 grep 是模糊匹配,如果想使用精确匹配,使用参数 -w
$ ps -ef | grep -w "test"

# 最简单的方法是使用 pgrep:
$ pgrep -f name
# 如果需要查找到 pid 之后 kill 掉该进程,还可以使用 pkill:
$ pkill -f name
# 如果是可执行程序的话,可以直接使用 pidof
$ pidof name

查看所有java进程的pid的命令

jdk1.5起提供jps来查看java进程的pid

用户类型和文件权限`

# 显示当前文件的详细信息 -a 参数表示显示隐藏文件(以.开头的文件就是隐藏文件)
$ ls -l <==> ll                ls -al <==> ll -a

# -r 逆序输出,-t 按修改时间排序,最新的排在最前面
$ ll -rt 

# 对于文件数量特别多的文件夹,ls 会卡住,原因是 ls 命令会将输出排序。为了排序,ls命令先将所有文件的名称读入内存。
# 当遇到一个非常大的目录时,它就在那里不断地读入文件名,并且内存占用越来越大,直到将所有文件一次性以字母数字顺序列出来。
# 可以通过下面的命令不排序直接显示文件
# -1 注意不是 -l,只显示文件名称
# -f 不排序强制输出
$ ls -1 -f

# 一个文件的详细信息如下
# 文件类型 各用户权限 用户名 用户所在组名 大小(字节) 最近修改时间 文件名
  - rwxr-xrwx.  1 root root   890461 Feb 22 10:27 smarket-spark.jar
  d rwxr-xrwx. 28 neu  neu      4096 Nov  8 09:38 spark-2.0.2
# linux针对文件有三种格式
  1)文件 用 - 来表示
  2)目录  用 d 来表示
  3)文件链接(快捷方式)用 l 来表示
# 每一类文件都会针对三类用户进行权限控制
  1)文件所有者 u
  2)文件同组者 g
  3)系统的其他用户 o
# 对于每一类用户的权限又分为三种
  1)可读 r ,权重是2的2次方 = 4
  2)可写 w ,权重是2的1次方 = 2
  3)可执行 x ,权重是2的0次方 = 1

# 改变文件所属用户和组  -R 代表递归更改文件夹内的所有文件
  chown -R zhangqiang:zhangqiang directory1
  # 只改变文件所属用户
  chown zhangqiang file.txt
  # 只改变文件所属组
  chgrp zhangqiang file.txt

# 改变文件权限 -R  代表递归更改文件夹内的所有文件
  1) chmod -R 755 directory2 # 通过修改权重来修改权限
  2) chmod  u-w|o+w ./file.txt # 通过删除或者添加用户的权限直接修改

一些简单好用的命令

# 查看用户历史命令行记录
$ history

# 查看当前文件夹完整路径
$ pwd

# 清除屏幕,但是向上滚动之后之前的命令行信息又出来了
$ clear
# 真正意义上的清除屏幕,但是稍微较慢,也可以解决命令乱行的问题
$ reset

# 查看当前文件夹下所有文件的大小
# -s 统计文件的总大小,不会显示文件夹中的子文件大小
# -h 适合人阅读的格式,将大小自动转换成单位k、m、g
$ du -sh * 
# 或者 
$ du -h ./
# 查看文件夹ci的大小
# -m 单位转换成 MB
$ du -sm ci

# 退出当前用户的命令
$ exit
# 切换到neu用户,并且进入neu用户的主目录,不需要输入密码
$ su - neu
# 切换到neu用户,并且进入上个用户当前正在使用的目录
$ su neu

# 给命令起一个别名
$ alias ll='ls -l'
# 查看系统已经设置的别名情况
$ alias -p
# 删除一个别名
$ unalias ll

Linux 网络设置

# 查看网络信息命令 (centos 7 deprecated),使用 ip 命令来管理网络
$ ifconfig == ipconfig(windows) 

# 查看网卡信息
$ ip address | ip addr | ip a

# 分配静态IP地址 (centos7) ifcfg-* (不一定是eth0) 
$ vi /etc/sysconfig/network-script/ifcfg-eth0

# MAC 地址
# 注意虚拟机上的系统默认不会配置这一项,可以通过 ip addr 找到 MAC 地址,不然会出现 
# Failed to start LSB: Bring up/down networking. 的错误
HWADDR=01:25:d2:01:c1:03
TYPE=Ethernet
# dhcp => static 
BOOTPROTO=static 
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=eth0
UUID=as7f302d-ab36-461a-821e-d26ccfd1ed71
# 开机启用本配置
ONBOOT=yes 
# 静态IP
IPADDR=192.168.10.101
# 默认网关
GATEWAY=192.168.10.1 
# 子网掩码
NETMASK=255.255.255.0 
# DNS 配置
DNS1=1.1.1.1 

# 查看本机公网IP
$ curl ifconfig.me

# 查看当前主机名
$ hostname

# 在root用户下 'hostname 主机名'  可以修改主机名,仅在当前生效,reboot之后就会还原
hostname zhangqiang
# 设置当前主机名,永久生效,将/etc/sysconfig/network 中的'HOSTNAME=主机名'
$ vi /etc/sysconfig/network 
# 或者通过修改/etc/hostname文件来设置主机名
$ vi /etc/hostname 将localhost.localdomain改为你想要的主机名字
# 重启机器
$ reboot


# 设置IP和主机名映射
$ vi /etc/hosts        
10.4.120.83 s12083

# 查看域名对应IP信息
$ nslookup www.baidu.com

# 配置代理 shell重启需要重新使用下面的命令
$ export http_proxy=account:\![email protected]:8080 # 注'!'在-bash中有特殊含义,需要加'\'转义字符

# windows
set http_proxy=http://proxy.domain.com:port
set http_proxy_user=
set http_proxy_pass=


# 网络检测命令 ping 命令
ping [options] [host|ip]
  #  [options]介绍
  # -c 请求次数 -i请求时间间隔 -s 请求包的大小 -t 设置TTL的值
  ping -c 5 -i 0.5 -s 1024 -t 255 www.baidu.com 


# 服务器端口连通检测
# 安装 
$ yum install nc | apt-get install netcat
# -z 设置 nc 监听守护进程,实际上并不会发送任何数据
# -v 详细模式
$ nc -zv <ip> <beginPort[-endPort]>
# 成功
Connection to 192.168.22.43 22 port [tcp/ssh] succeeded!
# 失败
nc: connect to 192.168.22.43 port 6380 (tcp) failed: Connection refused
# 也可以指定端口扫描的范围:
nc -zv 127.0.0.1 80-85 
# Windows 自带 telnet
$ telnet <ip> <port>
# 连接成功
Trying ::1...
Connected to localhost. #看到Connected就连接成功了
Escape character is '^]'.
SSH-2.0-OpenSSH_5.3
a
Protocol mismatch.
Connection closed by foreign host.
# 连接失败则直接提示连接被拒绝
Trying 10.0.250.3...
telnet: connect to address 10.0.250.3: Connection refused
# 如果远程主机开通了相应的端口,都会输出信息,如果没有开通相应的端口,则没有任何提示,需要CTRL+C断开。
$ curl <ip:port>
# 如果远程主机不存在端口则会一直提示连接主机。
$ wget <ip:port>
# 对于开启 sshd 的 Linux 服务器还可以使用 ssh 命令测试端口联通情况
# -v 开启 debug 模式
$ ssh -v -p <port> <[email protected]>

DNS 配置

# 配置 DNS Server
$ vim /etc/resolv.conf
nameserver 10.8.8.8
nameserver 10.8.8.9
nameserver 202.106.0.20
nameserver 202.106.196.115
nameserver 119.57.112.250
nameserver 119.57.112.254
nameserver 114.114.114.114
options timeout:1 attempts:2

# 刷新 DNS 缓存
$ sudo apt-get install nscd
$ sudo /etc/init.d/nscd restart

# 重启网络(Ubuntu)
$ sudo /etc/init.d/networking restart

Linux 系统监控

pidstat

从进程角度获取每个进程使用cpu、内存和磁盘等系统资源的统计信息

$ yum install -y sysstat
# 查看某进程的 cpu(-u)、memory(r)、disk(-d) 信息
# -p 指定 pid
# 以 2 秒为采样周期,输出 10 次统计信息
$ pidstat -urd -p 18936 2 10
09:32:27 AM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
09:32:27 AM     0     18936    1.66    0.31    0.00    1.97    21  java

09:32:27 AM   UID       PID  minflt/s  majflt/s     VSZ    RSS   %MEM  Command
09:32:27 AM     0     18936     48.32      0.00 41139636 35064140  26.62  java

09:32:27 AM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
09:32:27 AM     0     18936     43.40   1058.57      0.00  java

$ pidstat

netstat

netstat 是通过解析/proc/net/下的文件返回网络相关的信息

$ yum install -y net-tools
$ info netstat
       netstat  - Print network connections, routing tables, interface statis‐
       tics, masquerade connections, and multicast memberships
      
# 使用root用户才能看到全部信息
$ netstat [options]
   -a # Show both listening and non-listening sockets,LISTEN、ESTABLISHED、TIME_WAIT
   -l # --listening, Show only listening sockets.  (These are omitted by default.)
   -t # 列出 tcp 网络数据包的数据
   -u # 列出 udp 网络数据包的数据
   -n # Show numerical addresses instead of trying to determine symbolic host, port or user names.
   -p # Show the PID and name of the program to which each socket belongs.
   -r # 路由信息
 
# 每列的详细含义可以阅读 `man netstat` 的 OUTPUT 部分
# State:The state of the socket. 
# Since there are no states in raw mode and usually no states used in UDP, this column may be left blank. Normally this can be one of several values:
# - ESTABLISHED:The socket has an established connection.
# - SYN_SENT:The socket is actively attempting to establish a connection.
# - SYN_RECV:A connection request has been received from the network.
# - FIN_WAIT1:The socket is closed, and the connection is shutting down.
# - FIN_WAIT2:Connection is closed, and the socket is waiting for a shutdown from the remote end.
# - TIME_WAIT:The socket is waiting after close to handle packets still in the network.
# - CLOSE:The socket is not being used.
# - CLOSE_WAIT:The remote end has shut down, waiting for the socket to close.
# - LAST_ACK:The remote end has shut down, and the socket is closed. Waiting for acknowledgement.
# - LISTEN:The socket is listening for incoming connections.  Such sockets are not included in the output unless you specify the --listening (-l) or --all (-a) option.
# - CLOSING:Both sockets are shut down but we still don't have all our data sent.
# - UNKNOWN:The state of the socket is unknown.
$ sudo netstat -anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8181            0.0.0.0:*               LISTEN      1780/nginx: worker 
tcp        0      0 0.0.0.0:8181            0.0.0.0:*               LISTEN      1767/nginx: worker 
tcp        0      0 0.0.0.0:8181            0.0.0.0:*               LISTEN      1754/nginx: worker
...

# 例如:根据端口信息,产看进程号
$ netstat -anp | grep `port`

# 根据进程号,查看占用端口信息
$ netstat -anp | grep `pid`

# 查看路由表
# Destination: 目标 IP,后面的所有参数,如 Gateway、Genmask...都是针对前往这个 IP 的应该如何设置
# Gateway: 网关,如果需要前往 Destination IP,应该从哪个网关过去,这里有两种情况,即有内外网用不同网关的,也有内外网用相同网关的。
# Genmask: The netmask(子网掩码) for the destination net
# Flags: 标志位
# Refs: 可以简单的理解为重要性,相同的 IP,相同的网关,用这个重要性来区分使用哪个网卡
$ netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         gateway         0.0.0.0         UG        0 0          0 ens192
192.168.51.0    0.0.0.0         255.255.255.0   U         0 0          0 ens192

# 按 State 分组计算tcp连接数
$ netstat -a | awk '/^tcp/ {++SCount[$NF]};END {for(state in SCount) print state, SCount[state]}' 
LISTEN 208
ESTABLISHED 20
TIME_WAIT 50

ss

ss is used to dump socket statistics. It allows showing information similar to netstat. It can display more TCP and state informations than other tools.

# Print summary statistics. This option does not parse socket lists obtaining summary from various sources.
# It is useful when amount of sockets is so huge that parsing `/proc/net/tcp` is painful.
$ ss -s
Total: 1364 (kernel 0)
TCP:   862 (estab 20, closed 634, orphaned 0, synrecv 0, timewait 512/0), ports 0

Transport Total     IP        IPv6
*	        0         -         -        
RAW	      0         0         0        
UDP	      3         3         0        
TCP	      228       70        158      
INET	    231       73        158      
FRAG	    0         0         0

lsof

在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。

# lsof(list open files)是一个列出当前系统打开文件的工具。
$ lsof
# 在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。 
COMMAND    PID      USER   FD      TYPE     DEVICE     SIZE       NODE      NAME
init       1         root  cwd      DIR       3,3       1024       2         /
init       1         root  rtd      DIR       3,3       1024       2         /
init       1         root  txt      REG       3,3       38432      1763452  /sbin/init
init       1         root  mem      REG       3,3       106114     1091620  /lib/libdl-2.6.so
...
  • COMMAND:进程的名称
  • PID:进程标识符
  • USER:进程所有者
  • FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
  • TYPE:文件类型,如DIR、REG等
  • DEVICE:指定磁盘的名称
  • SIZE:文件的大小
  • NODE:索引节点(文件在磁盘上的标识)
  • NAME:打开文件的确切名称
# 命令格式
$ lsof [options] filename1 filename2 ...
# options
-a         # 表示其他参数都必须满足时才显示结果,相当于 and 连接符。
-c string  # 显示COMMAND列中包含指定字符的进程所有打开的文件
-u user    # 显示所属user进程打开的文件
-g gid     # 显示归属gid的进程情况
+d /DIR/   # 显示目录下被进程打开的文件
+D /DIR/   # 同上,递归搜索目录下的所有目录,时间相对较长
-d FD      # 显示指定文件描述符的进程
-n         # 不将 IP 转换为 hostname,即已 IP 形式展现
-r [time]  # 控制lsof不断重复执行,直到收到中断信号,time 单位秒,缺省是15s刷新。
+r [time]  # lsof会一直执行,直到没有档案被显示。
-p pid     # 显示指定进程打开的文件
-i         # 用以显示符合条件的进程情况
lsof -i[4|6][protocol][@[hostname|hostaddr]][:[service|port]]
            46 --> 显示类型是 IPv4 or IPv6的,默认都显示。
            protocol --> TCP or UDP,默认都显示。
            hostname --> Internet host name
            hostaddr --> IPv4地址
            service --> /etc/service中的 service name (可以不只一个)
            port --> 端口号 (可以不只一个)
# 例如显示IPV4、TCP、s12179的22端口的信息。
$ lsof -i4tcp@s12179:22
# 显示结果如下
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
sshd     3504 root    3r  IPv4 1507618      0t0  TCP s12179:ssh->10.4.124.98:54278 (ESTABLISHED)
sshd    30532 root    3u  IPv4 1024660      0t0  TCP s12179:ssh->10.4.126.51:56584 (ESTABLISHED)

# 根据端口号查看进程号
$ lsof -i:port 
# 或者
$ lsof -i | grep port

# 根据进程号查看端口号
# -P 端口以数字形式展示,而不是端口名称
$ lsof -n -P -i TCP | grep pid

# -s 配合 -i 使用,用于过滤输出
$ lsof -n -P -i TCP -s TCP:LISTEN | grep pid

# 查看某进程打开 TCP 连接情况
$ lsof -p 23809 | grep TCP

通过 /proc 查看打开文件数最多的前20个进程

  • what is proc
    for pid in `ps -eF | awk '{ print $2 }'`
    do 
    echo `ls /proc/$pid/fd 2> /dev/null | wc -l`  $pid  `cat /proc/$pid/cmdline 2> /dev/null`
    done | sort -n -r | head -n 20
    

nmon

奈吉尔性能监视器,用来检测系统的所有资源:CPU、内存、磁盘使用率、网络上的进程、NFS、内核等等。这个工具有两个模式: 在线模式捕捉模式。在线模式适用于实时监控,捕捉模式用于存储输出为 CSV 文件,然后通过nmon_analyzer工具产生数据文件与图形化结果。

# 这个得安装
$ yum install -y nmon

查看linux系统版本

# 显示linux系统的所有信息,注:适用所有linux发行版本
$ lsb_release -a

# 查看发行版centos版本信息
$ cat /etc/redhat-release
$ cat /etc/issue

# 查看系统内核版本 
$ cat /proc/version 
$ uname -a 
$ uname -r # 只显示系统内核版本。显示结果:2.6.32-642.el6.x86_64

内存监控

查看内存使用情况

$ free -m # 以MB为单位显示
$ free -g # 以GB为单位显示
              total        used        free      shared  buff/cache   available
Mem:            125          66           0           0          57          57
Swap:             3           0           3

# 内存并不是只有使用(used)和空闲(free)两个状态,还有缓冲(buffer)和缓存(cache),从字面义上这两个都是缓存,
# 但是缓存的数据不同。

# buffer 一般都不太大,在通用的 Linux 系统中一般为几十到几百MB,它是用来存储磁盘块设备的元数据的,比如哪些
# 块属于哪些文件,文件的权限目录信息等。

# cache 一般很大(GB),因为它用来存储读写文件的页,当对一个文件进行读时,会取磁盘文件页,放到内存,然后从内存
# 中进行读取;而写文件的时候,会先将数据写到缓存中,并将相关的页面标记为`dirty`。cache 会随着读写磁盘的多少
# 自动的增加或减少,这也取决于物理内存是否够用,如果物理内存不够用了,操作系统会适当的减少 buffer/cache 以
# 保证应用有足够的内存使用。

查看进程中各个模块占用内存情况

显示比较底层的进程模块所占用内存的信息,并且可以打印内存的起止地址等,可以用于定位深层次的JVM或者操作系统的内存问题

$ pmap -d 15450
15450:   /usr/java/jdk1.8.0_191-amd64/jre/bin/java -cp /root/spark-2.4.2-bin-hadoop2.7/conf/:/root/spark-2.4.2-bin-hadoop2.7/jars/* -Xmx1g org.apache.spark.deploy.worker.Worker --webui-port 8081 spark://rockfs:7077
Address           Kbytes Mode  Offset           Device    Mapping
0000000000400000       4 r-x-- 0000000000000000 0fd:00000 java
0000000000600000       4 r---- 0000000000000000 0fd:00000 java
0000000000601000       4 rw--- 0000000000001000 0fd:00000 java
0000000002446000     132 rw--- 0000000000000000 000:00000   [ anon ]
00000000c0000000  469504 rw--- 0000000000000000 000:00000   [ anon ]
00000000dca80000  229888 ----- 0000000000000000 000:00000   [ anon ]
00000000eab00000  327168 rw--- 0000000000000000 000:00000   [ anon ]
00000000fea80000   22016 ----- 0000000000000000 000:00000   [ anon ]
0000000100000000    4480 rw--- 0000000000000000 000:00000   [ anon ]
0000000100460000 1044096 ----- 0000000000000000 000:00000   [ anon ]
...
00007fd4fc000000       4 r--s- 0000000000000000 0fd:00000 kubernetes-model-common-4.1.2.jar
00007fd4fc001000       4 r--s- 000000000000b000 0fd:00000 snappy-0.2.jar
00007fd4fc002000      44 r--s- 00000000000b0000 0fd:00000 jtransforms-2.4.0.jar
00007fd4fc00d000       4 r--s- 000000000000a000 0fd:00000 apacheds-i18n-2.0.0-M15.jar
00007fd4fc00e000       4 r--s- 0000000000009000 0fd:00000 hadoop-annotations-2.7.3.jar
00007fd4fc00f000       8 r--s- 000000000000e000 0fd:00000 hadoop-mapreduce-client-jobclient-2.7.3.jar
00007fd4fc011000      20 r--s- 0000000000027000 0fd:00000 hk2-api-2.4.0-b34.jar
00007fd4fc016000       8 r--s- 0000000000004000 0fd:00000 stax-api-1.0-2.jar
00007fd4fc018000      12 r--s- 000000000000f000 0fd:00000 spark-network-shuffle_2.12-2.4.2.jar
...
mapped: 11446060K    writeable/private: 1390808K    shared: 13876K

磁盘监控

查看磁盘情况

$ fdisk -l
Disk /dev/vda: 42.9 GB, 42949672960 bytes, 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b2d99

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *        2048    83875364    41936658+  83  Linux

Disk /dev/vdb: 536.9 GB, 536870912000 bytes, 1048576000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

# 可以看到 /dev/vdb 磁盘没有格式化并挂载

# 格式化为 ext4
$ mkfs.ext4 /dev/vdb
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
32768000 inodes, 131072000 blocks
6553600 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2279604224
4000 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 
        102400000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

# 修改开启挂载项,将磁盘挂载到 /data 目录下,注意需要提前将目录建好
$ mkdir /data
$ vim /etc/fstab
/dev/vdb /data ext4 defaults 0  0

# 检测 /etc/fstab 文件自动挂载
$ mount -a

查看磁盘使用情况

$ df -lh
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root  2.7T  473G  2.2T  18% /
devtmpfs                  63G     0   63G   0% /dev
tmpfs                     63G     0   63G   0% /dev/shm
tmpfs                     63G   19M   63G   1% /run
tmpfs                     63G     0   63G   0% /sys/fs/cgroup
/dev/sda2               1014M  137M  878M  14% /boot
/dev/sda1                200M   12M  189M   6% /boot/efi
tmpfs                     13G     0   13G   0% /run/user/0

# 查看Inode使用情况
$ df -i
Filesystem       Inodes IUsed    IFree IUse% Mounted on
/dev/vda1      26213824 81171 26132653    1% /
devtmpfs        4095237   361  4094876    1% /dev
tmpfs           4097693     1  4097692    1% /dev/shm
tmpfs           4097693   453  4097240    1% /run
tmpfs           4097693    16  4097677    1% /sys/fs/cgroup
tmpfs           4097693     1  4097692    1% /run/user/0
tmpfs           4097693     1  4097692    1% /run/user/109910
/dev/vdb1      65536000  1664 65534336    1% /data
tmpfs           4097693     1  4097692    1% /run/user/109908

# 删除文件后,空间不释放
# 查看占用文件的 PID
$ lsof | grep deleted
zk-sessio  6350 12754       root    2w      REG              253,1 40460951552   67720033 /home/eagle/kafka-eagle-web-2.0.1/kms/logs/catalina.out (deleted)
zk-sessio  6350 12754       root    8w      REG              253,1        5595   68975530 /home/eagle/kafka-eagle-web-2.0.1/kms/logs/catalina.2020-11-21.log (deleted)
zk-sessio  6350 12754       root    9w      REG              253,1         416   67720044 /home/eagle/kafka-eagle-web-2.0.1/kms/logs/localhost.2020-09-29.log (deleted)
zk-sessio  6350 12754       root   10w      REG              253,1           0   67720322 /home/eagle/kafka-eagle-web-2.0.1/kms/logs/manager.2020-09-29.log (deleted)
zk-sessio  6350 12754       root   11w      REG              253,1           0   67726356 /home/eagle/
...
# 终止进程
$ kill -9 6350

磁盘 Direct IO 顺序写读写性能测试

# 测试写入20G数据,数据量越大,测试值应该更精确
$ sync;/usr/bin/time -p bash -c "(dd if=/dev/mapper/centos-root of=test.dd bs=1M count=20000;sync)"
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB) copied, 13.852 s, 1.5 GB/s
real 25.89
user 0.01
sys 17.03

# real write speed: 21GB / 25.89s = 0.811 GB/s

# sync 刷新文件系统的缓冲区,把内存中的数据缓冲写入到磁盘中。先执行下sync命令,是为了减少对后面测试的影响。也可以使用 echo 3 > /proc/sys/vm/drop_caches 来清除缓存。
# time 命令用来测试命令的执行时间,shell内建还有一个time命令,我们这里使用全路径来指定使用的是非内建命令。-p 选项设置时间的输出格式为POSIX缺省时间格式,单位是秒
# bash 命令 -c 选项的作用是将后面的字符串参数当作bash脚本来执行,看起来有些画蛇添足,好像直接执行也是可行的,其实不然,因为后面字符串中包含了两条命令行,而time命令需要统计这两条命令行的执行时间。
# 小括号的意思是另起一个子进程来执行括号中的脚本
# if=FILE read from FILE instead of stdin
# of=FILE write to FILE instead of stdout
# bs=BYTES read and write up to BYTES bytes at a time,默认 512KB
# count=N copy only N input blocks

# 读取20GB数据
$ echo 3 >/proc/sys/vm/drop_caches;time -p dd if=test.dd of=/dev/null bs=1M
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB) copied, 47.3728 s, 443 MB/s
real 47.38
user 0.01
sys 8.89

# real read speed: 21GB / 47.38s = 0.443 GB/s,读取不需要 sync,因此基本没有误差

# 或者使用hdparm,需要安装,且用 root 用户执行,测试 3 秒能读取多少数据
$ hdparm -t --direct /dev/mapper/centos-root

/dev/mapper/centos-root:
 Timing O_DIRECT disk reads: 2994 MB in  3.00 seconds = 997.47 MB/sec

查看磁盘实时 IO 信息

$ yum install -y sysstat
# 从磁盘设备 sda 角度统计 io
# -x 输出扩展信息,interval 5 
$ iostat -x 5
Linux 3.10.0-957.el7.x86_64 (rockfs)    05/31/2019      _x86_64_        (40 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           2.11    0.00    0.21    0.05    0.00   97.64

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.04     0.22   18.94   30.77  3169.87  7600.27   433.25     0.65   13.13    0.95   20.63   0.35   1.73
dm-0              0.00     0.00   18.94   30.90  3169.64  7599.91   432.21     0.66   13.17    0.95   20.66   0.35   1.73
dm-1              0.00     0.00    0.05    0.09     0.20     0.36     8.02     0.00   31.43    1.20   48.33   0.09   0.00
...
# rrqm/s、wrqm/s: The number of read/write requests merged per second that were queued to the device
# r/s、w/s: 指的 IOPS(Input/Output Operations Per Second) 每秒读写次数,after merge
# rkB/s、wkB/s: 指的是数据存取数据
# await 指的是 IO 平均等待时间,一般都在 10ms 左右,越大说明磁盘负载越大越繁忙
# $util 设备带宽利用率,越接近 100% 越饱和

# 从进程角度获取每个进程使用cpu、内存和磁盘等系统资源的统计信息
$ pidstat

$ yum install -y iotop
$ iotop
Total DISK READ :       0.00 B/s | Total DISK WRITE :       0.00 B/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                                                                                                         
20698 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/16:2]
    1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % systemd --switched-root --system --deserialize 22
    2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
    3 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
    5 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/0:0H]
    6 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/u80:0]

# iotop 命令的快捷键
1、左右箭头改变排序方式,默认是按IO排序
2、r 键是反向排序
3、o 键是只显示有IO输出的进程
4、q 是退出

iozone

# 官网 http://www.iozone.org/
# 下载地址 http://www.iozone.org/src/current/
$ wget http://www.iozone.org/src/current/iozone-3-487.src.rpm
$ rpm -ivh iozone-3-487.src.rpm
$ cd ~/rpmbuild/SOURCES
$ ll 
-rw-r--r--. 1 root root 1873920 Jan 18 15:26 iozone3_487.tar
# 或者直接下载
$ wget http://www.iozone.org/src/current/iozone3_487.tar
$ tar -xvf iozone3_487.tar
# 查看帮助文档
$ cd iozone3_487/docs && man ./iozone.1
# 编译
$ cd iozone3_487/src/current
# 查看编译参数
$ make
# 根据操作系统架构选择不同的参数
$ uname -m
x86_64
$ make linux-AMD64
$ ll -t 
-rwxr-xr-x. 1 root root  18616 Jun  2 23:45 pit_server
-rwxr-xr-x. 1 root root  44304 Jun  2 23:45 fileop
-rwxr-xr-x. 1 root root 359368 Jun  2 23:45 iozone
...
# 查看使用帮助
$ ./pit_server -h
$ ./fileop -h
$ ./iozone -h

$ ./iozone -Raz -b lab-2G.xls -g 2G |tee 2G.log

# -i 比如测试写: -i 0,测试读和写: -i 0 -i 1。 
  -R 产生excel格式的输出(仅显示在屏幕上,不会产生excel文件)
  -b 产生excel格式的文件
  -g 最大测试文件大小 for auto mode
  -t 并发数
  -s 测试文件的大小,支持-k -m -g
  -q 块大小 for auto mode
  -r 文件块大小。 
  -a 在希望的文件系统上测试,不过只有-a的话会进行全面测试,要花费很长时间,最好用-i指定测试范围。 
  -n 指定最小测试文件大小。 
  -f 指定测试文件。 
  -C 显示每个节点的吞吐量。 
  -c 测试包括文件的关闭时间 
  
# 附: -i 参数
  0=write/rewrite
  1=read/re-read
  2=random-read/write
  3=Read-backwards
  4=Re-write-record
  5=stride-read
  6=fwrite/re-fwrite
  7=fread/Re-fread,
  8=random mix
  9=pwrite/Re-pwrite
  10=pread/Re-pread
  11=pwritev/Re-pwritev,
  12=preadv/Re-preadv

python tqdm

$ pip install tqdm
$ vim iospeed.py
from tqdm import tqdm
import os
import time

# 写性能测试
file_size = 2*1000**3
trunk_size = 1000**2

data = os.urandom(trunk_size)
with tqdm(unit='B', unit_scale=True, total=file_size, smoothing=0) as pbar:
    with open('tmp', mode='wb', buffering=trunk_size) as f:
        for i in range(file_size//trunk_size):
            f.write(data)
            pbar.update(len(data))
        os.system('sync; echo 1 > /proc/sys/vm/drop_caches')

# 读性能测试
trunk_size = 1000**2
with open('tmp', mode='rb', buffering=trunk_size) as f:
    with tqdm(unit='B', unit_scale=True, total=os.fstat(f.fileno()).st_size,
              smoothing=0) as pbar:
        while True:
            d = f.read(trunk_size)
            pbar.update(len(d))
            if len(d) == 0:
                break

os.remove('tmp')

$ python iospeed.py

CPU 监控

查看 cpu 信息

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             2
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 13
Model name:            QEMU Virtual CPU version 2.5+
Stepping:              3
CPU MHz:               2099.998
BogoMIPS:              4199.99
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
L3 cache:              16384K
NUMA node0 CPU(s):     0-7
Flags:                 fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 ht syscall nx lm rep_good nopl xtopology pni cx16 x2apic hypervisor lahf_lm

top

# 服务器包含若干个 cpu,一个 cpu 包含若干物理核,一个物理核又包含若干逻辑核。
# 总核数 = 物理 cpu 个数 * 每个物理 cpu 的核数
# 超线程数 = 每个 cpu 线程数(siblings)  / 每个 cpu 物理核数(cpu cores),大于 1 表示启用了超线程技术,可以在逻辑上分几倍数量的 cpu core 出来。
# 总逻辑 cpu 数 = 物理 cpu 个数(physical cpus) * 每个物理 cpu 核数(cpu cores) * 超线程数 = 物理 cpu 个数(physical cpus) * 每个 cpu 线程数(siblings)

$ cat /proc/cpuinfo
# 物理 cpu 个数    
$ cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
# 每个 cpu 物理核数
$ cat /proc/cpuinfo | grep "cpu cores" | uniq
# 每个 cpu 线程数  
$ cat /proc/cpuinfo | grep "siblings" | uniq
# 总 cpu 逻辑核数
$ cat /proc/cpuinfo | grep -c "processor" 
# 或者
$ grep -c 'model name' /proc/cpuinfo
# 超线程指物理内核+逻辑内核,芯片上只存在一个物理内核,但是这个物理内核可以模拟出一个逻辑内核,于是系统信息就显示了两个内核,一真一假(一个核可以当两个用)。

# 查看 cpu 型号
$ cat /proc/cpuinfo|grep name|cut -f2 -d:|uniq -c


# 查看cpu负载情况,一秒一刷新
$ top -d 1
top - 13:42:52 up 39 days, 10 min,  3 users,  load average: 0.19, 0.16, 0.14
Tasks: 224 total,   1 running, 223 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.3 us,  0.3 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 32781820 total,   290688 free, 15894116 used, 16597016 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 16378768 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                         
 7755 hbase     20   0 3029804 423140   7464 S   1.0  1.3  76:21.68 java
.
.
.                                                                                          

下面说一下每一行的参数都是啥意思

  • 第一行 top -
字符 含义
13:42:52 当前系统时间
up 39 days, 10 min 系统已运行时间
3 users 当前有3个用户在线(包含系统用户)
load average: 0.19, 0.16, 0.14 分别为1分钟、5分钟、15分钟前到现在系统负载的平均值(即任务队列的平均长度)

判断 load average 是否正常是取决于你的系统拥有多少核,如果你有2个CPU,每个CPU有4个核,那么这个数小于8.0就都是正常的

  • 第二行 Tasks:
字符 含义
224 total total 总进程数
1 running 正在运行的进程数
223 sleeping 正在睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数
  • 第三行 %Cpu(s):
字符 含义
1.3 us 用户进程占用 cpu 百分率
0.3 sy 系统进程占用 cpu 百分率
0.0 ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.3 id cpu 空闲率
0.0 wa 等待IO的CPU时间百分比
0.0 hi 硬中断(Hardware IRQ)占用CPU的百分比
0.0 si 软中断(Software Interrupts)占用CPU的百分比
0.0 st  
  • 第四行 KiB Mem:
字符 含义
32781820 total 总内存
290688 free 内存空闲量
15894116 used 实际使用内存
16597016 buff/cache 缓存

总内存 - 实际使用内存 = 内存空闲量 + 缓存

  • 第五行 KiB Swap:
字符 含义
0 total 交换区总量
0 free 交换区空闲量
0 used 交换区使用量
16378768 avail Mem 还可以使用的交换区容量
  • 第六行
字符 含义
PID 进程号
USER 进程创建用户
PR 进程优先级
NI nice值。越小优先级越高,最小-20,最大20(用户设置最大19)
VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
SHR 共享内存大小,单位kb
S 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
%CPU 进程占用cpu百分比
%MEM 进程占用内存百分比
TIME+ 进程运行时间
COMMAND 进程名称

进入 top 后还可以使用的命令

  • 1: 在多核 cpu 和总 cpu(s) 之间切换,如查看多核负载情况

进入top后,按1可以

top - 13:44:25 up 39 days, 12 min,  3 users,  load average: 0.08, 0.14, 0.14
Tasks: 223 total,   1 running, 222 sleeping,   0 stopped,   0 zombie
%Cpu0  :  2.0 us,  0.0 sy,  0.0 ni, 98.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.0 us,  0.0 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.0 hi,  1.0 si,  0.0 st
%Cpu2  : 52.5 us,  3.0 sy,  0.0 ni, 44.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  7.0 us,  0.0 sy,  0.0 ni, 93.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  :  9.0 us,  1.0 sy,  0.0 ni, 90.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  :  3.0 us,  1.0 sy,  0.0 ni, 96.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
.
.
.
  • P: 以占据CPU百分比排序
  • M: 以占据内存百分比排序
  • T: 以累积占用CPU时间排序
  • q: 退出 top 查看页面
  • s: 按下 s 键,然后按下数字,即可修改刷新时间间隔为你输入的数字,单位为秒
  • k: 终止指定的进程。按下k键,再输入要杀死的进程的pid,按enter键(选择信号类型,以数字标示,默认15为杀死)本步可省略按enter键(常用为-9)

其他常用的参数

# -b: batch mode,在把输出写到文件的时候很有用,在 batch mode 下 top 不会接收 input 并且会
#     一直运行直到 -n 指定的次数或者被kill掉
# -p: 指定 pid
$ top -d 0.5 -b -p 1254 > top.log &

vmstat

显示关于内核线程、虚拟内存、磁盘 IO、线程和 CPU 占用率的统计信息

$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  40448 96350840  0   21916900  0    0    80   189    0    0  2  0 98  0  0

FIELD DESCRIPTION FOR VM MODE
   Procs
       r: The number of runnable processes (running or waiting for run time).
       b: The number of processes in uninterruptible sleep.

   Memory
       swpd: the amount of virtual memory used.
       free: the amount of idle memory.
       buff: the amount of memory used as buffers.
       # buff 是 I/O 系统存储的磁盘块文件的元数据的统计信息
       cache: the amount of memory used as cache.
       # cache 是操作系统用来缓存磁盘数据的缓冲区,操作系统会自动调解这个参数,在内存紧张的时候会减少 cache 占用的内存空间以保证其他进程可用
       inact: the amount of inactive memory.  (-a option)
       active: the amount of active memory.  (-a option)

   Swap
       si: Amount of memory swapped in from disk (/s).
       so: Amount of memory swapped to disk (/s).
       # si、so 较大说明系统频繁使用交换区(swap),可能是因为内存不够用造成的

   IO
       bi: Blocks received from a block device (blocks/s).
       bo: Blocks sent to a block device (blocks/s).
       # bi、bo 代表I/O 活动,根据其大小可以知道磁盘的负载情况
       
   System
       in: The number of interrupts per second, including the clock.
       cs: The number of context switches per second.
       # cs 表示线程环境的切换次数,该数值太大表明线程的同步机制有问题
   
   CPU
       These are percentages of total CPU time.
       us: Time spent running non-kernel code.  (user time, including nice time)
       sy: Time spent running kernel code.  (system time)
       id: Time spent idle.  Prior to Linux 2.5.41, this includes IO-wait time.
       wa: Time spent waiting for IO.  Prior to Linux 2.5.41, included in idle.
       st: Time stolen from a virtual machine.  Prior to Linux 2.6.11, unknown.

mpstat

用于实时监控 CPU 的一些统计信息,这些统计信息实际存在/proc/stat文件中,可以查看多核心 CPU 的平均使用信息,也可以查看某个特定的 CPU 信息

$ mpstat -P ALL
Linux 3.10.0-957.el7.x86_64 (rockfs)    05/31/2019      _x86_64_        (40 CPU)

08:30:10 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
08:30:10 AM  all    2.09    0.00    0.20    0.05    0.00    0.00    0.00    0.00    0.00   97.66
08:30:10 AM    0    2.40    0.00    0.38    0.05    0.00    0.00    0.00    0.00    0.00   97.17
08:30:10 AM    1    2.00    0.00    0.36    0.05    0.00    0.00    0.00    0.00    0.00   97.59
08:30:10 AM    2    1.86    0.00    0.29    0.04    0.00    0.00    0.00    0.00    0.00   97.81
08:30:10 AM    3    1.78    0.00    0.25    0.04    0.00    0.00    0.00    0.00    0.00   97.93
08:30:10 AM    4    1.90    0.00    0.31    0.04    0.00    0.00    0.00    0.00    0.00   97.75
08:30:10 AM    5    2.28    0.00    0.37    0.06    0.00    0.00    0.00    0.00    0.00   97.30
08:30:10 AM    6    2.55    0.00    0.33    0.08    0.00    0.01    0.00    0.00    0.00   97.03
08:30:10 AM    7    2.12    0.00    0.42    0.03    0.00    0.00    0.00    0.00    0.00   97.42
08:30:10 AM    8    2.07    0.00    0.42    0.03    0.00    0.00    0.00    0.00    0.00   97.47
08:30:10 AM    9    2.29    0.00    0.38    0.05    0.00    0.01    0.00    0.00    0.00   97.27
08:30:10 AM   10    2.89    0.00    0.53    0.14    0.00    0.00    0.00    0.00    0.00   96.44
08:30:10 AM   11    2.47    0.00    0.40    0.10    0.00    0.00    0.00    0.00    0.00   97.03
08:30:10 AM   12    2.53    0.00    0.35    0.13    0.00    0.00    0.00    0.00    0.00   96.99
08:30:10 AM   13    2.30    0.00    0.28    0.11    0.00    0.00    0.00    0.00    0.00   97.31
08:30:10 AM   14    2.26    0.00    0.24    0.11    0.00    0.00    0.00    0.00    0.00   97.39
08:30:10 AM   15    2.19    0.00    0.21    0.10    0.00    0.00    0.00    0.00    0.00   97.50
08:30:10 AM   16    2.16    0.00    0.20    0.10    0.00    0.00    0.00    0.00    0.00   97.54
08:30:10 AM   17    2.14    0.00    0.19    0.09    0.00    0.00    0.00    0.00    0.00   97.58
08:30:10 AM   18    2.15    0.00    0.18    0.09    0.00    0.00    0.00    0.00    0.00   97.58
08:30:10 AM   19    2.17    0.00    0.18    0.09    0.00    0.00    0.00    0.00    0.00   97.57
08:30:10 AM   20    1.92    0.00    0.11    0.03    0.00    0.00    0.00    0.00    0.00   97.94
08:30:10 AM   21    1.93    0.00    0.11    0.03    0.00    0.00    0.00    0.00    0.00   97.93
08:30:10 AM   22    1.99    0.00    0.12    0.01    0.00    0.01    0.00    0.00    0.00   97.87
08:30:10 AM   23    2.00    0.00    0.16    0.02    0.00    0.00    0.00    0.00    0.00   97.82
08:30:10 AM   24    1.91    0.00    0.10    0.02    0.00    0.00    0.00    0.00    0.00   97.96
08:30:10 AM   25    1.97    0.00    0.11    0.03    0.00    0.00    0.00    0.00    0.00   97.89
08:30:10 AM   26    1.97    0.00    0.10    0.02    0.00    0.00    0.00    0.00    0.00   97.91
08:30:10 AM   27    1.88    0.00    0.10    0.03    0.00    0.00    0.00    0.00    0.00   97.99
08:30:10 AM   28    1.94    0.00    0.12    0.03    0.00    0.00    0.00    0.00    0.00   97.91
08:30:10 AM   29    2.62    0.00    0.17    0.07    0.00    0.00    0.00    0.00    0.00   97.14
08:30:10 AM   30    1.87    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.04
08:30:10 AM   31    1.90    0.00    0.07    0.02    0.00    0.00    0.00    0.00    0.00   98.01
08:30:10 AM   32    2.01    0.00    0.07    0.02    0.00    0.00    0.00    0.00    0.00   97.90
08:30:10 AM   33    1.89    0.00    0.07    0.02    0.00    0.00    0.00    0.00    0.00   98.02
08:30:10 AM   34    1.89    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.03
08:30:10 AM   35    1.86    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.06
08:30:10 AM   36    1.87    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.05
08:30:10 AM   37    1.86    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.05
08:30:10 AM   38    1.88    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.04
08:30:10 AM   39    1.86    0.00    0.06    0.02    0.00    0.00    0.00    0.00    0.00   98.07

CPU
     Processor number. The keyword all indicates that statistics are calculated as averages among all processors.

%usr
     Show the percentage of CPU utilization that occurred while executing at the user level (application).

%nice
     Show the percentage of CPU utilization that occurred while executing at the user level with nice priority.

%sys
     Show the percentage of CPU utilization that occurred while executing at the system level (kernel). Note that this does not include time spent servicing hardware and software interrupts.

%iowait
     Show the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request.

%irq
     Show the percentage of time spent by the CPU or CPUs to service hardware interrupts.

%soft
     Show the percentage of time spent by the CPU or CPUs to service software interrupts.

%steal
     Show the percentage of time spent in involuntary wait by the virtual CPU or CPUs while the hypervisor was servicing another virtual processor.

%guest
     Show the percentage of time spent by the CPU or CPUs to run a virtual processor.

%gnice
     Show the percentage of time spent by the CPU or CPUs to run a niced guest.

%idle
     Show the percentage of time that the CPU or CPUs were idle and the system did not have an outstanding disk I/O request.

硬盘接口

机械硬盘的接口有很多,不过最主流的接口就是SATA(Serial ATA)接口,另一个就是IDE接口,不过是上一代的接口快被淘汰了。SATA接口仅用四支针脚就能完成所有的工作,分别用于连接电缆、连接地线、发送数据和接收数据,同时这样的架构还能降低系统能耗和减小系统复杂性。

版本 带宽 实际速度
SATA 1.0 1.5Gb/s 150MB/s
SATA 2.0 3Gb/s 300MB/s
SATA 3.0 6Gb/s 600MB/s

其中带宽中Gb/s=8*GB/sb代表bitB代表Byte

对于固态硬盘,一般有这么几种接口SATA 3.0PCI-EM.2接口。在传统SATA硬盘中,当我们进行数据操作时,数据会先从硬盘读取到内存,再将数据提取至CPU内部进行计算,计算后写入内存,再存储至硬盘中。PCI-E就不一样了,数据直接通过总线与CPU直连,接近最大的传输速度,最大的数据量,省去了内存调用硬盘的过程。

目前主流的SATA 3.0通道的最大传输速度为6Gbps,实际速度最大为600MB/sSATA通道已经无法满足固态硬盘日益增长的读写速度,所以PCI-E固态硬盘应运而生。只是,出于体积、兼容性和制造成本的限制,再加上会占用主板接口和总线,所以它注定无法大面积普及,目前,市面上的PCI-E接口固态硬盘并不多,对于对速度要求比较苛刻。因为PCI-E会占用总线通道,入门以及中端平台CPU通道数较少,都不太适合添加PCI-E固态硬盘,只有Z270,或者X99这样的旗舰级平台,才能充分发挥PCI-E固态硬盘的性能。

M.2接口未来将会一统江湖,M.2最初叫做NGFF,全名是Next Generation Form Factor。从目前市面上的固态硬盘来看,M.2接口固态硬盘主要有两种版本,分别为Socket2Socket3版本。

  • Socket2版本M.2固态硬盘金手指通常表现有两个缺口,能够走SATA通道和PCI-E X2通道,在速度上,走SATA通道基本为500MB/s左右,走PCI-E X2通道速度基本为1000MB/s左右.
  • Socket3版本M.2固态硬盘专为高性能打造,通过金手指表现为有一个缺口,走PCI-E X4通道,速度一般可以达到2000MB/s以上,而且,现在的Socket版本M.2固态硬盘一般都支持NVME协议,速度得到了进一步提升,巅峰速度能够达到4000MB/s左右,三星顶级固态硬盘NVMe 960系列就是用的这种接口。

所以,如果你的固态硬盘是M.2接口的,并不一定就很快。因为这个接口同时支持SATAPCI-E两个通道,速度是不是快取决于接口采用的是哪个通道。

防火墙设置

# 查看防火墙状态
$ service iptables status || /etc/init.d/iptables status
# 临时关闭放火墙(即时生效,重启后失效 )
$ service iptables stop || /etc/init.d/iptables stop
# 临时开启防火墙(即时生效,重启后失效 )
$ service iptables start || /etc/init.d/iptables start
# 永久关闭防火墙(重启生效)
$ chkconfig iptables off 
# 永久开启防火墙(重启生效)
$ chkconfig iptables on 
# 重新启动防火墙
$ service iptables restart || /etc/init.d/iptables restart
# 防火墙开放端口
$ vim /etc/sysconfig/iptables
  # 可以看到防火墙默认是开放了22端口,想开放别的端口就添加一条一样的
  # 把 --dport 置为你想开放的端口就好了
  *filter
  :INPUT ACCEPT [0:0]
  :FORWARD ACCEPT [0:0]
  :OUTPUT ACCEPT [0:0]
  -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  -A INPUT -p icmp -j ACCEPT
  -A INPUT -i lo -j ACCEPT
  # 默认开放的端口号 tcp 端口 22
  -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
  -A INPUT -j REJECT --reject-with icmp-host-prohibited
  -A FORWARD -j REJECT --reject-with icmp-host-prohibited
  COMMIT
  # 重启防火墙
$ service iptables restart

# 防火墙 firewalld
# 开放端口
$ firewall-cmd --zone=public --add-port=1903/tcp --permanent
# 生效
$ firewall-cmd --reload

软件安装

rpm

安装软件是root的工作,所以需要root权限

# 安装
$ rpm -ivh jdk-8u111-linux-x64.rpm
-i(install)
-v(显示详细的安装信息画面)
-h(以信息栏显示安装进度)

# 后面可以接多个rpm文件同时安装,以空格分隔,也可以用 *.rpm 表示
$ rpm -ivh jdk-8u111-linux-x64.rpm *.rpm

# 从网络上安装
$ rpm -ivh http://website.name/path/pkname.rpm

# 查看已经安装的所有软件包
$ rpm -qa

# 删除已安装软件包
$ rpm -e vsftpd-2.0.1-2mdk.x86_64

# 强制删除 yum 安装的有依赖的软件包
$ rpm -e --nodeps vsftpd-2.0.1-2mdk.x86_64

yum 源配置

yum (Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中shell前端软件包管理器,基于RPM包管理,能够从指定的服务器自动下载RPM包并安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。

yum源所在路径地址 /etc/yum.repos.d,将163的yum源地址配置文件Rhel-Base-163.repo放入 /etc/yum.repos.d文件夹中即可。CentOS 163 yum源下载地址

# 命令形式一般是:yum [options][command][package...], 其中[options]是可选的,参数包括
   -h(帮助)
   -y(当安装过程提示选择全部为"yes"-q(不显示安装的过程)等
# [command]为所要进行的操作 如:install | update | remove
# [package...]是操作的对象 如:gcc

# 清除yum源的所有缓存
$ yum clean all

# makecache就是把服务器的包信息下载到本地电脑缓存起来,不用上网检索就能查找软件信息
# 主要配合 yum -C search subversion(从缓存中查找)使用,速度明显比 yum search subversion快
$ yum makecache

本地 yum 源 server 配置

# 1、清除原 yum 源缓存 
$ yum clean all

# 2、将操作系统的镜像文件 `CentOS-7-x86_64-DVD-1611.iso` 上传到服务器

# 3、创建挂载目录
$ mkdir /media/CentOS-7-x86_64-DVD-1611

# 4、设置开机自动挂载光盘镜像
$ vi /etc/fstab
# 注意:fstab 输入错误会使主机无法正常启动而进入emergency mode紧急状态!
# 在最后一行添加
/root/operation-systems/CentOS-7-x86_64-DVD-1611.iso  /media/CentOS-7-x86_64-DVD-1611  iso9660  defaults,ro,loop  0  0

# 5、将光盘镜像挂载到挂载点
# 方式1:通过配置文件 /etc/fstab 的数据将未挂载的磁盘都挂载上来
$ mount -a
# 方式2:指定参数挂载
$ mount -t iso9660 -o loop CentOS-7-x86_64-DVD-1611.iso /media/CentOS-7-x86_64-DVD-1611

# 6、配置yum源,文件不存在则自动创建
$ vi /etc/yum.repos.d/CentOS7-Localyum.repo
[CentOS7-Localyum]
name=CentOS7
baseurl=file:///media/CentOS-7-x86_64-DVD-1611
# 1表示启用,0表示禁用
enabled=1
# 1表示对这个源下载的rpm包进行校验,0表示不进行校验
gpgcheck=0

# 7、生成本地 yum 缓存
$ yum makecache

# 8、安装 httpd
$ yum install -y httpd

# httpd 目录结构
# 安装目录:/etc/httpd
# 主配置文件:/etc/httpd/conf/httpd.conf
# 扩展配置文件:/etc/httpd/conf.d/*.conf

# httpd.conf 的重要配置项
# 根目录
DocumentRoot "/var/www/html"
# 监听端口
Listen 80

# 注:service 是一个脚本命令,它会去 /etc/init.d 下面执行相关程序
# /etc/init.d 其实是软连接,实际指向 /etc/rc.d/init.d

# 注:修改 httpd.conf 后只需重新加载,而修改服务器监听端口则要重新启动

# 9、httpd 的启动
# 注:CentOS 7 中使用了 systemd,systemd 兼容 service,对应的命令为 systemctl
# 关于 systemd 的详细介绍参考:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
# systemctl 融合了 service 和 chkconfig 的功能,使用如下:

# 启动服务
$ service httpd start
# 或者
$ systemctl start httpd.service

# 重新加载
$ service httpd reload
# 或者
$ systemctl reload httpd.service

# 重新启动
$ service httpd restart
# 或者
$ systemctl restart httpd.service

# 停止服务
$ service httpd stop
# 或者
$ systemctl stop httpd.service

# 设置 httpd 开机自启
$ chkconfig httpd start
# 或者
$ systemctl enable httpd.service

# 查看服务状态
$ service <service name> status
# 或者
$ systemctl status <service name>
● filebeat.service - Filebeat sends log files to Logstash or directly to Elasticsearch.
   Loaded: loaded (/usr/lib/systemd/system/filebeat.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2019-07-26 20:12:44 CST; 2 days ago
     Docs: https://www.elastic.co/products/beats/filebeat
 Main PID: 29753 (filebeat)
   CGroup: /system.slice/filebeat.service
           └─29753 /usr/share/filebeat/bin/filebeat -e -c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat
# 查看 service 配置
$ vim /usr/lib/systemd/system/filebeat.service
[Unit]
Description=Filebeat sends log files to Logstash or directly to Elasticsearch.
Documentation=https://www.elastic.co/products/beats/filebeat
Wants=network-online.target
After=network-online.target

[Service]
# 环境变量
Environment="BEAT_LOG_OPTS=-e"
Environment="BEAT_CONFIG_OPTS=-c /etc/filebeat/filebeat.yml"
Environment="BEAT_PATH_OPTS=-path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat"
# 启动命令
ExecStart=/usr/share/filebeat/bin/filebeat $BEAT_LOG_OPTS $BEAT_CONFIG_OPTS $BEAT_PATH_OPTS
# 进程挂掉之后重启(但对于服务本身起不来,假死问题,不能很好的解决)
Restart=always

[Install]
WantedBy=multi-user.target


# 10、建立软连接,指向根目录中的文件
$ ln -s /media/CentOS-7-x86_64-DVD-1611 /var/www/html/CentOS7

# 11、关闭防火墙
$ service iptables stop | systemctl stop firewalld

# 12、检测是否配置成功,浏览器输入 http://10.4.121.202:80/CentOS7 看是否可以成功访问

# 13、配置 client yum源(记得将系统原来的 repo 文件打包)
$ vi /etc/yum.repos.d/CentOS7-Localyum.repo
[CentOS7-Localyum]
name=CentOS7
baseurl=http://10.4.121.202:80/CentOS7
enabled=1
gpgcheck=0

如果需要添加额外的 rpm 包,如 CDH 相关的 rpm 包,则还需要执行createrepo命令,为 rpm 包建立索引文件:

# 创建本地 yum repo
$ mkdir local-yum-repo
# 用于放 CDH 相关的 rpm 包
$ mkdir local-yum-repo/CDH-Packages

# 建立 rpm 包的索引文件
# 命令语法:createrepo [option] <directory>
$ createrepo local-yum-repo/

deb 安装

$ dpkg -i filebeat-6.3.2-amd64.deb

Linux 代理配置

# 当密码中有特殊字符的时候需要添加转义符`\`
$ vim /etc/profile
http_proxy=http://username:[email protected]:8080/ 
ftp_proxy=http://username:[email protected]:8080/ 
export http_proxy 
export ftp_proxy

$ source /etc/profile
 
# 对于yum代理,还要另外设置 /etc/yum.conf
$ vim /etc/yum.conf
proxy=http://username:[email protected]:8080/ 

# 如果出现 Couldn't resolve proxy 'dl-proxy.something.com'的问题,在 /etc/hosts 中配置一下代理的IP 

程序的挂起与恢复

# & 的作用:设置此进程在后台运行,代表所有输出流。
# 默认情况下进程在前台进行,这样会把前台Shell给占据了,导致无法进行其他的操作,对于那些
# 没有交互的进程,我们希望让他在后台运行。
# 例如启动zookeeper:
$ ./bin/zookeeper-server-start.sh config/zookeeper.properties &
$ ctrl + c && jobs 
# 会看到程序依然在运行

# 除此之外,还可以这样
$ ./bin/zookeeper-server-start.sh config/zookeeper.properties
$ ctrl + z 
[1]+  Stopped                 bin/zookeeper-server-start.sh config/zookeeper.properties
# 挂起程序,会出现:其中[1]代表第一个job,+ 代表最近刚挂起的进程,- 代表次最近挂起的进程

# 然后将停止的进程后台运行:
$ bg    # 不加 %3,会默认将最近的进程(+)放至后台运行
$ bg %3 # 将id为3的job放置后台运行

# 其他的相关的命令:
$ fg      # 将后台进程放到前台运行
$ jobs    # 查看当前shell下运行的所有程序
$ kill %3 # 将第3个job干掉
# nohup = no hang up 不挂断,进程在账户退出是会接收到 hang up signal,这样
# 程序就会中断,如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,
# 那么可以使用 nohup 命令。该命令声明在退出账户的时候不发送 hang up signal。
# 这样退出帐户/关闭终端之后能继续运行相应的进程。
# 长命令必须写在 shell 文件中,否则 nohup 不起作用
# 该命令一般会配合 & 命令一起使用
$ nohup command &
# log输出到myout.file,并将标准错误输出重定向到标准输出,再被重定向到myout.file
$ nohup command > myout.file 2>&1

SELinux

# 查看SELinux状态:
# SELinux status 参数为 enabled 即为开启状态
$ /usr/sbin/sestatus -v      
SELinux status:                 enabled

# 或者用这个命令检查
$ getenforce                 

# 关闭 SELinux
# 1、临时关闭(不用重启机器)
# 0 为 permissive 模式
# 1 设置 SELinux 成为enforcing模式
$ setenforce 0 
                 
# 2、修改配置文件(需要重启机器)
$ vi /etc/selinux/config
SELINUX=enforcing => SELINUX=disabled
$ reboot

Linux 时间

查看时间

$ date

# 时间格式化
$ date +'FORMAT'
# 例如
$ echo "`date +'%Y-%m-%d %T'`"
2019-01-22 15:48:54

修改时区

可以通过两种方式修改时区

  • 第一种是通过tzselect查找相应地区的时区(TimeZone)比如中国北京时间就对应着Asia/Shanghai,然后通过配置环境变量来修改时区。
  • 第二种是直接修改配置文件,比如/etc/sysconfig/clock或者/etc/localtime

tzselect

$ tzselect 
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
 1) Africa
 2) Americas
 3) Antarctica
 4) Arctic Ocean
 5) Asia
 6) Atlantic Ocean
 7) Australia
 8) Europe
 9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 5
Please select a country.
 1) Afghanistan           18) Israel                35) Palestine
 2) Armenia               19) Japan                 36) Philippines
 3) Azerbaijan            20) Jordan                37) Qatar
 4) Bahrain               21) Kazakhstan            38) Russia
 5) Bangladesh            22) Korea (North)         39) Saudi Arabia
 6) Bhutan                23) Korea (South)         40) Singapore
 7) Brunei                24) Kuwait                41) Sri Lanka
 8) Cambodia              25) Kyrgyzstan            42) Syria
 9) China                 26) Laos                  43) Taiwan
10) Cyprus                27) Lebanon               44) Tajikistan
11) East Timor            28) Macau                 45) Thailand
12) Georgia               29) Malaysia              46) Turkmenistan
13) Hong Kong             30) Mongolia              47) United Arab Emirates
14) India                 31) Myanmar (Burma)       48) Uzbekistan
15) Indonesia             32) Nepal                 49) Vietnam
16) Iran                  33) Oman                  50) Yemen
17) Iraq                  34) Pakistan
#? 9
Please select one of the following time zone regions.
1) Beijing Time
2) Xinjiang Time
#? 1

The following information has been given:

        China
        Beijing Time

Therefore TZ='Asia/Shanghai' will be used.
Local time is now:      Sun May  5 13:21:37 CST 2019.
Universal Time is now:  Sun May  5 05:21:37 UTC 2019.
Is the above information OK?
1) Yes
2) No
#? 1

You can make this change permanent for yourself by appending the line
        TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.

Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai

$ echo "export TZ='Asia/Shanghai'" >> ~/.bash_profile
$ source ~/.bash_profile
$ date
Sun May  5 13:31:03 CST 2019

修改配置文件

# 方式1
$ vim /etc/sysconfig/clock         
ZONE=Asia/Shanghai

# 方式2
$ rm /etc/localtime
$ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
$ reboot

NTP时间同步

详细请参考文章

ntp时间同步的方式有两种:使用ntpdate直接进行时间同步、使用ntpd服务平滑同步。区别是什么呢?例如:ntpdate 202.118.6.8直接将本机的时间与目标时间服务器202.118.6.8的时间同步,不管时间差有多大。这样做其实是有潜在风险的,例如你有一个定时任务在13:00执行,现在你的本机时间是13:00整,现在定时任务已经执行了一次了,但是时间服务器的时间是12:30,这种情况下你将时间同步之后,定时任务在今天就会执行两次。所以为了避免这种情况,第二种同步方式就是平滑同步。顾名思义,它每次同步的时间偏移量不会特别陡(大),慢慢同步,不让同一时间点在一天内经历两次,弊端是完全同步会花很多时间。常见的做法就是在开启平滑同步之前,先使用ntpdate同步一次(当然确保没有定时任务在运行或者执行多次也没什么影响)。

# 查看ntp是否已经安装,一般系统都已经自带了
$ rpm -q ntp
# 如果没有安装,装了就忽略
$ yum install ntp
# 配置ntp服务为自启动
$ chkconfig ntp on
# 查看 runlevel 运行级别
$ chkconfig --list ntpd
ntpd           0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭

# 0 - 挂起(不要将此项作为默认设定)
# 1 - 单用户模式
# 2 - 多用户模式,不带NFS(与选项3相同,不支持网络)
# 3 - 标准的多用户模式
# 4 - 未定义
# 5 - X11
# 6 - 重启动(不要将此项作为默认设定)

# 首先手动同步一下时间,下面的时间服务器域名是 time.neusoft.com
ntpdate -u 202.118.6.8

配置内网NTP-Server,主要用于与外部时间服务器同步标准时间,是内网的时间服务器。

$ vim /etc/ntp.conf
# 允许内网其他机器同步时间
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
# 中国这边最活跃的时间服务器 : http://www.pool.ntp.org/zone/cn
server 202.118.6.8 perfer   # time.neusoft.com
server 210.72.145.44        # 中国国家受时中心
server 202.112.10.36        # 1.cn.pool.ntp.org
server 59.124.196.83        # 0.asia.pool.ntp.org
# allow update time by the upper server 
# 允许上层时间服务器主动修改本机时间
restrict 202.118.6.8 nomodify notrap noquery
restrict 210.72.145.44 nomodify notrap noquery
restrict 202.112.10.36 nomodify notrap noquery
restrict 59.124.196.83 nomodify notrap noquery
# 外部时间服务器不可用时,以本地时间作为时间服务
server  127.127.1.0     # local clock
fudge   127.127.1.0 stratum 10

# 保存退出、启动服务
$ sudo service ntpd start
# 查看服务连接和监听
$ netstat -tlunp | grep ntp    

# 查看网络中的NTP服务器,同时显示客户端和每个服务器的关系
$ ntpq -p

# 查看时间同步状态,这个一般需要5-10分钟后才能成功连接和同步。所以,服务器启动后需要稍等下。
$ ntpstat
# 刚启动的时候,一般是
unsynchronised
  time server re-starting
   polling server every 64 s
# 同步后
synchronised to NTP server (202.112.10.36) at stratum 3 
   time correct to within 275 ms
   polling server every 256 s

配置内网NTP-Clients

# 同样开启自启动
$ chkconfig ntp on
# 修改ntp配置文件
$ vim /etc/ntp.conf

# 配置时间服务器为本地的内网NTP-Server
server 10.4.121.79
# 允许上层时间服务器主动修改本机时间
restrict 10.4.121.79 nomodify notrap noquery
# 外部时间服务器不可用时,以本地时间作为时间服务
server  127.127.1.0     # local clock
fudge   127.127.1.0 stratum 10
# 保存退出

# 首先手动同步下时间,内网NTP-Server的IP地址,然后启动ntp服务
$ ntpdate -u 10.4.121.79 && service ntpd start

最后将配置文件scp到其他节点中。先手动同步,然后启动服务。

$ ntpdate -u 10.4.121.79 && service ntpd start

定时任务 crontab

crontab 任务的格式 M H D m d command

  • M: 分钟(0-59)。
  • H:小时(0-23)。
  • D:天(1-31)。
  • m: 月(1-12)。
  • d: 一星期内的天(0~6,0为星期天)。
  • command:要运行的程序,程序被送入sh执行
# 全局的crontab任务
$ vim /etc/crontab
# 每小时的01分执行 root 表示用root用户执行命令
01 * * * * root run-parts /etc/cron.hourly
# 每天的4:02分执行
02 4 * * * root run-parts /etc/cron.daily
# 每周天的4:22分执行一次
22 4 * * 0 root run-parts /etc/cron.weekly
# 每个月的1号的4:24分执行
42 4 1 * * root run-parts /etc/cron.monthly

# 在 root 用户下可以使用参数 -u 指定要操作的用户
# 用指定的文件替代当前用户[指定用户]的crontab。
$ crontab [-u user] file

# 用标准输入替代当前用户[指定用户]的crontab
$ crontab [-u user] -
# 命令格式和参数
$ crontab [-u user] [ -e | -l | -r ]

# -e 编辑当前用户的crontab,如果没有会新建一个。
[[email protected] etc]$ crontab -e 
# 每月1、10、22日的4:45重启apache。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
# 每周六、周日的1:10重启apache
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
# 每天18:00至23:00之间每隔30分钟重启apache
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart 
# 每2小时重启apache 
0 */2 * * * /usr/local/etc/rc.d/lighttpd restart 
# 晚上11点到早上7点之间,每隔2小时重启apache 23:00、1:00、3:00、5:00、7:00
0 23-7/2 * * * /usr/local/etc/rc.d/lighttpd restart 
# 23:00、1:00、3:00、5:00、7:00 和 8:00 重启apache
0 23-7/2,8 * * * /usr/local/etc/rc.d/lighttpd restart 
# 周一到周五每天下午 5:00 寄一封信给 [email protected] : 
0 17 * * 1-5 mail -s "hi" [email protected] < /tmp/maildat

# -l 列出当前用户的crontab
[[email protected] etc]$ crontab -l
0 3 * * *  /opt/spark/submit-bashs/ZombieSetTopBoxFilter.sh

# -e 删除当前用户的crontab文件
[[email protected] etc]$ crontab -r

# 调用脚本时引入环境变量
[[email protected] etc]$ vim /opt/spark/submit-bashs/ZombieSetTopBoxFilter.sh
#!/bin/sh
. /etc/profile
. ~/.bash_profile
spark-submit --class com.neusoft.apps.ZombieSetTopBoxFilter /opt/spark/submit-jars/JiangSu_GuangDian.jar

设置开机自启任务

  1. 编写要设置为开机自启的脚本,其中第二行表示脚本在2/3/4/5运行级别启动,启动序号S80,关闭序号K90。注意第二行和第三行必须存在,否则会出现service autostart.sh doesn't support chkconfig这样的错误。
    #!/bin/sh
    #chkconfig: 2345 80 90
    #description: 开机自动启动的脚本程序
    su - es
    /home/es/elasticsearch-6.2.3/bin/elasticsearch -d
    
  2. 将脚本移动到/etc/rc.d/init.d/目录下
    mv autostart.sh /etc/rc.d/init.d/
    
  3. 给脚本赋可执行权
    chmod +x autostart.sh
    
  4. 将脚本添加到开机自启动项目中
    chkconfig --add autostart.sh
    chkconfig autostart.sh on
    

数据流重定向

在执行脚本的时候,默认总是有三个文件处于打开状态。标准输入(键盘输入/dev/stdin)、标准输出(输出到屏幕/dev/stdout)、标准错误(将错误信息输出到屏幕/dev/stderr)。这三个文件对应的文件描述符分别为0、1、2。

输出重定向 > »

>每次执行脚本时,会覆盖掉上次文件的内容,而>>代表追加内容到文件。

$ touch exist.txt
$ ls exist.txt notexist.txt
ls: 无法访问notexist.txt: 没有那个文件或目录  # 错误输出
exist.txt # 标准输出

# 默认只会将标准输出写入到文件,错误输出依然会显示在屏幕上
$ ls exist.txt notexist.txt >success.log
ls: 无法访问notexist.txt: 没有那个文件或目录

# 将错误输出也写到日志文件中
$ ls exist.txt notexist.txt 1>success.log 2>error.log

# 重定向目的地标识符:&- 关闭某个输出,&1 代表标准输出,&2 代表错误输出

# 关闭错误输出
$ ls exist.txt notexist.txt 2>&-
# 除了使用 &- 还可以使用 /dev/null 类似关闭错误输出
$ ls exist.txt notexist.txt 2>dev/null
# 把错误输出重定向到标准输出,正确输出重定向到 all.log
$ ls exist.txt notexist.txt 1>all.log 2>&1
# 与上面等价
$ ls exist.txt notexist.txt >all.log 2>&1

# & 代表所有输出

# 例如:将所有输出重定向到 /dev/null
$ ls exist.txt notexist.txt &>/dev/null

输入重定向 < «

# cat 从屏幕获取输入,然后输出
$ cat
test # 输入
test # 输出到屏幕

# 重定向给test1.log
$ cat test >test1.log

# 读入文件 test1.log,写入 test2.log
$ cat >test2.log <test1.log

# << 除了表示输入重定向外,还接受一个输入结束的标识,当输入这个标识,就标志着结束输入
# 注意:<<EOF 或者 <<-EOF 之间是不可以有空格的,他们是一体的
# 如果使用 <<- 重定向操作符,那么分界符(EOF)所在行的开头部分的制表符(Tab)都将被去除
/usr/bin/expect <<EOF
    set timeout 60
    spawn ssh-keygen -t rsa -P ""
    expect {
        "*save the key*" { 
            send "\r"; exp_continue 
        }
        "Overwrite (y/n)?" { 
            send "n\r" 
            send_user "\nssh-key已经存在,不需要再重新生成\n"
            exit 2
        }
        timeout { 
            send_user \n"匹配等待60s超时\n"
            exit 1
        }
        eof { 
            send_user "\nssh-keygen 生成成功\n"
            exit 0
        }
    }
EOF
# 如果使用 <<EOF,那么结尾的EOF必须顶格写,前后不要有多余的空格或制表符

绑定重定向 exec

# 查看已有的文件描述符
$ ls /proc/self/fd
0  1  2  3

# 绑定一个新的文件描述符6,并且绑定标准输出(相当于给标准输出保存一个临时copy)
$ exec 6>&1
$ ls /proc/self/fd
0  1  2  3  6

# 绑定标准输出给 success.log
$ exec 1>success.log

# 把标准输出绑定回来
$ exec 1>&6

# 关闭自定义的文件描述符
$ exec 6>&-

Note:如果你没有提前给标准输出保存备份文件描述符,就将标准输出绑定给文件,你就再也变不回来了!!!

Shell Script

我的 shell script 演练笔记

特殊变量

# shell script 本身的 pid 
$$ 
# shell script 最后运行的后台 process 的 pid 
$! 
# 最后运行的命令的结束代码(返回值),一般来讲 0(exit 0) 代表成功结束,1和其他数值代表不同类型的失败,当然你也可以不那么定义
$? 
# 查看使用 set 命令设定的 flag 
$- 
# 所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 
$* 
# 所有参数列表。如"[email protected]"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 
[email protected] 
# 传递给当前 shell script 的参数个数
$# 
# 当前 shell script 的文件名 
$0 
# 传递给 shell script 的各个参数
$1 ~ $n 

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,一毛也是爱

打开支付宝扫一扫,即可进行扫码打赏哦