Linux 基础

前言

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

基础概念

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

# ~ 代表当前用户的根目录,`#`代表超级用户
[root@s12083 ~]# 

基础命令和工具

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 neu@s12181:/opt/neu/spark/conf

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

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

# 将多个文件发送到目标节点的用户根目录
$ scp file1 file2 file3  neu@s121203:

# 将远程主机的文件发送到本机用户根目录
$ scp neu@s121203:~/file ~

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

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

# 通过跳板机与内网机器互相传输
# -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 hadoop@{}:/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 download: 
- https://joncraton.org/blog/46/netcat-for-windows
- https://eternallybored.org/misc/netcat/
# 先在 receiver server 启动服务,监听端口等待接收文件
# -v 显示详细信息,一般用于 debug, -vv 显示更详细的信息
# -l listen mode, for inbound connects, 即启动 server
$ nc -vv -l 9995 >somefiles.rpm
# windows 需要加 -p, linux 不需要
$ nc -vv -l -p 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 10000 -e /bin/bash
# 这样就相当于跳过登录直接获取一个 bash shell 操控系统,不过用户权限取决于起 nc 服务的用户
$ nc 192.168.0.1 10000


# 端口转发
# -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

# undo 撤销,连续撤销就多按几下
u
:u
:undo
# redo 重做,撤销多了可以用 redo 返回
ctrl + r
:red
:redo
# 文件内容查看
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所指定的字符集进行解码。

# 系统重启,则会从默认语系配置文件 /etc/sysconfig/i18n 中读出字符集,然后赋予变量 LANG
$ cat /etc/sysconfig/i18n
LANG="en_US.UTF-8"

# 查看 LANG 变量,注:en_US.UTF-8 等价于 en_US.utf8
$ echo $LANG
en_US.UTF-8

# 查看当前系统支持的字符集
$ locale -a
C
C.UTF-8
POSIX
en_US.utf8

# 安装字符集
$ apt-get install -y language-pack-zh-hans

# 配置字符集
$ sudo locale-gen 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
# -k:不更新文件的修改时间
# -n:保留原始文件,将转换后的内容输出到新文件中
$ dos2unix [-kn] file.txt [new_file.txt]
$ dos2unix -n old_file.txt new_file.txt

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


# === 在 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 $1}' | 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 用户及权限管理

# 添加用户
useradd 参数 用户名

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

# 默认创建/home/neu为主目录
[root@s12083 ~]# useradd neu 

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

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

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

# 添加一个新的组neu
[root@s12083 ~]# groupadd neu

# 删除组neu
[root@s12083 ~]# groupdel neu  

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

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

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

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

# 为普通用户开启sudo功能,NOPASSWD会避免密码交互
[root@s12083 ~]# 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: 文件已存在)
[root@s12083 ~]# rm -rf /var/spool/mail/neu(用户名)
# 解决 useradd: invalid numeric argument 'hadoop'
# 这是由于 hadoop 组不存在 请先建 hadoop 组

用户类型和文件权限`

# 显示当前文件的详细信息 -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]
# -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> <username@ip>

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 系统版本

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

# 查看 CentOS 发行版版本信息
$ cat /etc/redhat-release
# 查看 Ubuntu/Debian 发行版版本信息
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)" # 发行版本
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
# 或者直接查看
$ cat /etc/issue
Ubuntu 18.04.5 LTS

# 查看系统内核版本 
$ cat /proc/version 
Linux version 4.4.0-187-generic (buildd@lgw01-amd64-035) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) ) #217-Ubuntu SMP Tue Jul 21 04:18:15 UTC 2020
$ uname -a
Linux clickhouse-client-5f7fc89fb-kcfn2 4.4.0-187-generic #217-Ubuntu SMP Tue Jul 21 04:18:15 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# 只显示系统内核版本
$ uname -r 
4.4.0-187-generic

磁盘

磁盘挂载

# 查看磁盘情况
$ 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

LVM 逻辑卷

硬盘接口

机械硬盘的接口有很多,不过最主流的接口就是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=Gb/s * 8b代表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两个通道,速度是不是快取决于接口采用的是哪个通道。

系统文件

/var 文件系统

/var包含系统一般运行时要改变的数据。通常这些数据所在的目录的大小是要经常变化或扩充的。原来 /var 目录中有些内容是在 /usr 中的,但为了保持 /usr 目录的相对稳定,就把那些需要经常改变的目录放到 /var 中了。每个系统是特定的,即不通过网络与其他计算机共享。下面列出一些重要的目录 ( 一些不太重要的目录省略了 ) 。

  1. /var/catman: 包括了格式化过的帮助(man)页。帮助页的源文件一般存在/usr/man/catman中;有些 man 页可能有预格式化的版本,存在 /usr/man/cat 中。而其他的 man 页在第一次看时都需要格式化,格式化完的版本存在 /var/man 中,这样其他人再看相同的页时就无须等待格式化了。 (/var/catman 经常被清除,就像清除临时目录一样。 )
  2. /var/lib: 存放系统正常运行时要改变的文件。
  3. /var/local: 存放/usr/local中安装的程序的可变数据(即系统管理员安装的程序)。注意,如果必要, 即使本地安装的程序也会使用其他 /var 目录,例如 /var/lock 。
  4. /var/lock: 锁定文件。许多程序遵循在/var/lock中产生一个锁定文件的约定,以用来支持他们正在使用某个特定的设备或文件。其他程序注意到这个锁定文件时,就不会再使用这个设备或文件。
  5. /var/log: 各种程序的日志 (log) 文件,尤其是 login (/var/log/wtmplog 纪录所有到系统的登录和注销 ) 和 syslog (/var/log/messages 纪录存储所有核心和系统程序信息 ) 。 /var/log 里的文件经常不确定地增长,应该定期清除。
  6. /var/run: 保存在下一次系统引导前有效的关于系统的信息文件。例如, /var/run/utmp 包含当前登录的用户的信息。
  7. /var/spool: 放置“假脱机 (spool)”程序的目录,如 mail 、 news 、打印队列和其他队列工作的目录。每个不同的 spool 在 /var/spool 下有自己的子目录,例如,用户的邮箱就存放在 /var/spool/mail 中。
  8. /var/tmp: 比 /tmp 允许更大的或需要存在较长时间的临时文件。注意系统管理员可能不允许 /var/tmp 有很旧的文件。

/etc 文件系统

/etc目录包含各种系统配置文件,下面说明其中的一些。其他的你应该知道它们属于哪个程序,并阅读该程序的 man 页。许多网络配置文件也在 /etc 中。

  1. /etc/rc/etc/rc.d/etc/rc?.d: 启动、或改变运行级时运行的脚本或脚本的目录。
  2. /etc/passwd: 用户数据库,其中的域给出了用户名、真实姓名、用户起始目录、加密口令和用户的其他信息。
  3. /etc/fdprm: 软盘参数表,用以说明不同的软盘格式。可用 setfdprm 进行设置。更多的信息见 setfdprm 的帮助页。
  4. /etc/fstab: 指定启动时需要自动安装的文件系统列表。也包括用 swapon -a 启用的 swap 区的信息。
  5. /etc/group: 类似 /etc/passwd ,但说明的不是用户信息而是组的信息。包括组的各种数据。
  6. /etc/inittab: init 的配置文件。
  7. /etc/issue: 包括用户在登录提示符前的输出信息。通常包括系统的一段短说明或欢迎信息。具体内容由系统管理员确定。
  8. /etc/magic: “file” 的配置文件。包含不同文件格式的说明, “file” 基于它猜测文件类型。
  9. /etc/motd: motd 是 message of the day 的缩写,用户成功登录后自动输出。内容由系统管理员确定。常用于通告信息,如计划关机时间的警告等。
  10. /etc/mtab: 当前安装的文件系统列表。由脚本 (scritp) 初始化,并由 mount 命令自动更新。当需要一个当前安装的文件系统的列表时使用 ( 例如 df 命令 ) 。
  11. /etc/shadow: 在安装了影子 (shadow) 口令软件的系统上的影子口令文件。影子口令文件将/etc/passwd文件中的加密口令移动到 /etc/shadow中,而后者只对超级用户(root)可读。这使破译口令更困难,以此增加系统的安全性。
  12. /etc/login.defs: login 命令的配置文件。
  13. /etc/printcap: 类似 /etc/termcap ,但针对打印机。语法不同。
  14. /etc/profile/etc/csh.login/etc/csh.cshrc: 登录或启动时 bourne 或 cshells 执行的文件。这允许系统管理员为所有用户建立全局缺省环境。
  15. /etc/securetty: 确认安全终端,即哪个终端允许超级用户(root)登录。一般只列出虚拟控制台,这样就不可能(至少很困难)通过调制解调器 (modem) 或网络闯入系统并得到超级用户特权。
  16. /etc/shells: 列出可以使用的 shell 。 chsh 命令允许用户在本文件指定范围内改变登录的 shell 。提供一台机器ftp服务的服务进程ftpd检查用户 shell 是否列在 /etc/shells 文件中,如果不是,将不允许该用户登录。
  17. /etc/termcap: 终端性能数据库。说明不同的终端用什么“转义序列”控制。写程序时不直接输出转义序列(这样只能工作于特定品牌的终端)而是从/etc/termcap中查找要做的工作的正确序列。这样,多数的程序可以在多数终端上运行。

防火墙设置

iptables

# 查看防火墙状态
$ 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
  # 重启防火墙

# 用命令添加规则,只对 IP 白名单开放端口访问,注意顺序不能乱
# -I insert 默认插入 linenumber=1 的位置,也就是 chain 的 head, -A 是 append 到 end
# INPUT 代表输入, -dport 代表数据写入本机的 destination port
# OUTPUT 代表输出, -sport 代表数据写出本机的 source port
# 1. 禁止所有的 IP 通过 TCP 协议访问本机的 1521 端口。
$ iptables -I INPUT -p tcp --dport 1521 -j DROP
# 2. 允许192.168.1.123访问本机的1521端口
$ iptables -I INPUT -s 192.168.1.123 -p tcp --dport 1521 -j ACCEPT
# 3. 允许192.168.1.124访问本机的1521端口
$ iptables -I INPUT -s 192.168.1.124 -p tcp --dport 1521 -j ACCEPT
# 以上是临时配置,保存 iptables
$ service iptables save
$ service iptables restart

# 查找所有规则,加行号
$ iptables -L INPUT --line-numbers
# 删除一条规则,11 是行号
$ iptables -D INPUT 11

firewalld

# 防火墙 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

Linux 软件包管理

yum sources for Redhat/CentOS

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/

apt sources for Debian/Ubuntu

# 源配置文件夹:    /etc/apt/sources.list.d/
# 默认配置文件:    /etc/apt/sources.list

# 注意选择相对应发行版本的源
$ vim /etc/apt/sources.list
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse

$ apt-get update

查看软件包信息

# 列出指定软件所有版本,并查看是否已经安装 
$ apt-cache madison [package]

# 列出软件的所有来源
$ apt-cache policy [package]

# 查看指定包信息
$ apt-cache show [package]
# 或者
$ dpkg -l [package]

# 查看已安装包详情
$ dpkg -s [package]
# 或者
$ dpkg-query -s [package]

安装软件包

# 安装指定版本的软件包
$ apt-get install [package]=[version]

# 安装 deb 文件
$ dpkg -i filebeat-6.3.2-amd64.deb

安装包卸载

# 删除软件包,保留配置文件
$ apt-get remove [package]

# 删除软件包,并删除不再被依赖的软件包
$ apt-get autoremove [package]

# 删除软件包,并删除配置文件
$ apt-get purge -y [package]
# 或者
$ apt-get --purge -y remove [package]

# apt 的底层包是 dpkg, 而 dpkg 安装 Package 时, 会将 *.deb 放在 /var/cache/apt/archives/ 中
# 执行该命令相当于执行 rm -rf /var/cache/apt/archives/*.deb
$ apt-get clean

# 会删除 /var/cache/apt/archives/ 已经过期的 deb
$ apt-get autoclean

Linux 代理配置

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

$ source /etc/profile
 
# 对于yum代理,还要另外设置 /etc/yum.conf
$ vim /etc/yum.conf
proxy=http://username:password@yourproxy: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,如果没有会新建一个。
[spark@master 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
[spark@master etc]$ crontab -l
0 3 * * *  /opt/spark/submit-bashs/ZombieSetTopBoxFilter.sh

# -e 删除当前用户的crontab文件
[spark@master etc]$ crontab -r

# 调用脚本时引入环境变量
[spark@master 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

  • Bash 教程 - 阮一峰
  • 我的 shell script 演练笔记

    特殊变量

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

qin

取消

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

扫码支持
扫码支持
扫码打赏

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